3-Tier Architecture

+---GOORM_ASSIGN
| app-alb-asg.tf
| main.tf
| network.tf
| rds.tf
| web-alb-asg.tf
main.tf
# Use AWS Provider
provider "aws" {
region = "ap-northeast-2"
}
network.tf
############# VPC ###############
# VPC resource
resource "aws_vpc" "goorm_vpc" {
cidr_block = "172.16.0.0/16"
tags = {
Name = "goorm_vpc"
}
}
# Subnet-a resource
resource "aws_subnet" "goorm_subnet_a" {
vpc_id = aws_vpc.goorm_vpc.id
cidr_block = "172.16.0.0/24"
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = true
tags = {
Name = "goorm_subnet_a"
}
}
# Subnet-c resource
resource "aws_subnet" "goorm_subnet_c" {
vpc_id = aws_vpc.goorm_vpc.id
cidr_block = "172.16.10.0/24"
availability_zone = "ap-northeast-2c"
map_public_ip_on_launch = true
tags = {
Name = "goorm_subnet_c"
}
}
# Private-Subnet-a resource
resource "aws_subnet" "goorm_private_subnet_a" {
vpc_id = aws_vpc.goorm_vpc.id
cidr_block = "172.16.20.0/24"
availability_zone = "ap-northeast-2a"
map_public_ip_on_launch = true
tags = {
Name = "goorm_private_subnet_a"
}
}
# Private-Subnet-c resource
resource "aws_subnet" "goorm_private_subnet_c" {
vpc_id = aws_vpc.goorm_vpc.id
cidr_block = "172.16.30.0/24"
availability_zone = "ap-northeast-2c"
map_public_ip_on_launch = true
tags = {
Name = "goorm_private_subnet_c"
}
}
############ DB Subnet GRP ##############
resource "aws_db_subnet_group" "goorm_private_db_subnet_grp" {
name = "goorm_private_db_subnet_grp"
subnet_ids = [
aws_subnet.goorm_private_db_subnet_a.id,
aws_subnet.goorm_private_db_subnet_c.id
]
}
# Private DB Subnet resources
resource "aws_subnet" "goorm_private_db_subnet_a" {
vpc_id = aws_vpc.goorm_vpc.id
cidr_block = "172.16.40.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "goorm_private_db_subnet_a"
}
}
resource "aws_subnet" "goorm_private_db_subnet_c" {
vpc_id = aws_vpc.goorm_vpc.id
cidr_block = "172.16.50.0/24"
availability_zone = "ap-northeast-2c"
tags = {
Name = "goorm_private_db_subnet_c"
}
}
########### Network gateway ###########
# Network Gateway for public web subnet
resource "aws_eip" "goorm-ngw-eip-a" {
domain = "vpc"
}
resource "aws_eip" "goorm-ngw-eip-c" {
domain = "vpc"
}
# NAT Gateway
resource "aws_nat_gateway" "goorm-ngw-a" {
allocation_id = aws_eip.goorm-ngw-eip-a.id
subnet_id = aws_subnet.goorm_subnet_a.id
tags = {
Name = "goorm-ngw-a"
}
}
resource "aws_nat_gateway" "goorm-ngw-c" {
allocation_id = aws_eip.goorm-ngw-eip-c.id
subnet_id = aws_subnet.goorm_subnet_c.id
tags = {
Name = "goorm-ngw-c"
}
}
########### Internet gateway ###########
resource "aws_internet_gateway" "goorm_internet_gw" {
vpc_id = aws_vpc.goorm_vpc.id
tags = {
Name = "goorm_internet_gw"
}
}
########### Route table ###########
resource "aws_route_table" "goorm_route_table" {
vpc_id = aws_vpc.goorm_vpc.id
tags = {
Name = "goorm_route_table"
}
}
# Route from internet gateway
resource "aws_route" "goorm_route" {
route_table_id = aws_route_table.goorm_route_table.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.goorm_internet_gw.id
}
resource "aws_route_table_association" "goorm_rtb_sub_a_aasosiation" {
subnet_id = aws_subnet.goorm_subnet_a.id
route_table_id = aws_route_table.goorm_route_table.id
}
# Route table association
resource "aws_route_table_association" "goorm_rtb_sub_c_aasosiation" {
subnet_id = aws_subnet.goorm_subnet_c.id
route_table_id = aws_route_table.goorm_route_table.id
}
# NGW-a to Private Subnet Route Table
resource "aws_route_table" "goorm_private_route_table_a" {
vpc_id = aws_vpc.goorm_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.goorm-ngw-a.id
}
tags = {
Name = "goorm_private_route_table_a"
}
}
resource "aws_route_table_association" "goorm_rtb_private_sub_a_asoc" {
subnet_id = aws_subnet.goorm_private_subnet_a.id
route_table_id = aws_route_table.goorm_private_route_table_a.id
}
# NGW-c to Private Subnet Route Table
resource "aws_route_table" "goorm_private_route_table_c" {
vpc_id = aws_vpc.goorm_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.goorm-ngw-c.id
}
tags = {
Name = "goorm_private_route_table_c"
}
}
resource "aws_route_table_association" "goorm_rtb_private_sub_c_asoc" {
subnet_id = aws_subnet.goorm_private_subnet_c.id
route_table_id = aws_route_table.goorm_private_route_table_c.id
}
web-alb-asg.tf
############ Instance SG ##############
resource "aws_security_group" "web_server_sg" {
name = "web_server_sg"
description = "allow 22, 80"
vpc_id = aws_vpc.goorm_vpc.id
}
resource "aws_security_group_rule" "websg_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.web_server_sg.id
description = "ssh"
}
resource "aws_security_group_rule" "websg_http" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.web_server_sg.id
description = "http"
}
resource "aws_security_group_rule" "websg_outbound" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.web_server_sg.id
description = "outbound"
}
############ Security Group #############
# Application Load Balancer SG
resource "aws_security_group" "web_alb_security_group" {
name = "web_alb_security_group"
description = "ALB Security Group"
vpc_id = aws_vpc.goorm_vpc.id
ingress {
description = "HTTP from Internet"
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 = "web_alb_security_group"
}
}
# Auto Scaling Group SG
resource "aws_security_group" "web_asg_security_group" {
name = "web_asg_security_group"
description = "ASG Security Group"
vpc_id = aws_vpc.goorm_vpc.id
ingress {
description = "HTTP from ALB"
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.web_alb_security_group.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "web_asg_security_group"
}
}
######## Application Load Balancer #########
resource "aws_lb" "web-alb" {
name = "web-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.web_alb_security_group.id]
subnets = [
aws_subnet.goorm_subnet_a.id,
aws_subnet.goorm_subnet_c.id
]
}
# Send HTTP request to target group
resource "aws_lb_listener" "web-alb-listener" {
load_balancer_arn = aws_lb.web-alb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web-alb-target-group.arn
}
}
resource "aws_lb_target_group" "web-alb-target-group" {
name = "web-alb-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.goorm_vpc.id
health_check {
path = "/"
matcher = 200
}
}
######## Auto Scaling Group #########
resource "aws_launch_configuration" "goorm-web-launch-config" {
name = "goorm-web-launchconfig"
image_id = "ami-01123b84e2a4fba05"
instance_type = "t2.micro"
security_groups = [aws_security_group.web_server_sg.id]
user_data = <<-EOF
#! /bin/bash
sudo yum update
sudo yum install nginx -y
sudo service nginx start
sudo chkconfig nginx on
sudo service nginx status
EOF
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "goorm-web-asg" {
name = "goorm-web-asg"
launch_configuration = aws_launch_configuration.goorm-web-launch-config.name
vpc_zone_identifier = [
aws_subnet.goorm_subnet_a.id,
aws_subnet.goorm_subnet_c.id
]
target_group_arns = [aws_lb_target_group.web-alb-target-group.arn]
health_check_type = "ELB"
min_size = 2
max_size = 5
tag {
key = "name"
value = "goorm-web-asg"
propagate_at_launch = true
}
}
app-alb-asg.tf
############ Security Group #############
# Application Load Balancer SG
resource "aws_security_group" "goorm_app_alb_security_group" {
name = "goorm_app_alb_security_group"
description = "ALB Security Group"
vpc_id = aws_vpc.goorm_vpc.id
ingress {
description = "HTTP from Web Instance"
from_port = 80
to_port = 80
protocol = "tcp"
# cidr_blocks = ["0.0.0.0/0"]
security_groups = [aws_security_group.web_server_sg.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "goorm_app_alb_security_group"
}
}
############ App Instance SG ##############
resource "aws_security_group" "app_server_sg" {
name = "app_server_sg"
description = "allow 22, 80"
vpc_id = aws_vpc.goorm_vpc.id
# ingress {
# from_port = 80
# to_port = 80
# protocol = "tcp"
# cidr_blocks = ["0.0.0.0/0"]
# }
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.goorm_app_alb_security_group.id]
}
}
resource "aws_security_group_rule" "appsg_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.app_server_sg.id
description = "ssh"
}
resource "aws_security_group_rule" "appsg_outbound" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.app_server_sg.id
description = "outbound"
}
######## Application Load Balancer #########
resource "aws_lb" "goorm-app-alb" {
name = "goorm-app-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.goorm_app_alb_security_group.id]
subnets = [
aws_subnet.goorm_subnet_a.id,
aws_subnet.goorm_subnet_c.id
]
}
# Send HTTP request to target group
resource "aws_lb_listener" "goorm-app-alb-listener" {
load_balancer_arn = aws_lb.goorm-app-alb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.goorm-app-alb-target-group.arn
}
}
resource "aws_lb_target_group" "goorm-app-alb-target-group" {
name = "goorm-app-alb-target-group"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.goorm_vpc.id
health_check {
path = "/"
matcher = 200
}
}
######## Auto Scaling Group #########
resource "aws_launch_configuration" "goorm-app-launch-config" {
name = "goorm-app-launchconfig"
image_id = "ami-01123b84e2a4fba05"
instance_type = "t2.micro"
security_groups = [aws_security_group.app_server_sg.id]
user_data = <<-EOF
#! /bin/bash
sudo yum update
sudo yum install nginx -y
sudo su
cd /usr/share/nginx/html/
sudo rm index.html
echo "<h1>Hello, World! You are now in private app<h1/>" > index.html
cd ~
sudo service nginx start
sudo chkconfig nginx on
sudo service nginx status
EOF
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "goorm-app-asg" {
name = "goorm-app-asg"
launch_configuration = aws_launch_configuration.goorm-app-launch-config.name
vpc_zone_identifier = [
aws_subnet.goorm_subnet_a.id,
aws_subnet.goorm_subnet_c.id
]
target_group_arns = [aws_lb_target_group.goorm-app-alb-target-group.arn]
health_check_type = "ELB"
min_size = 2
max_size = 5
tag {
key = "name"
value = "goorm-app-asg"
propagate_at_launch = true
}
}
rds.tf
############ Database SG ##############
resource "aws_security_group" "goorm-private-db-sg" {
name = "goorm-private-db-sg"
description = "database security group"
vpc_id = aws_vpc.goorm_vpc.id
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = [aws_security_group.app_server_sg.id]
}
# Can communicate only when manually set egress (outbound)
egress {
from_port = 0
to_port = 0
# -1 means all protocol
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "goorm-private-db-sg"
}
}
############# RDS Cluster ###############
resource "aws_rds_cluster" "goorm-aurora-mysql-db" {
cluster_identifier = "goorm-database"
engine_mode = "provisioned"
db_subnet_group_name = aws_db_subnet_group.goorm_private_db_subnet_grp.name
vpc_security_group_ids = [aws_security_group.goorm-private-db-sg.id]
engine = "aurora-mysql"
engine_version = "5.7.mysql_aurora.2.11.1"
availability_zones = [
"ap-northeast-2a",
"ap-northeast-2c"
]
database_name = "goormPrivatedb"
master_username = "root"
master_password = "root1234"
# skip_final_snapshot = false is cannot controlled by terraform destroy
skip_final_snapshot = true
}
# rds instance writer instance endpoint output for mysql, 3-tier architecture config
output "rds_writer_endpoint" {
value = aws_rds_cluster.goorm-aurora-mysql-db.endpoint
}
############# RDS Instance ##############
resource "aws_rds_cluster_instance" "aurora-mysql-db-instance" {
# 2 instances (reader, writer)
count = 2
identifier = "goorm-database-${count.index}"
cluster_identifier = aws_rds_cluster.goorm-aurora-mysql-db.id
instance_class = "db.r5.large"
engine = aws_rds_cluster.goorm-aurora-mysql-db.engine
engine_version = aws_rds_cluster.goorm-aurora-mysql-db.engine_version
}