使用 terraform aws_acm_certificate_validation 时缺少 DNS 验证记录

Ale*_*ioG 3 dns amazon-web-services amazon-route53 terraform terraform-provider-aws

在尝试创建 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" {
Run Code Online (Sandbox Code Playgroud)

笔记:我没有包括创建基础结构其他部分的执行计划,但我只报告了有问题的部分。

这是我的 tf 文件:

路由53.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
  }
}
Run Code Online (Sandbox Code Playgroud)

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"
    }
}
Run Code Online (Sandbox Code Playgroud)

分布.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"
    }
}
Run Code Online (Sandbox Code Playgroud)

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

错误日志分析

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

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

到目前为止,这是我能找到的,但我不知道如何继续前进。任何人以前来过这里并且可以帮助解决以下问题?

谢谢!

Mar*_*ski 8

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

结果证明验证资源需要包含所有生成的 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
}
Run Code Online (Sandbox Code Playgroud)

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

希望有帮助!


Gio*_*ino 5

以下是我在配置中解决此问题的方法,并对 Marcin Wyszynski 的答案进行了轻微修改。由于验证可能会导致重复的 DNS 记录,因此请使用allow_overwrite = trueinaws_route53_record来绕过already exists错误并确保它们全部创建。

配置.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"
}
Run Code Online (Sandbox Code Playgroud)

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"
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 -3

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