Skip to content

TerraformでAWS Certificate Managerに証明書を作成する方法

証明書を発行して利用可能にするためには、多くのリソースが必要になる。

ドメインを指定してACMで証明書を発行する。ドメイン名には * も利用できる。はてな社内の事情だけど、グローバルなリソースのCloudFrontに割り当てる証明書は us-east-1 で発行することになっているらしいので provider を指定している。

Terminal window
resource "aws_acm_certificate" "cloudfront" {
provider = aws.us-east-1
domain_name = "*.cloudfront.example.com"
validation_method = "DNS"
options {
certificate_transparency_logging_preference = "ENABLED"
}
lifecycle {
create_before_destroy = true
}
}

ここで validation_methodDNS を設定しているので、検証用のレコードをRoute 53に登録する。Route 53はグローバルリソースなので provider の指定は不要となる。

Terminal window
resource "aws_route53_record" "validation" {
for_each = {
for dvo in aws_acm_certificate.cloudfront.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}
allow_overwrite = false
name = each.value.name
records = [each.value.record]
ttl = 300
type = each.value.type
zone_id = aws_route53_zone.testdevhost.zone_id
depends_on = [aws_acm_certificate.cloudfront]
}

最後に検証完了を待つ。

Terminal window
resource "aws_acm_certificate_validation" "cloudfront" {
provider = aws.us-east-1
certificate_arn = aws_acm_certificate.cloudfront.arn
validation_record_fqdns = [for record in aws_route53_record.validation : record.fqdn]
}

証明書を検証するとき、委任しておかないと「保留中の検証(Pending validation)」状態でタイムアウトしてしまう。そのため親となるドメインにNSレコードを追加する。

Terminal window
resource "aws_route53_delegation_set" "cloudfront" {}
resource "aws_route53_zone" "cloudfront" {
name = "cloudfront.example.com"
delegation_set_id = aws_route53_delegation_set.cloudfront.id
}
data "aws_route53_zone" "example_com" {
name = "example.com."
}
resource "aws_route53_record" "delegation" {
zone_id = data.aws_route53_zone.example_com.zone_id
name = "cloudfront.example.com"
ttl = 300
type = "NS"
records = aws_route53_zone.cloudfront.name_servers
}

あとは名前解決するためのレコードを作れば良い。

Terminal window
resource "aws_route53_record" "cloudfront_example_com" {
zone_id = aws_route53_zone.cloudfront.zone_id
name = "*.cloudfront.example.com"
type = "A"
alias {
name = aws_cloudfront_distribution.devhost.domain_name
zone_id = aws_cloudfront_distribution.devhost.hosted_zone_id
evaluate_target_health = false
}
}

上記の例では、aws_cloudfront_distribution.devhost.domain_name にはCloudFrontを作成したときのデフォルト名が入っている。