目次
前回の振り返り
セキュリティグループのリソース定義を作成
- securitygroup.tf
IAM関連のリソース定義を作成
- iam.tf
Route 53のリソース定義を作成
- route53.tf
Certificate Manager(ACM)の定義を作成
- acm.tf
次回予告
前回の振り返り
前回はTerraformでVPCリソースの定義まで書きました。
今回はセキュリティグループ、IAM、Route 53、Certificate Managerリソースの定義を作成していきます。
terraform/ ├─vars/ │ └─terraform.tfvars ├─acm.tf ... ★今回★ ├─ec2.tf ├─elb.tf ├─iam.tf ... ★今回★ ├─provider.tf ... 第1回で作成済 ├─route53.tf ... ★今回★ ├─securitygroup.tf ... ★今回★ ├─terraform.tf ... 第1回で作成済 ├─variables.tf ... 第1回で作成済 └─vpc.tf ... 第1回で作成済
セキュリティグループのリソース定義を作成
セキュリティグループは2つ作成します。
- ALB用のセキュリティグループ
- 今回は検証のためHTTPS、HTTPを自分のIPアドレスからのみアクセスできるように許可します。
- EC2(Webサーバー)用のセキュリティグループ
- ALBからの80番ポートへの受信を許可します。
securitygroup.tf
data http ifconfig { url = "https://ifconfig.co/ip" } locals { myip = chomp(data.http.ifconfig.body) } # Internal ALB Security Group resource "aws_security_group" "alb_sg" { name = "${var.name_prefix}-alb-sg" vpc_id = aws_vpc.vpc.id /* In-Bound */ ingress = [ { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["${local.myip}/32"] description = "http allow" ipv6_cidr_blocks = [] prefix_list_ids = [] security_groups = [] self = false }, { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["${local.myip}/32"] description = "https allow" ipv6_cidr_blocks = [] prefix_list_ids = [] security_groups = [] self = false } ] /* Out-Bound */ egress = [ { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] description = "egress allow" ipv6_cidr_blocks = [] prefix_list_ids = [] security_groups = [] self = false } ] tags = { Name = "${var.name_prefix}-alb-sg" } } # EC2 Web Server Security Group resource "aws_security_group" "web_sg" { name = "${var.name_prefix}-web-server-sg" vpc_id = aws_vpc.vpc.id /* In-Bound */ ingress = [ { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = [] description = "http allow from alb" ipv6_cidr_blocks = [] prefix_list_ids = [] security_groups = [aws_security_group.alb_sg.id] self = false } ] /* Out-Bound */ egress = [ { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] description = "egress allow" ipv6_cidr_blocks = [] prefix_list_ids = [] security_groups = [] self = false } ] tags = { Name = "${var.name_prefix}-web-server-sg" } }
※ 作成したリソースは後ほど、ALBとEC2のリソースから参照します。Webサイトを全公開する場合は[“${local.myip}/32”]の部分を[“0.0.0.0/0”]に変更します。
IAM関連のリソース定義を作成
EC2にIAMロールをアタッチするための定義を作成していきます。
- EC2用のロール
⇒ SSMのセッションマネージャーが使用できるように「AmazonSSMManagedInstanceCore」AWS管理ポリシーをアタッチ
⇒ Cloud Watch Agentを導入する想定をして「CloudWatchAgentServerPolicy」をアタッチ - インスタンスプロファイル
- ポリシー
⇒ ssm:StartSessionアクションを許可 - ポリシーをロールにアタッチする定義
⇒ 作成したカスタマー管理ポリシーをEC2用のロールにアタッチする定義を書きます。
iam.tf
# ------------------------------------------------------ # # IAM # ------------------------------------------------------ # # EC2 Instance Attach Role resource "aws_iam_role" "ec2_role" { name = "${var.name_prefix}-ec2-role" assume_role_policy = jsonencode({ "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Allow", "Principal" : { "Service" : "ec2.amazonaws.com" }, "Action" : "sts:AssumeRole" } ] }) managed_policy_arns = [ "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore", "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" ] tags = { Name = "${var.name_prefix}-ec2-role" } } # Instance Profile resource "aws_iam_instance_profile" "ec2_profile" { name = "${var.name_prefix}-ec2-profile" role = aws_iam_role.ec2_role.name tags = { Name = "${var.name_prefix}-ec2-profile" } } # IAM Policy resource "aws_iam_policy" "start_session" { depends_on = [aws_instance.web] name = "${var.name_prefix}-start-session-policy" description = "session manager start session" policy = jsonencode({ "Version" : "2012-10-17", "Statement" : [ { "Effect" : "Allow", "Action" : "ssm:StartSession", "Resource" : [ "arn:aws:ec2:*:*:instance/${aws_instance.web.id}", "arn:aws:ssm:*:*:document/AWS-StartSSHSession" ] } ] }) tags = { Name = "${var.name_prefix}-start-session-policy" } } resource "aws_iam_policy_attachment" "ec2_role" { depends_on = [aws_iam_policy.start_session] name = "ec2-role-attachment" roles = [aws_iam_role.ec2_role.name] policy_arn = aws_iam_policy.start_session.arn }
※ SSMスタートセッション用のポリシーにインスタンスIDを変数として使用するため、「aws_iam_role」の「managed_policy_arns」には書かず、あえて「aws_iam_policy_attachment」リソースを別途定義しています。こうすることでapply実行時にEC2リソース作成後にこのポリシーを作成しアタッチしてくれるようになります。(下記参照)
- IAMロールを作成
- EC2を作成、作成したIAMロールをEC2にアタッチ
- ポリシーを作成
⇒ EC2が作成されないと52行目のインスタンスIDが分からないため、このタイミングで作成されないといけない。「aws_iam_role」の「managed_policy_arns」でアタッチすることを書いてしまうとEC2が作成される前にこのポリシーを作成しようとしてエラーが発生する。 - ポリシーをIAMロールにアタッチ
Route 53のリソース定義を作成
Webサーバーを公開するにはDNSの設定が必要です。Route53でゾーンを作成し、レコードを追加します。
route53.tf
# Public DNS Zone resource "aws_route53_zone" "public" { name = var.dns_zone } # DNS Record resource "aws_route53_record" "www" { zone_id = aws_route53_zone.public.zone_id name = "www.${var.dns_zone}" type = "CNAME" ttl = "300" records = [ "${aws_lb.alb.dns_name}" ] }
Certificate Manager(ACM)の定義を作成
昨今では、SSL/TLSによる暗号化が必須ですので、ACMで証明書を発行します。DNS検証によるドメイン所有者の確認もここでレコード追加が可能です。公式のドキュメントを参考に記載をします。
acm.tf
resource "aws_acm_certificate" "cert" { domain_name = "www.${var.dns_zone}" validation_method = "DNS" lifecycle { create_before_destroy = true } tags = { Name = "${var.name_prefix}-acm" } } resource "aws_route53_record" "cert_validation" { for_each = { for x in aws_acm_certificate.cert.domain_validation_options : x.domain_name => { name = x.resource_record_name record = x.resource_record_value type = x.resource_record_type } } allow_overwrite = true name = each.value.name records = [each.value.record] type = each.value.type ttl = "300" zone_id = aws_route53_zone.public.id }
次回予告
今回はSSL/TLS証明書が実用的に利用できるよう考慮もしました。次回はいよいよ大詰めでELB、EC2を作成していきます。