Terraform:使用Cloudflare DNS进行AWS证书验证的迭代列表



我在tfvars文件中有一个映射,其中包含Cloudflare区域id、站点地址和区域(域(,我想遍历该映射,生成ACM证书,并在Cloudflare中创建证书验证DNS记录。我的地图是这样的;

my_domains = {
example1 = {
cloudflare_zone_id = "00000000000000000000000000001"
address            = "dev.example1.com"
domain             = "example1.com"
}
example2 = {
cloudflare_zone_id = "0000000000000000000000000000002"
address            = "dev.example2.com"
domain             = "example2.com"
}
example3 = {
cloudflare_zone_id = "0000000000000000000000000000003"
address            = "dev.library.example3.com"
domain             = "example3.com"
}
}

然后,我有以下代码用于证书创建和验证:

resource "aws_acm_certificate" "my_certs" {
for_each          = var.my_domains
domain_name       = each.value.address
validation_method = "DNS"
subject_alternative_names = [
"*.${each.value.address}"
]
lifecycle {
create_before_destroy = true
}
}
resource "cloudflare_zone" "my_zone" {
for_each = var.my_domains
zone     = each.value.domain
type     = "full"
}
resource "cloudflare_record" "my_certificate_validation" {
for_each = {
for dvo in aws_acm_certificate.my_certs.domain_validation_options : dvo.domain_name => {
name   = dvo.resource_record_name
record = dvo.resource_record_value
type   = dvo.resource_record_type
}
}
zone_id = cloudflare_zone.my_zone.id
name    = each.value.name
value   = trimsuffix(each.value.record, ".")
type    = each.value.type
ttl     = 1
proxied = false
}

当我运行一个计划时,我会得到以下错误:

错误:缺少资源实例密钥

在cfcertvalidation.tf第23行;cloudflare_record"my_certificate_validation":23:对于aws_acm_certificate.my_certs.domain_validation_options:dvo.domain_name=>{

因为aws_acm_certificate.my_certs具有"for_each";集,其属性必须为在特定实例上访问。

例如,要与引用资源的索引关联,请使用:aws_acm_certificate.my_certs[each.key]

错误:缺少资源实例密钥

在cfcertvalidation.tf第30行;cloudflare_record"my_certificate_validation":30:zone_id=cloudflare_zone.my_zone.id

因为cloudflare_zone.cdt具有";for_each";集,其属性必须为在特定实例上访问。

例如,要与引用资源的索引关联,请使用:cloudflare_zone.my_zone[each.key]

注意:我添加了cloudflare_zone资源,而不是使用地图中已经存在的区域id,以简化故障排除过程。

我确信答案在使用[each.key]的建议中,但我不确定如何实现它。

如有任何协助,我们将不胜感激。

我已经为我的解决方案更改了一些映射,所以为了完整起见,我在这里包含了更改后的映射:

variable "my_domains" {
type = map(any)
default = {
example1 = {
cf_zone_id         = "0000000000000000000000000000"
address            = "example1.com"
zone               = "example1.com"
}
example2 = {
cf_zone_id         = "0000000000000000000000000000"
address            = "example2.com"
zone               = "example2.com"
}
example3 = {
cf_zone_id         = "0000000000000000000000000000"
address            = "library.example3.com"
zone               = "example3.com"
}
}
}

下面是工作解决方案,我们首先创建一个类型为list的本地变量,循环my_domains映射以获得我们需要的证书验证记录。然后将其转换为映射,cloudflare_record资源使用该映射来创建相关的DNS条目。

resource "aws_acm_certificate" "my_certs" {
for_each                  = var.my_domains
domain_name               = "${var.env_url_prefix}${var.my_domains[each.key] ["address"]}"
validation_method         = "DNS"
subject_alternative_names = ["*.${var.env_url_prefix}${var.my_domains[each.key]["address"]}"]
lifecycle {
create_before_destroy = true
}
}
locals {
validation = [
for certs in keys(var.my_domains) : {
for dvo in aws_acm_certificate.my_certs[certs].domain_validation_options : dvo.domain_name => {
name    = dvo.resource_record_name
value   = trimsuffix(dvo.resource_record_value, ".")
type    = dvo.resource_record_type
zone_id = var.my_domains[certs]["cf_zone_id"] # Get the zone id
}
}
]
# transform the list into a map
validation_map = { for item in local.validation : keys(item)[0] => values(item)[0]
}
}

resource "cloudflare_record" "my_cert_validations" {
for_each = local.validation_map
zone_id = local.validation_map[each.key]["zone_id"]
name    = local.validation_map[each.key]["name"]
value   = local.validation_map[each.key]["value"]
type    = local.validation_map[each.key]["type"]
ttl     = 1
proxied = false #important otherwise validation will fail
}

最新更新