IaC AWS 아키텍처 구축 - 4

SangYeon Min·2023년 11월 30일
0

STUDY-DevOps

목록 보기
5/7
post-thumbnail

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
}

0개의 댓글