【小ネタ】TerraformでACM証明書作成してALBに関連付ける
こんにちは!コンサル部のinomaso(@inomasosan)です。
最近はAWSでWebサイトを構築する際、SSLサーバ証明書をACMの無料証明書(DV証明書)にて対応することが多かったです。
そこでサクッと構築できるように、Terraformでコード化を検証してみました。
この記事で学べること
- ACM証明書やALBの作成方法
- Terraformでのコードの書き方
環境
今回実行した環境は以下の通りです。
- macOS Catalina 10.15.7
- Terraform 0.14.8
- AWSプロバイダー 3.34.0
前提
Route53でドメイン登録等を実施し、ホストゾーン作成まで完了していること。
コード
1. ACM関連
ACMで無料証明書を作成し、Route53にACMのドメイン検証用レコードを追加します。
Route53のホストゾーンIDは手動入力しているので、ご自分の環境で試される際は、AWSマネージメントコンソール等からご確認願います。
resource "aws_acm_certificate" "cert" { # ワイルドカード証明書で同じドメイン内の複数のサイトを保護 domain_name = "*.inomaso.classmethod.info" # ネイキッドドメインや apex ドメイン(ドメイン名そのもの)を保護 subject_alternative_names = ["inomaso.classmethod.info"] # ACMドメイン検証方法にDNS検証を指定 validation_method = "DNS" lifecycle { create_before_destroy = true } tags = { Name = "inomaso-dev-acm" } } resource "aws_route53_record" "cert_validation" { 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 } } allow_overwrite = true name = each.value.name records = [each.value.record] type = each.value.type ttl = "300" # レコードを追加するドメインのホストゾーンIDを指定 zone_id = "Z123456789ABCDEFG" }
2. ALB関連
ALBを作成し、ACM証明書をHTTPSリスナーに関連付けます。
resource "aws_lb" "alb" { name = "inomaso-dev-alb" load_balancer_type = "application" internal = false idle_timeout = 60 security_groups = [ aws_security_group.alb.id ] subnets = [ aws_subnet.sub_front_1a.id, aws_subnet.sub_front_1c.id ] } resource "aws_alb_listener" "alb_https" { load_balancer_arn = aws_lb.alb.arn port = "443" protocol = "HTTPS" ssl_policy = "ELBSecurityPolicy-2016-08" # ACM証明書をHTTPSリスナーに関連づけ certificate_arn = aws_acm_certificate.cert.arn default_action { target_group_arn = aws_lb_target_group.ec2_http.arn type = "forward" } } resource "aws_lb_target_group" "ec2_http" { name = "inomaso-dev-alb-tg" port = 80 protocol = "HTTP" vpc_id = aws_vpc.vpc.id health_check { interval = 10 path = "/" port = "traffic-port" protocol = "HTTP" timeout = 5 healthy_threshold = 2 unhealthy_threshold = 2 } } resource "aws_lb_target_group_attachment" "ec2" { target_group_arn = aws_lb_target_group.ec2_http.arn target_id = aws_instance.ec2.id port = 80 }
ハマったこと
Route53にACMのドメイン検証用レコード追加は、最初以下のようなコードにしていましたが
This value does not have any indices.というエラーが発生しました。
resource "aws_route53_record" "acm" { zone_id = "Z123456789ABCDEFG" name = aws_acm_certificate.acm.domain_validation_options[0].resource_record_name type = aws_acm_certificate.acm.domain_validation_options[0].resource_record_type records = [aws_acm_certificate.acm.domain_validation_options[0].resource_record_value] ttl = "300" }
調べてみたところ、AWS Provider 3.0.0 以降から仕様変更されており、listタイプではダメなことがわかりました。
下記ブログにある通り、今回はsetタイプにコードを修正しております。
set は list とは異なり順序付けされません。よって、以前のようなカウントインデックスは割り当てられず Error: Invalid index となるわけです。
結果確認
まずはACMから確認していきます。
証明書の状況は発行済で、ドメイン検証状態も成功しております。
また更新資格も使用可能のため、証明書の自動更新にも対応済です。
次にALBを確認していきます。
HTTPSリスナールールにSSL証明書が関連付けられていますね。
まとめ
ACM証明書作成からALBへの関連づけまでをコードで対応できるようになったので、構築時には楽できるようになりました。
ちょっとずつ、AWSマネージメントコンソールのポチポチから卒業していきたいと思います。
この記事が、どなたかのお役に立てば幸いです。それでは!