Terraform 与 API-Gateway、Route53 和 SSL 认证相互依赖问题
Posted
技术标签:
【中文标题】Terraform 与 API-Gateway、Route53 和 SSL 认证相互依赖问题【英文标题】:Terraform with API-Gateway, Route53, and SSL Certification interdependency problem 【发布时间】:2019-07-28 14:16:00 【问题描述】:我似乎无法使用 terraform 从 ACM 获得在 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"]
问题似乎是:
-
aws_api_gateway_domain_name 需要 aws_acm_certificate
aws_acm_certificate 必须经过验证,所以第 3 步
aws_route53_record.cert_validation 需要 aws_route53_record.sub_domain
aws_route53_record.subdomain 需要 aws_api_gateway_domain_name
转到 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
【问题讨论】:
3. aws_route53_record.cert_validation requires aws_route53_record.sub_domain
是假的。它只需要验证记录,而不需要作为证书主题的子域的记录。您可以通过为工作中的 Route 53 托管区域中不存在的子域手动创建经过 DNS 验证的 ACM 证书来证明这一点。错误消息仅表明证书尚未被验证,而不是验证不能/不会成功。
啊,所以我可以删除 zone_id 字段,然后它会成功吗?如果不是我创建它的域,它怎么知道在哪里添加记录作为它的父项?
好的,所以我验证了我的说法,即用于证书验证的 aws_route53_record 需要 zone_id。因此,要附加记录的区域必须先存在,然后才能附加记录。这是有道理的。那么问题是,它所附加的子域的 aws_route53_record 需要来自 api 网关域名的记录,以便将别名附加到 api 网关创建的云端分发。再说一次,这只是另一个我不确定如何解决的循环依赖。
【参考方案1】:
我似乎通过将证书验证记录添加到根域而不是子域来解决问题。从而打破循环依赖。
问题似乎是没有证书就无法创建子域,没有子域就无法验证证书。所以情况陷入僵局,无法解决。
您可以手动创建子域,但如果您必须手动解决问题,那么自动化的意义何在。
所以我尝试将证书验证记录添加到根目录。突然它开始工作,因为根域是在项目外部创建的。一种可以在外部处理的全球基础设施项目。然后,您的各个项目可以根据具体情况暂停该基础架构。
这是有效的 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"
【讨论】:
以上是关于Terraform 与 API-Gateway、Route53 和 SSL 认证相互依赖问题的主要内容,如果未能解决你的问题,请参考以下文章