【问题标题】:Missing DNS validation record when using terraform aws_acm_certificate_validation使用 terraform aws_acm_certificate_validation 时缺少 DNS 验证记录
【发布时间】:2019-12-29 20:26:24
【问题描述】:

在尝试创建 AWS Route53 资源和 AWS Certificate Manager 资源时,我一整天都遇到 Terraform 错误。 这 2 位是更广泛项目(通过其静态服务功能托管在 s3 中的网站)的一部分。

特别是在证书的 DNS 验证过程中,当 CNAME 记录作为 DNS 记录插入 Route53 时,会弹出错误。

我将列出错误,然后描述设置。

错误

terraform plan -var-file=production.vars

Creating...
module.infrastructure.aws_route53_record.idarth-validation-record: Still creating... [10s elapsed]
module.infrastructure.aws_route53_record.idarth-validation-record: Still creating... [20s elapsed]
module.infrastructure.aws_route53_record.idarth-validation-record: Still creating... [30s elapsed]
module.infrastructure.aws_route53_record.idarth-validation-record: Still creating... [40s elapsed]
module.infrastructure.aws_route53_record.idarth-validation-record: Still creating... [50s elapsed]
module.infrastructure.aws_route53_record.idarth-validation-record: Still creating... [1m0s elapsed]
module.infrastructure.aws_route53_record.idarth-validation-record: Still creating... [1m10s elapsed]
module.infrastructure.aws_route53_record.idarth-validation-record: Creation complete after 1m12s [id=ZB4TSGZTTZ3CQ__7bc5230529c8192e8e697aeab0ec0eb9.idarth.com._CNAME]
module.infrastructure.aws_acm_certificate_validation.idarth-ssl-certificate: Creating...
2019/08/24 18:32:40 [ERROR] module.infrastructure: eval: *terraform.EvalSequence, err: 1 error occurred:
    * missing www.idarth.com DNS validation record: _18ff46dac48c6d852b696306dfa57093.www.idarth.com

2019/08/24 18:32:40 [TRACE] [walkApply] Exiting eval tree: module.infrastructure.aws_acm_certificate_validation.idarth-ssl-certificate

Error: 1 error occurred:
    * missing www.idarth.com DNS validation record: _18ff46dac48c6d852b696306dfa57093.www.idarth.com



  on ../modules/route53.tf line 14, in resource "aws_acm_certificate_validation" "idarth-ssl-certificate":
  14: resource "aws_acm_certificate_validation" "idarth-ssl-certificate" {

注意:我没有包括创建基础设施其他部分的执行计划,但我只报告了有问题的部分。

这是我的 tf 文件:

route53.tf

resource "aws_route53_zone" "idarth-hosted-zone" {
  name = "${var.domain_name}"
}


resource "aws_route53_record" "idarth-validation-record" {
  name    = "${aws_acm_certificate.idarth-ssl-certificate.domain_validation_options.0.resource_record_name}"
  type    = "${aws_acm_certificate.idarth-ssl-certificate.domain_validation_options.0.resource_record_type}"
  zone_id = "${aws_route53_zone.idarth-hosted-zone.zone_id}"
  records = ["${aws_acm_certificate.idarth-ssl-certificate.domain_validation_options.0.resource_record_value}"]
  ttl     = "60"
}

resource "aws_acm_certificate_validation" "idarth-ssl-certificate" {
  provider        = "aws.us_east_1"
  certificate_arn = "${aws_acm_certificate.idarth-ssl-certificate.arn}"
  validation_record_fqdns = [
    "${aws_route53_record.idarth-validation-record.fqdn}"
  ]
}

resource "aws_route53_record" "idarth-record-domain" {
  zone_id = "${aws_route53_zone.idarth-hosted-zone.zone_id}"
  name = "${var.domain_name}"
  type = "A"

  alias {
    name = "${aws_cloudfront_distribution.idarth-cloudfront-distr.domain_name}"
    zone_id = "${aws_cloudfront_distribution.idarth-cloudfront-distr.hosted_zone_id}"
    evaluate_target_health = false
  }
}

resource "aws_route53_record" "idarth-record-domain-www" {
  zone_id = "${aws_route53_zone.idarth-hosted-zone.zone_id}"
  name = "${var.domain_name_www}"
  type = "A"

  alias {
    name = "${aws_cloudfront_distribution.idarth-cloudfront-distr.domain_name}"
    zone_id = "${aws_cloudfront_distribution.idarth-cloudfront-distr.hosted_zone_id}"
    evaluate_target_health = false
  }
}

ssl_certificate.tf

provider "aws" {
  alias           = "us_east_1"
  region          = "us-east-1"
}

resource "aws_acm_certificate" "idarth-ssl-certificate" {
  provider        = "aws.us_east_1"

  domain_name       = "${var.domain_name}"
  subject_alternative_names = ["${var.domain_name_www}"]
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }

  tags = {
        Project = "${var.name}-${var.env}"
        Scope    = "personal-blog"
    }
}

distribution.tf

resource "aws_cloudfront_distribution" "idarth-cloudfront-distr" {
  depends_on = ["aws_acm_certificate_validation.idarth-ssl-certificate"]

  origin {
    domain_name = "${aws_s3_bucket.idarth-static-site-host.bucket_regional_domain_name}"
    origin_id   = "${var.domain_name}"

    /*s3_origin_config {
      origin_access_identity = "origin-access-identity/cloudfront/ABCDEFG1234567"
    }*/
  }

  enabled             = true
  is_ipv6_enabled     = true
  default_root_object = "index.html"

  /*logging_config {
    include_cookies = false
    bucket          = "mylogs.s3.amazonaws.com"
    prefix          = "myprefix"
  }*/

  aliases = ["${var.domain_name}", "${var.domain_name_www}"]

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "${var.domain_name}"

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    compress = true
    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }


  #price_class = "PriceClass_200"

  restrictions {
    geo_restriction {
      restriction_type = "none"
      locations        = []
    }
  }

  viewer_certificate {
    acm_certificate_arn  = "${aws_acm_certificate_validation.idarth-ssl-certificate.certificate_arn}"
    ssl_support_method  = "sni-only"
  }


    tags = {
        Project = "${var.name}-${var.env}"
        Scope    = "personal-blog"
    }
}

Terraform 版本:0.12.7,aws 提供者版本:v2.25.0_x4

错误日志分析

我花了一天时间尝试调试上面的错误,以下是我的想法:

  • 证书正在为 2 个域(变量:var.domain_name、var.domain_name_www)生成 2 个 CNAME:_7bc5230529c8192e8e697aeab0ec0eb9.idarth.com._CNAME_18ff46dac48c6d852b696306dfa57093.www.
  • 如您在执行计划的日志中所见,第一个的创建已成功创建,而第二个则导致问题。
  • 查看 AWS 控制台,我可以看到 DNS 托管区域中插入的第一个 CNAME,但不是第二个。即使插入了 DNS 托管区域,该记录的证书仍会导致等待验证。

这是迄今为止我能找到的,但我不知道如何继续前进。 有没有人来过这里并且可以提供以下帮助?

谢谢!

【问题讨论】:

    标签: amazon-web-services dns terraform amazon-route53 terraform-provider-aws


    【解决方案1】:

    您现在可以使用validate_certificate = false 作为解决方法,但这已在此模块的最新版本中解决,请尝试更新您的 terraform。

    【讨论】:

    【解决方案2】:

    该区域不应该有最终的. 吗?

    resource "aws_route53_zone" "idarth-hosted-zone" {
      name = "${var.dns_zone}."
    }
    

    在类似的场景中,我使用 CNAME 作为指向 CloudFront 分配的 DNS 记录

    resource aws_route53_record www {
        zone_id = data.aws_route53_zone.selected.zone_id
        name    = "openbanking.${var.dns_zone}"
        type    = "CNAME"
        records = [aws_cloudfront_distribution.open_banking_public_website.domain_name]
        ttl     = 60
    }
    

    HTH

    【讨论】:

    • 您好 Giulio,我仍然面临与 CNAME 相同的问题。这个 aws_acm_certificate_validation 在线上有很多混淆。我读过很多人面临与我类似的问题,目前还没有明确的答案。感谢您在这里提供帮助,谢谢!
    • 我有工作代码,4-6 周前在 Terraform 0.12 中约会,所以可以完成。我无法完整分享它,但应该通过博客文章部分显示它。公开时会发布链接。
    • 这对 Giulio 有帮助,如果可以的话,如果你准备好了,你可以在这里 ping 它。
    【解决方案3】:

    不确定这是否仍然相关,但我今天遇到了同样的问题并在这里找到了这个问题,所以也许我会把答案留给后代。

    原来验证资源需要包含所有生成的 CNAME,如下所示:

    resource "aws_acm_certificate" "some-cert" {
      provider = "aws.us-east-1"
    
      domain_name               = "some.domain"
      validation_method         = "DNS"
      subject_alternative_names = ["www.some.domain"]
    }
    
    resource "aws_route53_record" "cert-validations" {
      count = length(aws_acm_certificate.some-cert.domain_validation_options)
    
      zone_id = var.zone_id
      name    = element(aws_acm_certificate.some-cert.domain_validation_options.*.resource_record_name, count.index)
      type    = element(aws_acm_certificate.some-cert.domain_validation_options.*.resource_record_type, count.index)
      records = [element(aws_acm_certificate.some-cert.domain_validation_options.*.resource_record_value, count.index)]
      ttl     = 60
    }
    
    resource "aws_acm_certificate_validation" "cert-validation" {
      provider = "aws.us-east-1"
    
      certificate_arn         = aws_acm_certificate.some-cert.arn
      validation_record_fqdns = aws_route53_record.cert-validations.*.fqdn
    }
    

    请特别注意,我们有一个 aws_acm_certificate_validation 资源,但它包含来自所有生成的验证 CNAME DNS 记录的多个 validation_record_fqdns 的列表。

    希望有帮助!

    【讨论】:

    • Terraform 抛出一条错误消息,指出““计数”值取决于在应用之前无法确定的资源属性,因此 Terraform 无法预测将创建多少个实例。”你为此做了什么?你用过“-target”吗?
    • 想通了。制作了一个可变名称列表,然后将其用于计数。前任。 count = length(var.alternative-names) + 1.
    • 是的,这是一种选择。另一种选择是将其分成两次运行 - 首先,创建记录,然后是验证。
    【解决方案4】:

    以下是我在配置中解决此问题的方法,对 Marcin Wyszynski 的答案稍作修改。由于验证可能导致重复的 DNS 记录,请使用 aws_route53_record 中的 allow_overwrite = true 绕过 already exists 错误并确保它们都已创建。

    config.tf

    # locals must be used so ${var.env} can be interpolated in the definition
    locals {
      tags = {
        Name        = "${var.domain_name}"
        Environment = "${var.env}"
      }
      cert_sans = ["www.${var.domain_name}", "cdn.${var.domain_name}", "*.${var.domain_name}"]
    }
    
    variable "env" {
      default = "production"
    }
    
    variable "domain_name" {
      default = "your-domain.com"
    }
    

    acm.tf

    resource "aws_acm_certificate" "site" {
      domain_name               = var.domain_name
      validation_method         = "DNS"
      tags                      = local.tags
      subject_alternative_names = local.cert_sans
    
      lifecycle {
        create_before_destroy = true
      }
    }
    
    resource "aws_route53_record" "cert_validations" {
      count = length(local.cert_sans) + 1
    
      zone_id         = aws_route53_zone.public.zone_id
      allow_overwrite = true # This is what allowed for conflict resolution in DNS
      name            = element(aws_acm_certificate.site.domain_validation_options.*.resource_record_name, count.index)
      type            = element(aws_acm_certificate.site.domain_validation_options.*.resource_record_type, count.index)
      records         = [element(aws_acm_certificate.site.domain_validation_options.*.resource_record_value, count.index)]
      ttl             = 60
    }
    
    resource "aws_acm_certificate_validation" "cert_validation" {
      certificate_arn         = aws_acm_certificate.site.arn
      validation_record_fqdns = aws_route53_record.cert_validations.*.fqdn
    
      timeouts {
        create = "120m"
      }
    }
    

    【讨论】:

      【解决方案5】:

      我在生成一个证书时遇到了这个问题,该证书在不同的 Route 53 区域中有四个主题备用名称。如果不是在凌晨 2:30 的一个奇怪的清醒时刻偶然发现修复,我不确定我是否会修复它:)

      给定一个包含最多四个主题备用名称的证书:

      locals {
        subject_alternative_names = compact([
          "${var.include_apex_zone_names_in_aliases ? "${var.env}.${var.dns_zone_name}" : null }",
          "${var.include_apex_zone_names_in_aliases ? var.last_mile_apex_zone_name : null }",
          "${var.env}.${var.last_mile_apex_zone_name}"
        ])
      }
      resource "aws_acm_certificate" "cert" {
        domain_name       = var.include_apex_zone_names_in_aliases ? var.dns_zone_name : "${var.env}.${var.dns_zone_name}"
        subject_alternative_names = local.subject_alternative_names
        validation_method = "DNS"
      
        lifecycle {
          create_before_destroy = true
        }
      }
      

      我必须在每个 DNS 区域中创建 ACM 证书验证记录,所以我有四个这样的块:

      resource "aws_route53_record" "acm_validation" {
        for_each = {
          for dvo in aws_acm_certificate.cert.domain_validation_options : dvo.domain_name => {
            name   = dvo.resource_record_name
            record = dvo.resource_record_value
            type   = dvo.resource_record_type
          } if dvo.domain_name == var.dns_zone_name
        }
      
        allow_overwrite = true
        name            = each.value.name
        records         = [each.value.record]
        ttl             = 60
        type            = each.value.type
        zone_id         = var.create_apex_zones ? aws_route53_zone.apex[0].zone_id : data.aws_route53_zone.apex.0.zone_id
      }
      

      代码最初有一个 aws_acm_cert_validation 资源直接从文档中的示例中提取:

      resource "aws_acm_certificate_validation" "cert" {
        certificate_arn         = aws_acm_certificate.cert.arn
        validation_record_fqdns = [for record in aws_route53_record.acm_validation : record.fqdn]
      }
      

      但我必须将所有aws_route53_record 资源合并到validation_record_fqdns 参数的映射中:

      resource "aws_acm_certificate_validation" "cert" {
        certificate_arn         = aws_acm_certificate.cert.arn
        validation_record_fqdns = [for record in merge(aws_route53_record.acm_validation, aws_route53_record.env_acm_validation, aws_route53_record.last_mile_apex_acm_validation, aws_route53_record.last_mile_environment_acm_validation) : record.fqdn]
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-28
        • 1970-01-01
        • 2022-12-03
        • 2021-10-21
        • 2017-01-15
        • 1970-01-01
        • 2020-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多