본문 바로가기

KOSA 클라우드 솔루션즈 아키텍트 양성과정

[7.1] Terraform 복습(alb 생성)

구분 CloudFormation Terraform
필드 대소문자 섞어서 작성 소문자로 작성 =>
가독성을 위해 중간에 _를 넣어줌
보안 그룹에 [] (대괄호)
attach IGW를 만들고 별도로 attach IGW를 만들면서 동시에 attach 
 라우팅 테이블 라우팅 테이블을 만든 후 별도로 라우트 정보를 넣어 줌 라우팅 테이블을 만들면서 동시에 라우트 정보를 넣어줌
형식 yaml   json

* Terraform에서 data의 정보를 가져올 때 :

=> data.aws(프로바이더)_availability_zones(가용영역).available.names[0] (가용영역의 첫 번째인 2a 가용영역을 가져옴)

* Terraform에서 id를 가지고 올 때는 "(큰 따옴표) 로 감싸지 말 것


Terraform으로 ALB 생성하기

provider "aws" {
  region = "ap-northeast-2"
}

data "aws_availability_zones" "available" {
  state = "available"
}
resource "aws_vpc" "new_vpc" {
  cidr_block  = "192.168.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support = true
  instance_tenancy = "default"

  tags = {
    Name = "NEW-VPC"
  }
}
resource "aws_subnet" "new_public_subnet_2a" {
  vpc_id = aws_vpc.new_vpc.id
  cidr_block = "192.168.0.0/20"
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available.names[0]
  tags = {
    Name = "NEW-PUBLIC-SUBNET-2A"
  }
}
resource "aws_subnet" "new_public_subnet_2b" {
  vpc_id = aws_vpc.new_vpc.id
  cidr_block = "192.168.16.0/20"
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available.names[1]
  tags = {
    Name = "NEW-PUBLIC-SUBNET-2B"
  }
}
resource "aws_subnet" "new_public_subnet_2c" {
  vpc_id = aws_vpc.new_vpc.id
  cidr_block = "192.168.32.0/20"
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available.names[2]
  tags = {
    Name = "NEW-PUBLIC-SUBNET-2C"
  }
}
resource "aws_subnet" "new_public_subnet_2d" {
  vpc_id = aws_vpc.new_vpc.id
  cidr_block = "192.168.48.0/20"
  map_public_ip_on_launch = true
  availability_zone = data.aws_availability_zones.available.names[3]
  tags = {
    Name = "NEW-PUBLIC-SUBNET-2D"
  }
}
resource "aws_internet_gateway" "new_igw" {
  vpc_id = aws_vpc.new_vpc.id
  tags = {
    Name = "NEW-IGW"
  }
}
resource "aws_route_table" "new_public_rtb" {
  vpc_id = aws_vpc.new_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.new_igw.id
  }
  tags = {
    Name = "NEW-PUBLIC-RTB"
  }
}
resource "aws_route_table_association" "new_public_subnet_2a_association" {
  subnet_id = aws_subnet.new_public_subnet_2a.id
  route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2b_association" {
  subnet_id = aws_subnet.new_public_subnet_2b.id
  route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2c_association" {
  subnet_id = aws_subnet.new_public_subnet_2c.id
  route_table_id = aws_route_table.new_public_rtb.id
}
resource "aws_route_table_association" "new_public_subnet_2d_association" {
  subnet_id = aws_subnet.new_public_subnet_2d.id
  route_table_id = aws_route_table.new_public_rtb.id
}

#data "aws_vpc" "new_vpc" {
#  tags = {
#    Name = "NEW-VPC"
#  }
#}
#data "aws_subnet" "apne2_az1" {
#  tags = {
#    Name = "NEW-PUBLIC-SUBNET-2A"
#  }
#}
#data "aws_subnet" "apne2_az3" {
#  tags = {
#    Name = "NEW-PUBLIC-SUBNET-2C"
#  }
#}

variable "security_group_name" {
  description = "The name of the security group"
  type        = string
  default     = "NEW-SG-ALB"
}

resource "aws_security_group" "new_sg_alb" {
  name   = var.security_group_name
#  vpc_id = data.aws_vpc.new_vpc.id
  vpc_id = aws_vpc.new_vpc.id
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 443
    to_port     = 443
    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 = "NEW-SG-ALB"
  }
}

resource "aws_lb" "frontend" {
  name               = "alb-example"
  internal           = false                       => 인터넷 경계 셋팅(인터널이 false면 사용자가 외부에서 접속하는 것)
  load_balancer_type = "application"
  security_groups    = [aws_security_group.new_sg_alb.id]
  subnets            = [
    aws_subnet.new_public_subnet_2a.id,
    aws_subnet.new_public_subnet_2c.id
  ]

  tags = {
    Name = "NEW-ALB"
  }

  lifecycle { create_before_destroy = true }        => EC2를 지우기 전에 먼저 EC2를 만들어라( 추후 ASG를 위함)
}


resource "aws_instance" "alb_vm_01" {
  ami                    = "ami-0fd0765afb77bcca7"
  instance_type          = "t2.micro"
  subnet_id              = aws_subnet.new_public_subnet_2a.id
  vpc_security_group_ids = [aws_security_group.new_sg_alb.id]
  key_name  = "new-key"
  user_data = <<-EOF
              #! /bin/bash
              yum install -y httpd
              systemctl enable --now httpd
              echo "Hello, Terraform01" > /var/www/html/index.html
              EOF

  tags = {
    Name = "ALB01"
  }
}

resource "aws_instance" "alb_vm_02" {
  ami                    = "ami-0fd0765afb77bcca7"
  instance_type          = "t2.micro"
  subnet_id              = aws_subnet.new_public_subnet_2c.id
  vpc_security_group_ids = [aws_security_group.new_sg_alb.id]
  key_name  = "new-key"
  user_data = <<-EOF
              #! /bin/bash
              yum install -y httpd
              systemctl enable --now httpd
              echo "Hello, Terraform02" > /var/www/html/index.html
              EOF

  tags = {
    Name = "ALB02"
  }
}

resource "aws_lb_target_group" "tg" {
  name        = "TargetGroup"
  port        = 80
  target_type = "instance"
  protocol    = "HTTP"
  vpc_id      = aws_vpc.new_vpc.id

  health_check {
    path                = "/"    => /var/www/html/index.html 와 같은 의미, 다른 폴더를 헬스체크 폴더로 해주면 해당 경로 입력
    protocol            = "HTTP"
    matcher             = "200"
    interval            = 15
    timeout             = 3
    healthy_threshold   = 2
    unhealthy_threshold = 2
  }
}
resource "aws_alb_target_group_attachment" "tgattachment01" {
  target_group_arn = aws_lb_target_group.tg.arn
  target_id        = aws_instance.alb_vm_01.id
  port             = 80
}
resource "aws_alb_target_group_attachment" "tgattachment02" {
  target_group_arn = aws_lb_target_group.tg.arn
  target_id        = aws_instance.alb_vm_02.id
  port             = 80
}

resource "aws_lb_listener" "front_end" {
  load_balancer_arn = aws_lb.frontend.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.tg.arn
  }
}
output "lb_dns_name" {
  description = "The DNS name of the load balancer."
  value       = aws_lb.frontend.dns_name
}