Terraformを使ったACMリソース(ワイルドカード証明書)作成

AWSIaC

Terraformを活用してACMリソースを作成する手順を、各動作フローとともに詳しく整理しました。
今回は、Route 53に「api」「www」「blog」のサブドメインを登録済みのドメイン「example.com」に対して、ワイルドカード証明書を発行した。

1. 手順

1-1. acmを記述

acm.tf記載例

# ---------------------------------------------
# Certificate
# ---------------------------------------------

# ①:証明書を発行するためのACMリソースを記述 
resource "aws_acm_certificate" "example_cert" {
  domain_name       = "*.${var.domain}"   # ワイルドカード証明書のドメイン名
  validation_method = "DNS"                 # DNS認証を使用

  tags = {
    Name = "wildcard-ssl/tls-cert"
  }

  depends_on = [
    aws_route53_zone.example_zone  # Route53ゾーンに依存
  ]
}

# ②:DNSレコードを作成してACM証明書の認証を行う(DNS認証)
resource "aws_route53_record" "route53_acm_dns_resolve" {
  for_each = {
    for dvo in aws_acm_certificate.example_cert.domain_validation_options : 
      dvo.domain_name => {
        name   = dvo.resource_record_name  # レコード名
        type   = dvo.resource_record_type  # レコードタイプ(通常はCNAME)
        record = dvo.resource_record_value  # レコード値
      }
  }

  allow_overwrite = true  # 既存のレコードを上書きする設定
  zone_id         = aws_route53_zone.example_zone.zone_id  # Route53ゾーンのID
  name            = each.value.name  # レコード名
  type            = each.value.type  # レコードタイプ
  ttl             = 600  # TTL(キャッシュの有効時間)
  records         = [each.value.record]  # 証明書の認証用レコード値
}

# DNSレコードを使ってACM証明書の認証を完了させる
resource "aws_acm_certificate_validation" "cert_valid" {
  certificate_arn         = aws_acm_certificate.example_cert.arn  # 証明書のARN
  validation_record_fqdns = [for record in aws_route53_record.route53_acm_dns_resolve : record.fqdn]  # DNSレコードのFQDN
}
補足:変数のサンプル
# 変数のサンプル
variable "domain" {
  description = "The domain name for the certificate"
  type        = string
  default     = "example.com"
}

# Route53ゾーンのリソース(例として)
resource "aws_route53_zone" "example_zone" {
  name = "${var.domain}"  # ドメイン名に基づいてゾーンを作成
}


2. 説明

①:証明書を発行するためのACMリソースを記述

今回は、ワイルドカード証明書、DNS検証で進めていきます。

  domain_name       = "*.${var.domain}"   # ワイルドカード証明書のドメイン名
  validation_method = "DNS"                 # DNS認証を使用 ACMでは"DNS/EMAIL"のみ


②:DNSレコードを作成してACM証明書の認証を行う(ドメイン所有者確認)

1. ACMリソースでvalidation_method = "DNS"を選択すると、内部でdomain_validation_optionsが生成されます。(validation_methodで"DNS"を選択した場合はCNAMEレコード情報が生成される)

自動生成されたdomain_validation_optionsのサンプル
(ドメイン「example.com」にサブドメイン「api」「www」「blog」登録済みの場合)

"domain_validation_options": [
    {
        "domain_name": "api.example.com",  // 証明書が発行されるドメイン名(例: api.example.com)
        "resource_record_name": "_abcdef1234567890.api.example.com",  // DNS検証用のCNAMEレコード名(例: _abcdef1234567890.api.example.com)
        "resource_record_type": "CNAME",  // DNSレコードタイプ(通常は "CNAME")
        "resource_record_value": "_xyz9876543210.acm-validations.aws"  // 設定すべきCNAMEレコードの値(ACMが提供する検証用のレコード値)
    },
    {
        "domain_name": "www.example.com",  // 証明書が発行される別のドメイン名(例: www.example.com)
        "resource_record_name": "_ghijk1234567890.www.example.com",  // このドメインの検証用CNAMEレコード名
        "resource_record_type": "CNAME",  // DNSレコードタイプ(通常は "CNAME")
        "resource_record_value": "_uvw9876543210.acm-validations.aws"  // 検証用のCNAMEレコード値
    },
    {
        "domain_name": "blog.example.com",  // 証明書が発行される別のドメイン名(例: blog.example.com)
        "resource_record_name": "_lmnop1234567890.blog.example.com",  // このドメインの検証用CNAMEレコード名
        "resource_record_type": "CNAME",  // DNSレコードタイプ(通常は "CNAME")
        "resource_record_value": "_rst9876543210.acm-validations.aws"  // 検証用のCNAMEレコード値
    }
]
補足:route53.tf例
# Route 53ゾーンの設定(すでに存在しているゾーンを使用)
resource "aws_route53_zone" "example_zone" {
  name = "example.com"
}

# api.example.com 用のAレコード
resource "aws_route53_record" "api_subdomain" {
  zone_id = aws_route53_zone.example_zone.zone_id
  name    = "api.example.com"  # サブドメイン名
  type    = "A"                # Aレコード
  ttl     = 300                # TTL (秒)
  records = ["192.0.2.1"]      # ここに実際のIPアドレスを指定
}

# www.example.com 用のAレコード
resource "aws_route53_record" "www_subdomain" {
  zone_id = aws_route53_zone.example_zone.zone_id
  name    = "www.example.com"  # サブドメイン名
  type    = "A"                # Aレコード
  ttl     = 300                # TTL (秒)
  records = ["192.0.2.2"]      # ここに実際のIPアドレスを指定
}

# blog.example.com 用のCNAMEレコード
resource "aws_route53_record" "blog_subdomain" {
  zone_id = aws_route53_zone.example_zone.zone_id
  name    = "blog.example.com"  # サブドメイン名
  type    = "CNAME"             # CNAMEレコード
  ttl     = 300                 # TTL (秒)
  records = ["blog-content.example.com"]  # ここにリダイレクト先を指定
}

2. 上記のdomain_validation_optionsを使って、対象のゾーンにCNAMEレコードを追加
  (ワイルドカード証明書にしたいので、各サブドメインの情報を拾っています。)

for_eachを使ってdomain_validation_optionsの各バリューを用いマップを作成

resource "aws_route53_record" "route53_acm_dns_resolve" {
  for_each = {
    for dvo in aws_acm_certificate.example_cert.domain_validation_options : 
      dvo.domain_name => {
        name   = dvo.resource_record_name  # レコード名
        type   = dvo.resource_record_type  # レコードタイプ(通常はCNAME)
        record = dvo.resource_record_value  # レコード値
      }
  }
  <<省略>>
for_each を使って作成されるマップ例
{
  "api.example.com": {
    "name": "_abcdef1234567890.api.example.com",
    "type": "CNAME",
    "record": "_xyz9876543210.acm-validations.aws"
  },
  "www.example.com": {
    "name": "_ghijk1234567890.www.example.com",
    "type": "CNAME",
    "record": "_uvw9876543210.acm-validations.aws"
  },
  "blog.example.com": {
    "name": "_lmnop1234567890.blog.example.com",
    "type": "CNAME",
    "record": "_rst9876543210.acm-validations.aws"
  }
}


3. each.value.を用いfor_eachで代入した各属性値を取得し各レコードを作成

  <<省略>>
  allow_overwrite = true  # 既存のレコードを上書きする設定
  zone_id         = aws_route53_zone.example_zone.zone_id  # Route53ゾーンのID
  name            = each.value.name  # レコード名
  type            = each.value.type  # レコードタイプ
  ttl             = 600  # TTL(キャッシュの有効時間)
  records         = [each.value.record]  # 証明書の認証用レコード値
}



まとめ

簡単にフローをまとめ

・キーペア作成
・CSR作成
・作成したCSRを認証局(CA)に送信
・DNS認証(ドメイン所有者確認)
  ・ドメイン所有者確認用に、CNAMEレコードを作成
  ・上記CNAMEレコードを使ってドメイン所有者を確認
・証明書発行

今回のacm.tfの記述で上記まで実装できます。

こちらの記事もどうぞ。


めも

ACMで利用される認証局(CA)
  • ACMは主にAmazon Trust Services(ATS)を利用して証明書を発行
  • 特定のユースケースや互換性の理由で、ACMはDigiCertとも提携している


参考サイト:

ACMの機能や利用方法、証明書の管理に関する詳細が記載されています。


ACMの概要、利点、ユースケースなど、サービス全般に関する情報が記載されています。