Terraform 与 A​​PI-Gateway、Route53 和 SSL 认证相互依赖问题

Chr*_*mas 7 amazon-web-services amazon-route53 terraform aws-api-gateway terraform-provider-aws

我似乎无法从 ACM 使用 terraform 在 API-Gateway、Route53 上获得 SSL 证书。似乎存在相互依赖的问题。

data "aws_route53_zone" "root_domain" {
  name         = "${var.route53_root_domain_name}"
  private_zone = false
}

# The domain name to use with api-gateway
resource "aws_api_gateway_domain_name" "domain_name" {
  domain_name = "${var.route53_sub_domain_name}"

  certificate_arn = "${aws_acm_certificate.cert.arn}"
}

resource "aws_route53_record" "sub_domain" {
  name    = "${var.route53_sub_domain_name}"
  type    = "A"
  zone_id = "${data.aws_route53_zone.root_domain.zone_id}"

  alias {
    name                   = "${aws_api_gateway_domain_name.domain_name.cloudfront_domain_name}"
    zone_id                = "${aws_api_gateway_domain_name.domain_name.cloudfront_zone_id}"
    evaluate_target_health = false
  }
}

resource "aws_acm_certificate" "cert" {
  # api-gateway / cloudfront certificates need to use the us-east-1 region
  provider          = "aws.cloudfront-acm-certs"
  domain_name       = "${var.route53_sub_domain_name}"
  validation_method = "DNS"

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_route53_record" "cert_validation" {
  name    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
  type    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
  zone_id = "${aws_route53_record.sub_domain.zone_id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl     = 60
}

resource "aws_acm_certificate_validation" "cert" {
  # api-gateway / cloudfront certificates need to use the us-east-1 region
  provider          = "aws.cloudfront-acm-certs"

  certificate_arn         = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]
}
Run Code Online (Sandbox Code Playgroud)

问题似乎是:

  1. aws_api_gateway_domain_name 需要 aws_acm_certificate
  2. aws_acm_certificate 必须经过验证,所以第 3 步
  3. aws_route53_record.cert_validation 需要 aws_route53_record.sub_domain
  4. aws_route53_record.subdomain 需要 aws_api_gateway_domain_name
  5. 前往 1

每次尝试使用给定的配置时,都会出现以下错误:

aws_api_gateway_domain_name.domain_name:创建 API 网关域名时出错:BadRequestException:无法将证书 arn:aws:acm:us-east-1:yyyy:certificate/zzzz 与 CloudFront 关联。此错误可能会阻止域名 audit-log.taspli.com 在 API Gateway 中使用长达 40 分钟。请确保证书域名与请求的域名匹配,并且该用户有权在“*”资源上调用 cloudfront:UpdateDistribution。状态码:400,请求 ID:xxxx

Chr*_*mas 9

我似乎通过将证书验证记录添加到根域而不是子域来解决问题。因此打破了循环依赖。

问题似乎是没有证书就无法创建子域,没有子域就无法验证证书。因此,情况陷入困境,无法解决。

您可以手动创建子域,但是如果您必须手动解决问题,那么自动化有什么意义。

所以我尝试将证书验证记录添加到根目录。突然它开始工作了,因为根域是在项目外部创建的。一种可以在外部处理的全球基础设施项目。然后,您的个人项目可以根据具体情况暂停该基础架构。

这是有效的terraform配置:

data "aws_route53_zone" "root_domain" {
  name         = "${var.route53_root_domain_name}"
  private_zone = false
}

# The domain name to use with api-gateway
resource "aws_api_gateway_domain_name" "domain_name" {
  domain_name = "${var.route53_sub_domain_name}"

  certificate_arn = "${aws_acm_certificate.cert.arn}"
}

resource "aws_route53_record" "sub_domain" {
  name    = "${var.route53_sub_domain_name}"
  type    = "A"
  zone_id = "${data.aws_route53_zone.root_domain.zone_id}"

  alias {
    name                   = "${aws_api_gateway_domain_name.domain_name.cloudfront_domain_name}"
    zone_id                = "${aws_api_gateway_domain_name.domain_name.cloudfront_zone_id}"
    evaluate_target_health = false
  }
}

resource "aws_acm_certificate" "cert" {
  # api-gateway / cloudfront certificates need to use the us-east-1 region
  provider          = "aws.cloudfront-acm-certs"
  domain_name       = "${var.route53_sub_domain_name}"
  validation_method = "DNS"
}

resource "aws_route53_record" "cert_validation" {
  name    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_name}"
  type    = "${aws_acm_certificate.cert.domain_validation_options.0.resource_record_type}"
  zone_id = "${data.aws_route53_zone.root_domain.zone_id}"
  records = ["${aws_acm_certificate.cert.domain_validation_options.0.resource_record_value}"]
  ttl     = 60
}

resource "aws_acm_certificate_validation" "cert" {
  # api-gateway / cloudfront certificates need to use the us-east-1 region
  provider          = "aws.cloudfront-acm-certs"

  certificate_arn         = "${aws_acm_certificate.cert.arn}"
  validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"]

  timeouts {
    create = "45m"
  }
}
Run Code Online (Sandbox Code Playgroud)