访问其他 for 循环 Terraform 中 for_each 创建的所有资源

Lad*_*ili 0 amazon-web-services terraform terragrunt

我想创建多个 acm 证书和 Route53 记录以进行验证,只是无法弄清楚如何引用 Route53 资源块中的 for_each 创建的所有 ACM 资源,该资源块在 ACM 资源中循环以获取所有 DNS _validation 属性,代码正在运行如果我在变量中设置一个证书并直接使用名称引用它,那很好,但是如何循环到所有域名以在 for 循环中引用它?\n问题是这一行

\n

for dvo in aws_acm_certificate.web[for i in keys(var.certificates) : i]

\n

正在返回

\n

The index operator must end with a closing bracket ("]").

\n

像这样添加第二个括号

\n

for dvo in aws_acm_certificate.web[[for i in keys(var.certificates) : i]]

\n

返回错误

\n
\xe2\x94\x82\n\xe2\x94\x82   on main.tf line 21, in resource "aws_route53_record" "domain_validation":\n\xe2\x94\x82   21:     for dvo in aws_acm_certificate.web[[for i in keys(var.certificates) : i]].domain_validation_options : dvo.domain_name => {\n\xe2\x94\x82     \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n\xe2\x94\x82     \xe2\x94\x82 aws_acm_certificate.web is object with 2 attributes\n\xe2\x94\x82     \xe2\x94\x82 var.certificates is object with 2 attributes\n\xe2\x94\x82\n\xe2\x94\x82 The given key does not identify an element in this collection value: string\n\xe2\x94\x82 required.```\n
Run Code Online (Sandbox Code Playgroud)\n
resource "aws_acm_certificate" "web" {\n  for_each = var.certificates\n  domain_name       = "${replace(each.key, var.search_period, var.replace_period)}"\n  subject_alternative_names = each.value.subject_alternative_names\n  validation_method = "DNS"\n}\n\n\nresource "aws_route53_record" "domain_validation" {\n  for_each = var.dns_validation ? {\n    for dvo in aws_acm_certificate.web[[for i in keys(var.certificates) : i]].domain_validation_options : dvo.domain_name => {\n      name   = dvo.resource_record_name\n      record = dvo.resource_record_value\n      type   = dvo.resource_record_type\n    }\n  } : {}\n\n  allow_overwrite = true\n  name            = each.value.name #aws_acm_certificate.web[each.key].domain_validation_options.0.resource_record_name\n  records         = [each.value.record] #aws_acm_certificate.web[each.key].domain_validation_options.0.resource_record_value\n  ttl             = 60\n  type            = each.value.type #aws_acm_certificate.web[each.key].domain_validation_options.0.resource_record_type\n  zone_id         = data.aws_route53_zone.selected[[for i in keys(var.certificates) : i]].zone_id\n}\n
Run Code Online (Sandbox Code Playgroud)\n

var.certificates 看起来像这样:

\n
certificates  = {\n        "xxx.com" = {\n            subject_alternative_names = ["*.xxx.com","*.dev.xxx.com","*.stage.xxx.com","*.preprod.xxx.com"]\n        },\n        "zzz.com" = {\n            subject_alternative_names = ["*.dev.zzz.com","*.zzz.com"]\n        },\n\n\n       \n    }\n\n\n
Run Code Online (Sandbox Code Playgroud)\n

控制台中的 aws_acm_certificate.web 如下所示:

\n
``` \n> aws_acm_certificate.web\n{\n  "test.com" = {\n    "arn" = "arn:aws:acm:eu-west-1:584637875403:certificate/a6fed-01c6-4f2c-ad87-59c04877bd0b"\n    "certificate_authority_arn" = ""\n    "certificate_body" = tostring(null)\n    "certificate_chain" = tostring(null)\n    "domain_name" = "test.com"\n    "domain_validation_options" = toset([\n      {\n        "domain_name" = "*.test.com"\n        "resource_record_name" = "_d5e2266fa07c911501b806f3d19e.test.com."\n        "resource_record_type" = "CNAME"\n        "resource_record_value" = "_fcc7913c9269201f77625b7f71ec.ltyvprtsjl.acm-validations.aws."\n      },\n      {\n        "domain_name" = "*.dev.test.com"\n        "resource_record_name" = "_f2aa63aabaae8cd721bf0143dee6.dev.test.com."\n        "resource_record_type" = "CNAME"\n        "resource_record_value" = "_f461eca5849d2a3e218dea91955.ltyvprtsjl.acm-validations.aws."\n      },\n      {\n        "domain_name" = "*.preprod.test.com"\n        "resource_record_name" = "_2747174805245587c6f9811a1180.preprod.test.com."\n        "resource_record_type" = "CNAME"\n        "resource_record_value" = "_7d3ccdf1006b12074ebcbc9c3d1.ltyvprtsjl.acm-validations.aws."\n      },\n      {\n        "domain_name" = "*.stage.test.com"\n        "resource_record_name" = "_6f571d29f334dcccfe098a2371c.stage.test.com."\n        "resource_record_type" = "CNAME"\n        "resource_record_value" = "_9c9657a4839d827d1ff6db0ffd0.ltyvprtsjl.acm-validations.aws."\n      },\n      {\n        "domain_name" = "test.com"\n        "resource_record_name" = "_d5e2266fa07c91bad71501bd19e.test.com."\n        "resource_record_type" = "CNAME"\n        "resource_record_value" = "_fcc7913c926926efc05b7f71ec.ltyvprtsjl.acm-validations.aws."\n      },\n    ])\n    "id" = "arn:aws:acm:eu-west-1:584637875403:certificate/a6fed5981c6-4f2c-ad87-59c04877bd0b"\n    "options" = tolist([\n      {\n        "certificate_transparency_logging_preference" = "ENABLED"\n      },\n    ])\n    "private_key" = (sensitive)\n    "status" = "ISSUED"\n    "subject_alternative_names" = toset([\n      "*.test.com",\n      "*.dev.test.com",\n      "*.preprod.test.com",\n      "*.stage.test.com",\n    ])\n    "tags" = tomap({})\n    "tags_all" = tomap({})\n    "validation_emails" = tolist([])\n    "validation_method" = "DNS"\n  }\n}\n``` \n
Run Code Online (Sandbox Code Playgroud)\n

Mar*_*cin 5

你必须先把你的东西弄平aws_acm_certificate.web。例如:

locals {
  certificate_web_flat = merge([
    for hzone, certs in aws_acm_certificate.web:   {
        for domain_validation_option in certs.domain_validation_options:
          "${hzone}-${domain_validation_option.domain_name}" => {
            "hzone" = hzone
            "domain_name" = domain_validation_option.domain_name
             resource_record_name   = domain_validation_option.resource_record_name
             resource_record_value = domain_validation_option.resource_record_value
             resource_record_type   = domain_validation_option.resource_record_type            
          }
      }
  ]...)
}
Run Code Online (Sandbox Code Playgroud)

然后

resource "aws_route53_record" "domain_validation" {
  for_each = var.dns_validation ? local.certificate_web_flat : {}

  allow_overwrite = true
  name            = each.value.resource_record_name
  records         = [each.value.resource_record_value] 
  ttl             = 60
  type            = each.value.resource_record_type 
  zone_id         = data.aws_route53_zone.selected[each.value.hzone].zone_id
}
Run Code Online (Sandbox Code Playgroud)