非常に基本的なことですが、3年前くらいにはまったのでメモしておきます
Route53 はドメインの取得や DNS の設定をするサービスで、 ACM は SSL 証明書を取得するサービスです。 ACM と Route53 は連携しており、例えば Route53 に登録したドメインの SSL 証明書を ACM で取得しようとすると、 Route53 に CNAME レコードを作成しますか?みたいなボタンが出てきて、それを押すと簡単に取得できます。多分内部的に Let's Encrypt の DNS チャレンジみたいなことが行われてるんだと思います。
Route53 はグローバルに適用されるサービスですが、 ACM はリージョン別にあります。ここで東京リージョンなどで取得してしまうと、確か CloudFront に設定できなかったり、ワイルドカードドメインが取得できなかったりして詰みます。まあ詰むといっても、 US East 1 で取り直せばよいのですが、東京リージョンの証明書が残ってしまうと、後々これって使ってるんだっけ?みたいなことになったりして厄介なので、東京リージョンで作ってしまった場合は消しましょう。
US East 1 以外で ACM を作るメリットがあるんだと思いますが、いまいち思いつかないです。
Terraform でリージョン跨ぐと面倒じゃない?と思ったかもしれませんが、 ACM を手動で取得して acm_certificate_arn
に設定することができます。
以下は CloudFront + S3 で静的サイトを作る例。
resource "aws_cloudfront_distribution" "main" {
origin {
domain_name = aws_s3_bucket.main.website_endpoint
origin_id = aws_s3_bucket.main.id
custom_origin_config {
http_port = "80"
https_port = "443"
origin_protocol_policy = "http-only"
origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"]
}
}
wait_for_deployment = false
retain_on_delete = true
enabled = true
is_ipv6_enabled = true
aliases = ["www.example.com"]
restrictions {
geo_restriction {
restriction_type = "none"
}
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
target_origin_id = aws_s3_bucket.main.id
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
forwarded_values {
query_string = true
cookies {
forward = "none"
}
}
}
viewer_certificate {
# ここで別リージョンの ACM も普通に使える
#(適当なUUIDです)
acm_certificate_arn = "arn:aws:acm:us-east-1:881756217246:certificate/fed902fa-b1d5-45a4-8a40-d949e5b9e764"
ssl_support_method = "sni-only"
}
}
ACM を Terraform でやって、証明書まで全部自動化したぜ!みたいなことやってた時期もあったんですが、なんか途中で Terraform が止まったりして安定しなかったのと、リージョン切り替えたりする設定を書くのが面倒なので、 ACM は手動で取るのが落とし所かなと思いました。一回取得すれば、あんまり増えたり減ったりしない箇所かなと思うので、そこまで Infrastructure as Code に拘らなくても良いかなと。どっちみちドメイン取ったり、 DNS を AWS に向けるのとかは手動でやらないといけないし、
おまけ: Cloudflare だと簡単だが...
Cloudflare はデフォルトで証明書を設定してくれるので、この辺をすごくすっきり Terraform で書けて良さそうに思えます。が、 Cloudflare は無料版は WebSocket が100秒で切れるという欠点があるので、 WebSocket がビジネス要件に入ってくる可能性が少しでもあるなら Route53 + (CloudFront | ELB) にしといた方が安心かなと思います。ちゃんと測定したわけじゃないけど、 S3 + Cloudflare より S3 + CloudFront の方が Brotli 圧縮を加味しても体感速い気がします。あとなんか Cloudflare たまに止まったりするような。これは自分が使い方間違ってるだけかもですが。
追記: CloudFront も2024年現在は Brotli 圧縮に対応しています。