gpt4 book ai didi

amazon-web-services - Terraform:创建和验证多个ACM证书

转载 作者:行者123 更新时间:2023-12-04 00:13:17 25 4
gpt4 key购买 nike

我遇到了一个非常令人困惑的Terraform资源问题,它会自动生成ACM中(Terraform管理的)托管区域列表的SSL证书的生成和DNS验证。也可以在in this gist中找到代码。

我首先通过引导托管区域来引用此特定于环境的变量。

hosted_zones = [
{
domain = "site1.com"
zone_id = "MANUALLY FILL"
}
]

我用来构建区域的块似乎工作可靠。
resource "aws_route53_zone" "zones" {
count = "${length(var.hosted_zones)}"
name = "${lookup(var.hosted_zones[count.index], "domain")}"
}

在构建区域之后,由于HCL的局限性以及我缺乏经验,因此我没有想出一种自动的方法来自动将区域ID复制到变量中。

我可以使用...为每个托管区域可靠地生成裸证书和splat证书
resource "aws_acm_certificate" "cert" {
count = "${length(var.hosted_zones)}"
domain_name = "${lookup(var.hosted_zones[count.index], "domain")}"
subject_alternative_names = ["*.${lookup(var.hosted_zones[count.index], "domain")}"]
validation_method = "DNS"

tags {
Project = "${var.project}"
Environment = "${var.environment}"
}
}

当我尝试自动执行证书的DNS验证时,事情变得很繁琐。单个托管区域有 a good example in the documentation,但我无法成功将其移植到多个托管区域。我的尝试
resource "aws_route53_record" "cert_validation" {
count = "${length(var.hosted_zones)}"

name = "${aws_acm_certificate.cert.*.domain_validation_options.0.resource_record_name[count.index]}"
type = "${aws_acm_certificate.cert.*.domain_validation_options.0.resource_record_type[count.index]}"
zone_id = "${var.zone_override != "" ? var.zone_override : lookup(var.hosted_zones[count.index], "zone_id")}"
records = ["${aws_acm_certificate.cert.*.domain_validation_options.0.resource_record_value[count.index]}"]
ttl = 60
}

resource "aws_acm_certificate_validation" "cert" {
count = "${length(var.hosted_zones)}"

certificate_arn = "${aws_acm_certificate.cert.*.arn[count.index]}"
validation_record_fqdns = ["${aws_route53_record.cert_validation.*.fqdn[count.index]}"]
}

我在第一次运行时看到的错误是:
* module.acm.aws_route53_record.cert_validation: 1 error(s) occurred:
* module.acm.aws_route53_record.cert_validation: Resource 'aws_acm_certificate.cert' does not have attribute 'domain_validation_options.0.resource_record_value' for variable 'aws_acm_certificate.cert.*.domain_validation_options.0.resource_record_value'

令人讨厌的部分是,如果我注释了 validation资源,则 apply成功,然后取消注释它们并重新运行也成功。

我已经尝试过(感觉上) element() lookup()list()map()的每个排列,以第一个资源块的输出中的索引为目标来定向证书,但是遇到了文档化的“平面列表”限制,这是我最近的一次获得成功。我想了解为什么需要这种解决方法,所以我可以消除它。这感觉像是语法问题,或者我试图让HCL的行为更像是OO语言。

感谢您提供的任何经验!

最佳答案

我有一个类似的场景,解决该问题的关键是使用localsflatten()。该方法也应该对您有用,这样您就不需要两次通过就可以创建资源。

在这种情况下,有多个域,每个域都有子域,这些子域将出现在证书的subjectAltName部分中。例如:

├── preview.example.com
│ ├── app.preview.example.com
│ └── www.preview.example.com
├── demo.example.com
│ ├── app.demo.example.com
│ └── www.demo.example.com
├── staging.example.com
│ ├── app.staging.example.com
│ └── www.staging.example.com
└── example.com
├── app.example.com
└── www.example.com

为此,我们首先设置一些变量:
variable "domains" {
type = "list"
default = [
"demo.example.com",
"preview.example.com",
"staging.example.com",
"example.com"
]
}
variable "subdomains" {
type = "list"
default = [
"app",
"www"
]
}

接下来,我们创建包含作为SAN的子域的证书资源。
resource "aws_acm_certificate" "cert" {
count = "${length(var.domains)}"
domain_name = "${element(var.domains, count.index)}"
validation_method = "DNS"

subject_alternative_names = ["${
formatlist("%s.%s",
var.subdomains,
element(var.domains, count.index)
)
}"]
}

接下来,我们将需要一个局部变量来平整域和子域的结果集。
这是必需的,因为从0.11.7版本开始,terraform不支持​​嵌套列表语法,
通过 element()插值或`list [count]。
locals {
dvo = "${flatten(aws_acm_certificate.cert.*.domain_validation_options)}"
}

接下来,我们需要查找Route 53区域,我们可以在后续的Route 53记录中使用该区域:
data "aws_route53_zone" "zone" {
count = "${length(var.domains) > 0 ? 1 : 0}"
name = "example.com."
private_zone = false
}

然后,我们创建Route 53 DNS记录,这些记录中将填充来自证书的数据
DNS验证的资源。我们将一个添加到子域中,以便我们也有一个
未包含在子域列表中的基本域的记录。
resource "aws_route53_record" "cert_validation" {
count = "${length(var.domains) * (length(var.subdomains) + 1)}"
zone_id = "${data.aws_route53_zone.zone.id}"
ttl = 60

name = "${lookup(local.dvo[count.index], "resource_record_name")}"
type = "${lookup(local.dvo[count.index], "resource_record_type")}"
records = ["${lookup(local.dvo[count.index], "resource_record_value")}"]
}

最后,我们创建证书验证资源,它将等待证书被提交。
发布。
resource "aws_acm_certificate_validation" "cert" {
count = "${length(var.domains) * (length(var.subdomains) + 1)}"
certificate_arn = "${element(aws_acm_certificate.cert.*.arn, count.index)}"
validation_record_fqdns = ["${aws_route53_record.cert_validation.*.fqdn}"]
}

最后一项资源的一个警告是,它将为每个资源创建一个资源实例。
请求的证书,但每个实例将取决于所有域中的所有FQDN,并且
子域。这不会影响AWS中的任何内容,但是terraform代码不会继续/完成
直到所有证书都签发为止。

这应该可以在一次应用运行中工作,而无需在第一遍中对任何资源进行 -target编码,
虽然 how long it takes for the validations tocomplete周围存在一个明显的已知问题,
通过terraform执行,因此即使不更改代码或计划/应用调用,也可能需要第二遍。

关于amazon-web-services - Terraform:创建和验证多个ACM证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50067317/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com