この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは!コンサル部の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マネージメントコンソールのポチポチから卒業していきたいと思います。
この記事が、どなたかのお役に立てば幸いです。それでは!