【发布时间】:2022-01-21 02:13:05
【问题描述】:
我有以下 terraform,旨在:
- 创建 S3 存储桶
- 创建一个 CloudFront 分配,以存储桶为源
- 创建 Route53 托管区域
- 创建 ACM 证书
- 通过 DNS 验证证书
- 向托管区域添加一些其他 DNS 记录。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.27"
}
}
required_version = ">= 1.0.4"
}
provider "aws" {
profile = "default"
region = "eu-west-2"
}
provider "aws" {
alias = "acm"
region = "us-east-1"
}
resource "aws_cloudfront_origin_access_identity" "frontend_access" {
}
data "aws_iam_policy_document" "s3_policy" {
statement {
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.frontend.arn}/*"]
principals {
type = "AWS"
identifiers = [aws_cloudfront_origin_access_identity.frontend_access.iam_arn]
}
}
}
resource "aws_s3_bucket_policy" "frontend_bucket_policy" {
bucket = aws_s3_bucket.frontend.id
policy = data.aws_iam_policy_document.s3_policy.json
}
resource "aws_s3_bucket" "frontend" {
bucket = "domain-frontend"
acl = "private"
}
resource "aws_acm_certificate" "default" {
provider = aws.acm
domain_name = "domain.com"
subject_alternative_names = ["api.domain.com"]
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
resource "aws_route53_record" "validation" {
for_each = {
for dvo in aws_acm_certificate.default.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = aws_route53_zone.main.zone_id
}
resource "aws_acm_certificate_validation" "certValidation" {
provider = aws.acm
certificate_arn = aws_acm_certificate.default.arn
validation_record_fqdns = [for record in aws_route53_record.validation : record.fqdn]
}
resource "aws_route53_zone" "main" {
name = "domain.com"
}
resource "aws_route53_record" "frontend_domain" {
zone_id = aws_route53_zone.main.zone_id
name = "domain.com"
type = "A"
alias {
name = aws_cloudfront_distribution.s3_distribution.domain_name
zone_id = aws_cloudfront_distribution.s3_distribution.hosted_zone_id
evaluate_target_health = false
}
}
resource "aws_route53_record" "mx_record" {
zone_id = aws_route53_zone.main.zone_id
name = "domain.com"
type = "MX"
ttl = 300
records = [
"1 aspmx.l.google.com.",
"10 alt3.aspmx.l.google.com.",
"10 alt4.aspmx.l.google.com.",
"5 alt1.aspmx.l.google.com.",
"5 alt2.aspmx.l.google.com."
]
}
resource "aws_route53_record" "google_site_verification" {
zone_id = aws_route53_zone.main.zone_id
name = "domain.com"
type = "TXT"
ttl = 300
records = ["VALUE"]
}
resource "aws_route53_record" "dkim" {
zone_id = aws_route53_zone.main.zone_id
name = "google._domainkey.domain.com"
type = "TXT"
ttl = 300
records = ["VALUE"]
}
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = aws_s3_bucket.frontend.bucket_regional_domain_name
origin_id = aws_s3_bucket.frontend.id
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.frontend_access.cloudfront_access_identity_path
}
}
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = aws_s3_bucket.frontend.id
forwarded_values {
query_string = true
cookies {
forward = "none"
}
}
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
restrictions {
geo_restriction {
restriction_type = "none"
locations = []
}
}
price_class = "PriceClass_100"
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.default.arn
ssl_support_method = "sni-only"
}
}
观察到的行为是 terraform 脚本在 aws_acm_certificate_validation.certValidation Still creating... [time elapsed] 上挂起 45 分钟,此时它失败并显示 Error creating CloudFront distribution: InvalidViewerCertificate: The specified SSL certificate doesn't exist, isn't in the us-east-1 region, isn't valid, or doesn't include a valid certificate chain. 我已手动检查托管区域上的记录,并且存在验证 CNAME 记录。
【问题讨论】:
-
我会尝试分离出这个资源创建。将 ACM 和 Route53 验证放在一个计划/根模块中,其余部分放在另一个中。您可以在第一个根模块中添加 terraform 输出,可以通过创建其余资源的第二个计划/根模块中的 terraform 数据源访问该输出。我现在没有时间确切地展示它的样子,但如果你仍然卡住,lmk & 我可以做到。
-
我认为记录的创建不正确。尽管存在 CNAME 记录,并且在我看来很好,但即使在 24 小时后,AWS 也没有验证证书。
-
我尝试了您的示例“domain.com”,但这对我也不起作用,但 domain.com 归其他人所有,这就是验证对我不起作用的原因。您能否确认您尝试验证的域名实际上归您所有,并且您有权访问注册商账户,您可以在其中将名称服务器 (NS) 更新为您的 Route53 AWS 名称服务器?
-
抱歉,出于隐私原因,我更换了域,它归我所有,通过 AWS Route53 购买,所以是的,我可以更新域的 NS 记录。
-
不幸的是,我无法使用相同的代码和我拥有的域重现您的错误。只有当我使用在注册商中没有正确名称服务器或我不拥有的域时,我才能重现此错误。所以我现在唯一能说的就是验证 CNAME 验证记录是在正确的托管区域中创建的,并确保您的托管区域是公开的,而不是私有的。
标签: amazon-web-services dns terraform terraform-provider-aws