微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Terraform嵌套的for_each aws_acm_certificate domain_validation_options

如何解决Terraform嵌套的for_each aws_acm_certificate domain_validation_options

我正在使用terraform v0.13.5。如果我为在AWS中注册的域创建单个AWS证书资源,则还可以使用以下方法成功创建Route53 DNS验证记录:

resource "aws_acm_certificate" "api" {
  domain_name       = "api.example.com"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_route53_record" "api_validation" {
  for_each = {
    for dvo in aws_acm_certificate.api.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      record = dvo.resource_record_value
      type   = dvo.resource_record_type
    }
  }
  allow_overwrite = true
  name            = each.value.name
  records         = [each.value.record]
  ttl             = 60
  type            = each.value.type
  zone_id         = data.aws_route53_zone.example.zone_id # already exists
}

但是,我想使用带有映射变量的for_each创建多个证书。我使用以下方法定义了aws_acm_certificate资源:

variable "sub_domains" {
  type = map
  default = {
    "api"      = "api"
    "api_test" = "api.test"
  }
}

resource "aws_acm_certificate" "certs" {
  for_each          = var.sub_domains
  domain_name       = "${each.value}.example.com"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

我无法确定在定义验证记录时如何引用创建的动态证书。 以下代码段现在不起作用

resource "aws_route53_record" "api_validation" {
  for_each = {
    for dvo in aws_acm_certificate.certs.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      record = dvo.resource_record_value
      type   = dvo.resource_record_type
    }
  }
  allow_overwrite = true
  name            = each.value.name
  records         = [each.value.record]
  ttl             = 60
  type            = each.value.type
  zone_id         = data.aws_route53_zone.myzone.zone_id # already exists
}

terraform抱怨以下错误

Because aws_acm_certificate.certs has "for_each" set,its attributes must be
accessed on specific instances.

那么如何为每个动态创建的证书获取domain_validation_options

解决方法

您可以通过几种方式处理此问题。

  1. 您似乎正在使用相同的高级域。在这种情况下,它是example.com。您应该考虑在subject_alternative_names资源中使用aws_acm_certificate选项。这将只需要一个具有多个SAN的证书,并且提供商文档中提供的逻辑将根据需要创建验证记录集。

  2. 如果您要创建独特的个人证书,建议使用模块化方法。如果仅查看通过DNS验证的证书,则可以获取那里的所有代码(加上未显示的aws_acm_certificate_validation资源)并将其打包到其自己的文件夹中的模块中。然后,您可以使用以下方式调用该模块:

module "acm_certs" {
  for_each = var.sub_domains

  source = "../modules/acm_certificate/"

  certificate_domain_name   = "${each.value}.example.com"
  validation_domain_name    = "example.com"
}

请注意,我们可以使用for_each来调用Terraform v0.13 +中的模块,从而使我们能够更灵活地完成您所要的内容,但不会在可重用代码本身中引入复杂性。

您看到的每个变量都有模块的输入。如果您需要更详细地解释我所说的模块的含义,请回答,我会更深入地介绍。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。