具有API网关,Route53和SSL认证相互依赖性问题的Terraform

时间:2019-03-06 19:52:02

标签: amazon-web-services aws-api-gateway terraform amazon-route53 terraform-provider-aws

我似乎无法从terraform的API网关Route53的ACM处获得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}"]
}

问题似乎是:

  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网关中长达40分钟。请确保证书   域名与请求的域名匹配,并且该用户具有   在'*'资源上调用cloudfront:UpdateDistribution的权限。     状态码:400,请求ID:xxxx

1 个答案:

答案 0 :(得分:0)

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

问题似乎是没有证书就无法创建子域,而没有子域也无法验证证书。因此,局势陷入僵局,无法解决。

您可以手动创建子域,但是如果您必须手动解决问题,那么自动化的意义何在?

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

这是有效的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"
  }
}