はじめに
- (Terraformに慣れるために)AWS CLIで構築したスケーラブルなウェブサイト環境を手順と資料を合わせてアウトプット資料としてまとめます。
- 個人的に気づいたことも付け加えていこうと思います。
構成図
手順
main.tf
# ---------------------------
# プロバイダ設定
# ---------------------------
# AWS
provider "aws" {
region = "ap-northeast-1"
}
# 自分のパブリックIPを取得する
provider "http" {}
VPCの作成
vpc.tf
#---
#VPCの作成
#---
resource "aws_vpc" "test" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = "true"
tags = {
Name = "test"
}
}
#---
#サブネットの作成
#---
resource "aws_subnet" "test-public-1a" {
vpc_id = aws_vpc.test.id
cidr_block = "10.0.0.0/24"
availability_zone = "${var.az_a}"
tags = {
Name = "test-public-1"
}
}
resource "aws_subnet" "test-public-1c" {
vpc_id = aws_vpc.test.id
cidr_block = "10.0.1.0/24"
availability_zone = "${var.az_c}"
tags = {
Name = "test-public-2"
}
}
resource "aws_subnet" "test-private-1a" {
vpc_id = aws_vpc.test.id
cidr_block = "10.0.2.0/24"
availability_zone = "${var.az_a}"
tags = {
Name = "test-private-1"
}
}
resource "aws_subnet" "test-private-1c" {
vpc_id = aws_vpc.test.id
cidr_block = "10.0.3.0/24"
availability_zone = "${var.az_c}"
tags = {
Name = "test-private-2"
}
}
#---
#IGWの作成
#---
resource "aws_internet_gateway" "test-igw" {
vpc_id = aws_vpc.test.id
tags = {
Name = "test-igw"
}
}
#---
#ルートテーブルの作成
#---
resource "aws_route_table" "test-public" {
vpc_id = aws_vpc.test.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.test-igw.id
}
tags = {
Name = "test-public"
}
}
#---
#ルートテーブルの関連付け
#---
resource "aws_route_table_association" "test-public-1a" {
subnet_id = aws_subnet.test-public-1a.id
route_table_id = aws_route_table.test-public.id
}
resource "aws_route_table_association" "test-public-1c" {
subnet_id = aws_subnet.test-public-1c.id
route_table_id = aws_route_table.test-public.id
}
#---
#セキュリティグループの作成
#---
#EC2
resource "aws_security_group" "test-web" {
name = "test-web"
description = "test-web sg"
vpc_id = aws_vpc.test.id
ingress {
description = "ssh"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "http"
from_port = 80
to_port = 80
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 = "test-web"
}
}
#RDS
resource "aws_security_group" "test-rds" {
name = "test-rds"
description = "test-rds-sg"
vpc_id = aws_vpc.test.id
ingress {
from_port = 3306
to_port = 3306
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 = "test-rds"
}
}
#ELB
resource "aws_security_group" "test-elb" {
name = "test-elb"
description = "test-elb-sg"
vpc_id = aws_vpc.test.id
ingress {
from_port = 80
to_port = 80
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 = "test-elb"
}
}
EC2の作成
ec2.tf
# Amazon Linux 2 の最新AMIを取得する
data "aws_ssm_parameter" "amzn2_latest_ami" {
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}
#キーペアの作成
variable "key_name" {
default = "test-keypair"
}
# 秘密鍵のアルゴリズム設定
resource "tls_private_key" "private_key" {
algorithm = "RSA"
rsa_bits = 2048
}
# PCにキーペアを作成
locals {
public_key_file = "C:\\terraform_handson\\${var.key_name}.id_rsa.pub"
private_key_file = "C:\\terraform_handson\\${var.key_name}.id_rsa"
}
resource "local_file" "private_key_pem" {
filename = "${local.private_key_file}"
content = "${tls_private_key.private_key.private_key_pem}"
}
# 上記で作成した公開鍵をAWSのKey pairにインポート
resource "aws_key_pair" "keypair" {
key_name = "${var.key_name}"
public_key = "${tls_private_key.private_key.public_key_openssh}"
}
#EC2の作成
resource "aws_instance" "test-ec2" {
ami = data.aws_ssm_parameter.amzn2_latest_ami.value
instance_type = "t2.micro"
availability_zone = "${var.az_a}"
vpc_security_group_ids = [aws_security_group.test-web.id]
subnet_id = aws_subnet.test-public-1a.id
associate_public_ip_address = "true"
key_name = "${var.key_name}"
user_data = file("userdata.sh")
tags = {
Name = "test-web-instance-1a"
}
}
RDSの作成
rds.tf
#---
#RDSサブネットグループの作成
#---
resource "aws_db_subnet_group" "test-db-subnet" {
name = "test-db-subnet"
subnet_ids = [aws_subnet.test-private-1a.id, aws_subnet.test-private-1c.id]
tags = {
Name = "test-db-subnet"
}
}
#---
#インスタンスの作成
#---
resource "aws_db_instance" "test-db" {
allocated_storage = 20
db_name = "test-db"
engine = "mysql"
engine_version = "8.0.28"
instance_class = "db.t3.micro"
username = "test"
password = "password"
backup_retention_period = 0
db_subnet_group_name = "test-db-subnet"
skip_final_snapshot = true
multi_az = true
tags = {
Name = "test-rds"
}
}
ELBの作成
elb.tf
#---
#ALBの作成
#---
resource "aws_lb" "test" {
name = "test-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.lb_sg.id]
subnets = [aws_subnet.test-public-1a.id,aws_subnet.test-public-1c.id]
ip_address_type = "ipv4"
enable_deletion_protection = true
tags = {
name = "test-alb"
}
}
#---
#ターゲットグループの作成
#---
resource "aws_lb_target_group" "test-target" {
name = "test-target"
target_type = "instance"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.test.id
tags = {
name = "test-elb"
}
health_check {
protocol = "HTTP"
path = "/"
}
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
#ターゲットグループにインスタンスを登録
"##1台目
resource "aws_lb_target_group_attachment" "test-target-1" {
target_group_arn = aws_lb_target_group.test-target.arn
target_id = aws_instance.test.id
port = 80
}
##2台目
resource "aws_lb_target_group_attachment" "test-target-2" {
target_group_arn = aws_lb_target_group.test-target.arn
target_id = aws_instance.test.id
port = 80
}
#---
#リスナー設定
#---
resource "aws_lb_listener" "test-listnet" {
load_balancer_arn = aws_lb.test.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.test-target.arn
}
}
AMIの作成
ami.tf
#---
#AMIの作成
#---
resource "aws_ami_from_instance" "test-ami" {
name = "test-ec2-ami"
source_instance_id = "i-xxxxxxxx"
}
作成したAMIをもとに、EC2を作成します。
Terraformレジストリ
VPC
- aws_vpc
- aws_subnet
- aws_internet_gateway
- aws_route_table
- aws_route_table_association
- aws_security_group
- aws_key_pair
- aws_instance
RDS
ELB
AMI
補足
複数台のEC2を構築したいとき、異なるAZ間に配置したいときの