🌟

【Terraform】ACMでワイルドカードを含む証明書をDNS認証したときのエラー

2025/01/12に公開

Terraform で ACM の SSL 証明書を作成しました。

SANs にワイルドカードを指定したところエラーになりました。

今後もハマりそうなのでまとめておきます

やりたかったこと

  • Terraform で ACM の SSL 証明書を作成
  • 証明書は SANs にワイルドカードを含む
    • つまり、証明書は example.com と*.example.com のドメインを含む
  • Route53 で DNS 認証する

エラー

terraform apply した際に以下のエラーが出ました

│ Error: creating Route 53 Record: InvalidChangeBatch: [Tried to create resource record set [name='_c8a4d1c796965d52314cf626cb2f04f5.example.com.', type='CNAME'] but it already exists]
│ 	status code: 400, request id: 16f72747-91fd-4deb-900d-9c548d3acbd2
│
│   with module.route53.aws_route53_record.cert["*.example.com"],
│   on ../../modules/route53/main.tf line 35, in resource "aws_route53_record" "cert":
│   35: resource "aws_route53_record" "cert" {

Route53 で DNS 検証用のレコードを作成しようとしたけど、すでにそのレコードあります

みたいなエラーかなと

原因調査

https://budougumi0617.github.io/2020/11/07/define_https_subdomain_by_terraform/

こちらの記事によると、ルートドメインとワイルドカードの検証用レコードが一緒みたい。

ルートドメインとワイルドカードドメインで検証用レコードを別々に作成しようとするため、
同じ内容のレコードを2つ作成することになりすでにレコードがありますになっていました。

対処法としては、

検証用レコードを作成するaws_route53_record にてレコードの上書きを許容する
allow_overwrite を trueにすれば OK です!

コード修正

検証用のレコードに allow_overwrite = true を追加します

resource "aws_route53_zone" "hostzone" {
  name = "example.com"
}

# ACMでSSL証明書を作成
resource "aws_acm_certificate" "cert" {
  domain_name               = "example.com"
  validation_method         = "DNS"
  subject_alternative_names = ["*.example.com"]

  lifecycle {
    create_before_destroy = true
  }
}

# SSL証明書の検証
resource "aws_acm_certificate_validation" "cert" {
  certificate_arn         = aws_acm_certificate.cert.arn
  validation_record_fqdns = flatten([values(aws_route53_record.cert)[*].fqdn])
}

# SSL証明書のDNS検証用レコード
resource "aws_route53_record" "cert" {
  for_each = {
    for dvo in aws_acm_certificate.cert.domain_validation_options : dvo.domain_name => {
      name   = dvo.resource_record_name
      record = dvo.resource_record_value
      type   = dvo.resource_record_type
    }
  }

  name            = each.value.name
  type            = each.value.type
  records         = [each.value.record]
  zone_id         = aws_route53_zone.hostzone.zone_id
  ttl             = 60
+ allow_overwrite = true
}

再度 apply

再度 Apply したら通りました!

よかったーー

参考

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record#allow_overwrite

https://budougumi0617.github.io/2020/11/07/define_https_subdomain_by_terraform/

https://fusagiko.hatenablog.jp/entry/2019/09/30/223700

Discussion