はじめに
普段、EC2インスタンスやApplication Load Balancer (ALB) の検証環境を手軽に作成したいときには、Terraformを利用しています。
簡易的に使用する目的で活用していますが、改めて自分への備忘録として整理していきます。
この記事では、過去の記事で手動で構築した環境を、そのままコード化する方法を紹介します。
前回の記事の復習
前回の記事では、EC2インスタンスの起動からApplication Load Balancer (ALB) の設定、動作確認までの手順を説明しました。
今回は、その内容を踏まえて、以下の構成をインフラコードとして定義していきます。
引用画像:https://canmakewakuwaku.com/elb_alb/
実際に完成したコード
以下は、Terraformで作成したコードです。長くなっていますが、内容としてはそれほど難しくないシンプルな構成となっています。
provider "aws" {
region = "ap-northeast-1" # 東京リージョンを指定
}
# VPC作成 (仮想プライベートクラウド)
resource "aws_vpc" "main_vpc" {
cidr_block = "10.0.0.0/16" # VPCのCIDRブロック
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "terraform-main-vpc"
}
}
# パブリックサブネット1作成
resource "aws_subnet" "public_subnet_1" {
vpc_id = aws_vpc.main_vpc.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
tags = {
Name = "terraform-public-subnet-1"
}
}
# パブリックサブネット2作成
resource "aws_subnet" "public_subnet_2" {
vpc_id = aws_vpc.main_vpc.id
cidr_block = "10.0.2.0/24"
map_public_ip_on_launch = true
tags = {
Name = "terraform-public-subnet-2"
}
}
# インターネットゲートウェイ作成
resource "aws_internet_gateway" "main_igw" {
vpc_id = aws_vpc.main_vpc.id
tags = {
Name = "terraform-main-igw"
}
}
# ルートテーブル作成 (パブリックルート)
resource "aws_route_table" "public_route_table" {
vpc_id = aws_vpc.main_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main_igw.id
}
tags = {
Name = "terraform-public-route-table"
}
}
# サブネット1とルートテーブルを関連付ける
resource "aws_route_table_association" "public_association_1" {
subnet_id = aws_subnet.public_subnet_1.id
route_table_id = aws_route_table.public_route_table.id
}
# サブネット2とルートテーブルを関連付ける
resource "aws_route_table_association" "public_association_2" {
subnet_id = aws_subnet.public_subnet_2.id
route_table_id = aws_route_table.public_route_table.id
}
# セキュリティグループ作成 (HTTPおよびSSHアクセスを許可)
resource "aws_security_group" "public_sg" {
vpc_id = aws_vpc.main_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "terraform-public-sg"
}
}
# EC2インスタンス1作成 (Aサイト)
resource "aws_instance" "apache_ec2_1" {
ami = "ami-0b6fe957a0eb4c1b9"
instance_type = "t2.micro"
subnet_id = aws_subnet.public_subnet_1.id
security_groups = [aws_security_group.public_sg.id]
associate_public_ip_address = true
user_data = <<-EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<html><body><h1>自分に負けるな〜(Aサイト)</h1></body></html>" > /var/www/html/index.html
EOF
depends_on = [aws_security_group.public_sg]
tags = {
Name = "terraform-apache-ec2-1"
}
}
# EC2インスタンス2作成 (Bサイト)
resource "aws_instance" "apache_ec2_2" {
ami = "ami-0b6fe957a0eb4c1b9"
instance_type = "t2.micro"
subnet_id = aws_subnet.public_subnet_2.id
security_groups = [aws_security_group.public_sg.id]
associate_public_ip_address = true
user_data = <<-EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<html><body><h1>自分に負けるな〜(Bサイト)</h1></body></html>" > /var/www/html/index.html
EOF
depends_on = [aws_security_group.public_sg]
tags = {
Name = "terraform-apache-ec2-2"
}
}
# アプリケーションロードバランサー(ALB)作成
resource "aws_lb" "main_alb" {
name = "terraform-main-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.public_sg.id]
subnets = [aws_subnet.public_subnet_1.id, aws_subnet.public_subnet_2.id]
enable_deletion_protection = false
tags = {
Name = "terraform-main-alb"
}
}
# ターゲットグループ作成 (EC2インスタンスをターゲットに)
resource "aws_lb_target_group" "main_target_group" {
name = "terraform-main-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main_vpc.id
health_check {
interval = 30
path = "/"
protocol = "HTTP"
timeout = 5
healthy_threshold = 3
unhealthy_threshold = 3
}
tags = {
Name = "terraform-main-target-group"
}
}
# ALBのリスナー作成 (HTTPリスナー)
resource "aws_lb_listener" "http_listener" {
load_balancer_arn = aws_lb.main_alb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.main_target_group.arn
}
}
# EC2インスタンス1をターゲットグループに追加
resource "aws_lb_target_group_attachment" "ec2_attachment_1" {
target_group_arn = aws_lb_target_group.main_target_group.arn
target_id = aws_instance.apache_ec2_1.id
port = 80
}
# EC2インスタンス2をターゲットグループに追加
resource "aws_lb_target_group_attachment" "ec2_attachment_2" {
target_group_arn = aws_lb_target_group.main_target_group.arn
target_id = aws_instance.apache_ec2_2.id
port = 80
}
実際にやってみた
ここでは、CloudShellでの Terraform のセットアップが完了していることを前提に進めます。
まだセットアップが完了していない方は、過去の記事を参考にしてセットアップを実施してください。
まず、以下のコマンドを入力して、main.tfというファイルを作成します。
vi main.tf
vi
では、ファイル編集後にESCキーを押し、:wq
で保存して終了します。
# 上記の完成した全体のコードをコピーして貼り付けてください。
次に、以下のコマンドで Terraform を初期化します。
terraform init
実際に、以下のように「Terraform has been successfully initialized!
」と表示され、成功が確認できました。
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
次に、以下のコマンドを入力して、確認メッセージが表示されたら「yes
」と入力します。
terraform apply
その後、以下のように「Apply complete! Resources: xx added, 0 changed, 0 destroyed.
」と表示され、作成が成功したことが確認できました。
デプロイ後の動作確認
ALBの詳細画面からDNS名を取得し、ブラウザでアクセスして、2台のApacheサーバーが正常に応答しているか確認します。
私の環境では、以下がロードバランサーのDNS名ですので、ブラウザで確認してみます。
http://terraform-main-alb-421986447.ap-northeast-1.elb.amazonaws.com/
何度かアクセスして「自分に負けるな〜(xxサイト)
」と表示される「A
」「B
」が切り替われば、動作確認は成功です。
まとめ
この記事では、手動で構築したインフラ環境をTerraformを使ってコード化する手順を紹介しました。
VPC、サブネット、インターネットゲートウェイ、セキュリティグループ、EC2インスタンス、ロードバランサー(ALB)、ターゲットグループ、リスナー、そしてターゲットグループへのEC2インスタンス追加までの流れをまとめました。
この記事が、誰かの技術の支えになれば嬉しいです!
関連記事
Terraformについての記事はいくつか投稿しているので興味のあるものがあれば、読んでみてください!