Cloud/Terraform

Terraform - Private Subnet에 Application Load Balancer 구성

잇(IT) 2022. 7. 9. 20:58

1. vpc.tf 코드

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

resource "aws_vpc" "vpc-10-10-0-0" {
  cidr_block       = "10.10.0.0/16"
  instance_tenancy = "default"
  enable_dns_hostnames = true

  tags = {
    Name = "vpc-10-10-0-0"
  }
}

resource "aws_subnet" "sub-pub1-10-10-1-0" {
  vpc_id     = aws_vpc.vpc-10-10-0-0.id
  cidr_block = "10.10.1.0/24"
  availability_zone = "ap-northeast-2a"
  map_public_ip_on_launch = true
  
  tags = {
    Name = "sub-pub1-10-10-1-0"
  }
}

resource "aws_subnet" "sub-pub2-10-10-2-0" {
  vpc_id     = aws_vpc.vpc-10-10-0-0.id
  cidr_block = "10.10.2.0/24"
  availability_zone = "ap-northeast-2c"
  map_public_ip_on_launch = true
  # 이 부분 때문에 public ip가 부여 된다.
  
  tags = {
    Name = "sub-pub1-10-10-2-0"
  }
}

resource "aws_subnet" "sub-pri1-10-10-3-0" {
  vpc_id     = aws_vpc.vpc-10-10-0-0.id
  cidr_block = "10.10.3.0/24"
  availability_zone = "ap-northeast-2a"
  # pri이기 떄문에 pub과 다르게 이부분이 없다.
  
  tags = {
    Name = "sub-pub1-10-10-3-0"
  }
}

resource "aws_subnet" "sub-pri2-10-10-4-0" {
  vpc_id     = aws_vpc.vpc-10-10-0-0.id
  cidr_block = "10.10.4.0/24"
  availability_zone = "ap-northeast-2c"
  
  tags = {
    Name = "sub-pub1-10-10-4-0"
  }
}


# internet gateway
resource "aws_internet_gateway" "igw-vpc-10-10-0-0" {
  vpc_id = aws_vpc.vpc-10-10-0-0.id

  tags = {
    Name = "igw-vpc-10-10-0-0"
  }
}

#routing table 생성
resource "aws_route_table" "rt-pub-vpc-10-10-0-0" {
  vpc_id = aws_vpc.vpc-10-10-0-0.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw-vpc-10-10-0-0.id
  }

  tags = {
    Name = "rt-pub-vpc-10-10-0-0"
  }
}

# pub 라우팅 테이블에 associate 하기
resource "aws_route_table_association" "rt-pub-as1-vpc-10-10-0-0" {
  subnet_id      = aws_subnet.sub-pub1-10-10-1-0.id
  route_table_id = aws_route_table.rt-pub-vpc-10-10-0-0.id
}

resource "aws_route_table_association" "rt-pub-as2-vpc-10-10-0-0" {
  subnet_id      = aws_subnet.sub-pub2-10-10-2-0.id
  route_table_id = aws_route_table.rt-pub-vpc-10-10-0-0.id
}

resource "aws_route_table" "rt-pri1-vpc-10-10-0-0" {
  vpc_id = aws_vpc.vpc-10-10-0-0.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_nat_gateway.natgw-2a.id
  }

  tags = {
    Name = "rt-pri1-vpc-10-10-0-0"
  }
}

resource "aws_route_table" "rt-pri2-vpc-10-10-0-0" {
  vpc_id = aws_vpc.vpc-10-10-0-0.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_nat_gateway.natgw-2c.id
  }

  tags = {
    Name = "rt-pri2-vpc-10-10-0-0"
  }
}

resource "aws_route_table_association" "rt-pri1-as1-vpc-10-10-0-0" {
  subnet_id      = aws_subnet.sub-pri1-10-10-3-0.id
  route_table_id = aws_route_table.rt-pri1-vpc-10-10-0-0.id
}

resource "aws_route_table_association" "rt-pri2-as2-vpc-10-10-0-0" {
  subnet_id      = aws_subnet.sub-pri2-10-10-4-0.id
  route_table_id = aws_route_table.rt-pri2-vpc-10-10-0-0.id
}

# EIP 받아오기
resource "aws_eip" "nat-2a" {
  vpc      = true
}

resource "aws_eip" "nat-2c" {
  vpc      = true
}

resource "aws_nat_gateway" "natgw-2a" {
  allocation_id = aws_eip.nat-2a.id
  subnet_id     = aws_subnet.sub-pub1-10-10-1-0.id

  tags = {
    Name = "gw NAT-2a"
  }
}
  resource "aws_nat_gateway" "natgw-2c" {
  allocation_id = aws_eip.nat-2c.id
  subnet_id     = aws_subnet.sub-pub2-10-10-2-0.id

  tags = {
    Name = "gw NAT-2c"
  }
}

2. ec2.tf 코드

data "aws_ami" "amzn2" {
  most_recent = true

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-2.0.????????.?-x86_64-gp2"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["amazon"] # Canonical
}

resource "aws_security_group" "allow_web-sg" {
  name        = "allow_web-sg"
  description = "Allow web-sg inbound traffic"
  vpc_id      = aws_vpc.vpc-10-10-0-0.id

  ingress {
    description      = "web from VPC"
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name = "allow_web"
  }
}

resource "aws_instance" "bastion" {
  ami           = data.aws_ami.amzn2.id
  instance_type = "t2.micro"
  key_name = "AWS_ISBAEK"
  vpc_security_group_ids = [aws_security_group.allow_web-sg.id]
  availability_zone = "ap-northeast-2a"
  subnet_id = aws_subnet.sub-pub1-10-10-1-0.id
  user_data = file("./userdata.sh")
  
  root_block_device {
      volume_size = 30
  }
  
  tags = {
    Name = "bastion"
  }
  
}

resource "aws_instance" "web-2a" {
  ami           = data.aws_ami.amzn2.id
  instance_type = "t2.micro"
  key_name = "AWS_ISBAEK"
  vpc_security_group_ids = [aws_security_group.allow_web-sg.id]
  availability_zone = "ap-northeast-2a"
  subnet_id = aws_subnet.sub-pri1-10-10-3-0.id
  user_data = file("./userdata.sh")
  
  root_block_device {
      volume_size = 30
  }
  
  tags = {
    Name = "web-2a"
  }
  
}

resource "aws_instance" "web-2c" {
  ami           = data.aws_ami.amzn2.id
  instance_type = "t2.micro"
  key_name = "AWS_ISBAEK"
  vpc_security_group_ids = [aws_security_group.allow_web-sg.id]
  availability_zone = "ap-northeast-2c"
  subnet_id = aws_subnet.sub-pri2-10-10-4-0.id
  user_data = file("./userdata.sh")
  
  root_block_device {
      volume_size = 30
  }
  
  tags = {
    Name = "web-2c"
  }
  
}

3. alb.tf

resource "aws_security_group" "alb-sg" {
  name        = "alb-sg"
  description = "Allow alb inbound traffic"
  vpc_id      = aws_vpc.vpc-10-10-0-0.id

  ingress {
    description      = "alb from VPC"
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name = "alb-sg"
  }
}

resource "aws_lb" "tf-alb" {
  name               = "test-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb-sg.id]
  subnets            = [aws_subnet.sub-pub1-10-10-1-0.id, aws_subnet.sub-pub2-10-10-2-0.id]

  enable_deletion_protection = false

  tags = {
    Name = "tf-alb"
  }
}

resource "aws_lb_target_group" "alb-tg" {
  name     = "tf-alb-tg"
  port     = 80
  protocol = "HTTP"
  vpc_id   = aws_vpc.vpc-10-10-0-0.id
  
  health_check {
        enabled             = true
        healthy_threshold   = 3
        interval            = 5
        matcher             = "200"
        path                = "/"
        port                = "traffic-port"
        protocol            = "HTTP"
        timeout             = 2
        unhealthy_threshold = 2
    }
}

resource "aws_lb_listener" "alb-ln" {
  load_balancer_arn = aws_lb.tf-alb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.alb-tg.arn
  }
}

resource "aws_lb_target_group_attachment" "foreach" {
  for_each         = toset(data.aws_instances.test.ids)
  target_group_arn = aws_lb_target_group.alb-tg.arn
  target_id        = each.key
  port             = 80
}

data "aws_instances" "test" {
  filter {
    name = "tag:Name"
    values = ["web-*"]
  }
}

output "alb_dns_name" {
  value = aws_lb.tf-alb.dns_name
}
728x90