目次
前回の振り返り
セキュリティグループのリソース定義を作成
- 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を作成していきます。
