Terraform で CloudFront のテンプレートをモジュール化したいとき、ACMつけるときと付けない時の viewer_certificate{} の中身を変えないといけないので、モジュール化できなくて枕を濡らしたことはありませんか?
ACM無し
viewer_certificate{
cloudfront_default_certificate = true
}
ACM有り
viewer_certificate{
acm_certificate_arn = aws_acm_certificate.cert.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
cloudfront_default_certificate = false
}
そんな時は dynamic ブロックを使えばいいんです。
dynamic ブロックは、配列の中身の分だけ動的に設定してくれるので default_cert を使う場合と、ACM を使う場合用の dynamic ブロックを用意しておく感じです。
こんな感じ
variables "acm_arn" { default = "" }
variables "aliases" {
type = list
default = []
}
locals {
aliases = var.acm_arn == "" ? [] : var.aliases
use_default_cert = var.acm_arn == "" ? [true] : []
use_custom_cert = var.acm_arn == "" ? [] : [var.acm_arn]
}
resource "aws_cloudfront_distribution" "site" {
enabled = true
aliases = local.aliases
price_class = "PriceClass_All"
http_version = "http2and3"
# CloudFront のデフォルト証明書を使用する場合
dynamic "viewer_certificate" {
for_each = local.use_default_cert
content {
cloudfront_default_certificate = viewer_certificate.value
}
}
# ACM を使用する場合
dynamic "viewer_certificate" {
for_each = local.use_custom_cert
content {
acm_certificate_arn = viewer_certificate.value
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2022"
cloudfront_default_certificate = false
}
}
# :
}
var.acm_arn に何もセットされていない場合、以下のようになります。
-
local.use_default_cert→[ true ] -
local.use_custom_cert→[]
なので、1つ目の dynamic "viewer_certificate" {} ブロックしか実行されません。
var.acm_arn に何かがセットされている場合、以下のようになります。
-
local.use_default_cert→[] -
local.use_custom_cert→[var.acm_arn]
なので、2つ目の dynamic "viewer_certificate" {} ブロックしか実行されません。
これで、モジュール化しても安心ですね。