Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

우당탕탕 개발일지

테라폼 3-Tier 아키텍처 구축(2) - VPC, EC2 본문

Cloud

테라폼 3-Tier 아키텍처 구축(2) - VPC, EC2

YUDENG 2023. 11. 26. 05:32

[Cloud] - 테라폼 3-Tier 아키텍처 구축(1) - 보안그룹

 

[ vpc ]

- variable.tf

variable "vpc-id" {
  description = "VPC ID"
  type        = string
}

variable "pub-sub1-id" {
  description = "Public Subnet1 ID"
  type        = string
}
variable "pub-sub2-id" {
  description = "Public Subnet2 ID"
  type        = string
}

variable "pri-sub1-id" {
  description = "Private Subnet1 ID"
  type        = string
}
variable "pri-sub2-id" {
  description = "Private Subnet2 ID"
  type        = string
}

variable "pub-rt-id" {
  description = "Public Route Table ID"
  type        = string
}
variable "pri-rt-id" {
  description = "Private Route Table ID"
  type        = string
}

variable "igw-id" {
  description = "Internet Gateway ID"
  type        = string
}
variable "ngw-id" {
  description = "Nat Gateway ID"
  type        = string
}
variable "eip-id" {
  description = "Elastic ID"
  type        = string
}

- outputs.tf

output "vpc_id" { 
  description = "VPC ID"
  value = aws_vpc.vpc.id
}
output "public_subnet1_id" {
  description = "Public Subnet1 ID"
  value = aws_subnet.public_subnet1.id
}
output "public_subnet2_id" {
  description = "Public Subnet2 ID"
  value = aws_subnet.public_subnet2.id
}
output "private_subnet1_id" {
  description = "Private Subnet1 ID"
  value = aws_subnet.private_subnet1.id
}
output "private_subnet2_id" {
  description = "Private Subnet2 ID"
  value = aws_subnet.private_subnet2.id
}
output "public_route_table_id" {
  description = "Public Route Table ID"
  value = aws_route_table.public_route_table.id
}
output "private_route_table_id" {
  description = "Private Route Table ID"
  value = aws_route_table.private_route_table.id
}

output "internet_gateway_id" {
  description = "Internet Gateway ID"
  value = aws_internet_gateway.internet_gateway.id
}
output "nat_gateway_id" {
  description = "Nat Gateway ID"
  value = aws_nat_gateway.nat_gateway.id
}
output "elastic_ip_id" {
  description = "Elastic IP ID"
  value = aws_eip.elastic_ip.id
}

- vpc (aws_vpc)

resource "aws_vpc" "vpc" {
  cidr_block       = "10.0.0.0/16"
  instance_tenancy = "default"
  enable_dns_hostnames = true

  tags = {
    Name = "vpc"
  }
}

- 서브넷 (aws_subnet)

Public -> public-subnet1, public-subnet2

Private -> private -subnet1, private-subnet2

####################################
#   Public Subnet
####################################
resource "aws_subnet" "public_subnet1" {
  vpc_id     = var.vpc-id
  cidr_block = "10.0.1.0/24"
  availability_zone = "us-east-2a"

  tags = {
    Name = "public_subnet1"
  }
}
resource "aws_subnet" "public_subnet2" {
  vpc_id     = var.vpc-id
  cidr_block = "10.0.2.0/24"
  availability_zone = "us-east-2b"
  map_public_ip_on_launch = true

  tags = {
    Name = "public_subnet2"
  }
}

####################################
#   Private Subnet
####################################
resource "aws_subnet" "private_subnet1" {
  vpc_id     = var.vpc-id
  cidr_block = "10.0.11.0/24"
  availability_zone = "us-east-2a"

  tags = {
    Name = "private_subnet1"
  }
}
resource "aws_subnet" "private_subnet2" {
  vpc_id     = var.vpc-id
  cidr_block = "10.0.12.0/24"
  availability_zone = "us-east-2b"

  tags = {
    Name = "private_subnet2"
  }
}

- 인터넷 게이트웨이 (aws_internet_gateway)

resource "aws_internet_gateway" "internet_gateway" {
  vpc_id = var.vpc-id
  tags = {
    Name = "internet-gateway"
  }
}

- 네트워크 게이트웨이 (aws_nat_gateway)

####################################
#   Elastic IPs
####################################
resource "aws_eip" "elastic_ip" {
  # instance = aws_instance.web.id
  domain   = "vpc"
}

####################################
#   Nat Gateway
####################################
resource "aws_nat_gateway" "nat_gateway" {
  allocation_id = var.eip-id
  subnet_id     = var.pub-sub1-id
  tags = {
    Name = "nat_gateway"
  }
}

- 라우팅 테이블 (aws_route_table)

라우팅 테이블은 ip 주소에 대한 라우팅 경로를 설정한다. 이는 Public Private을 나눠 설정하고 각각 Public, Private 서브넷에 연결한다. 외부에서 내부로의 접근이 가능해야 하므로 Public 서브넷만 인터넷 게이트와 연결한다.

public-route-table, private-route-table

####################################
#   Public Route Table
####################################
resource "aws_route_table" "public_route_table" {
  vpc_id = var.vpc-id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = var.igw-id
  }

  tags = {
    Name = "public_route_table"
  }
}

####################################
#   Association
####################################
resource "aws_route_table_association" "public-rt-association1" {
  subnet_id      = var.pub-sub2-id
  route_table_id = var.pub-rt-id
}
resource "aws_route_table_association" "public-rt-association2" {
  subnet_id      = var.pub-sub1-id
  route_table_id = var.pub-rt-id
}

####################################
#   Private Route Table
####################################
resource "aws_route_table" "private_route_table" {
  vpc_id = var.vpc-id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = var.ngw-id
  }

  tags = {
    Name = "private_route_table"
  }
}

####################################
#   Association
####################################
resource "aws_route_table_association" "private-rt-association1" {
  subnet_id      = var.pri-sub1-id
  route_table_id = var.pri-rt-id
}
resource "aws_route_table_association" "private-rt-association2" {
  subnet_id      = var.pri-sub2-id
  route_table_id = var.pri-rt-id
}

 

[ ec2 ]

- variable.tf

variable "vpc-sg-id" {
  description = "VPC Security Group ID"
  type = string
}
variable "web-sg-id" {
  description = "WEB Security Group ID"
  type = string
}

variable "was-sg-id" {
  description = "WAS Security Group ID"
  type = string
}

variable "vpc-id" {
  description = "VPC ID"
  type = string
}

variable "pub-sub1-id" {
  description = "Public Subnet1 ID"
  type = string
}
variable "pub-sub2-id" {
  description = "Public Subnet2 ID"
  type = string
}

variable "pri-sub1-id" {
  description = "private Subnet1 ID"
  type = string
}
variable "pri-sub2-id" {
  description = "private Subnet2 ID"
  type = string
}

- outputs.tf

output "bastion_instance_id" {
  description = "Bastion Instance ID"
  value = aws_instance.bastion_instance.id
}

- 오토 스케일링 (aws_autoscaling_group)

Bastion_instance, web_instance * 2, was_instance * 2

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
  }

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

  owners = ["099720109477"] # Canonical
}

####################################
#   SSH Key
####################################
resource "aws_key_pair" "deployer" {
key_name = "deployer-key"
public_key = file("~/.ssh/testkey.pub")
}

####################################
#   WEB Launch Configuration 
####################################
resource "aws_launch_configuration" "web-configuration" {
  name          = "web_config"
  image_id      = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"

  security_groups = [var.web-sg-id]

  lifecycle {
    create_before_destroy = true
  }
}

####################################
#   WAS Launch Configuration 
####################################
resource "aws_launch_configuration" "was-configuration" {
  name          = "was_config"
  image_id      = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"

  user_data = file("userdata.template")
  security_groups = [var.was-sg-id]

  lifecycle {
    create_before_destroy = true
  }
}

####################################
#   Bastion Instance
####################################
resource "aws_instance" "bastion_instance"{
  ami = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  subnet_id = var.pub-sub1-id
  associate_public_ip_address = "true"

  key_name = aws_key_pair.deployer.key_name
  vpc_security_group_ids = [var.vpc-sg-id]
  tags = { Name = "bastion_instance" }
}
####################################
#   WEB Autoscaling 
####################################
resource "aws_autoscaling_group" "web-autoscaling" {
  name                      = "web-autoscaling"
  max_size                  = 4
  min_size                  = 2
  desired_capacity          = 2
  
  health_check_grace_period = 300
  health_check_type         = "ELB"
  force_delete              = true

  launch_configuration      = aws_launch_configuration.web-configuration.name
  vpc_zone_identifier       = [var.pub-sub1-id, var.pub-sub2-id]
  target_group_arns = [aws_lb_target_group.alb-target-group.arn]

  tag {
    key                 = "Name"
    value               = "web-autoscaling"
    propagate_at_launch = false
  }
  lifecycle {
    create_before_destroy = true
  }
}

####################################
#   WAS Autoscaling 
####################################
resource "aws_autoscaling_group" "was-autoscaling" {
  name                      = "was-autoscaling"
  max_size                  = 4
  min_size                  = 2
  desired_capacity          = 2
  
  health_check_grace_period = 300
  health_check_type         = "ELB"
  force_delete              = true

  launch_configuration      = aws_launch_configuration.was-configuration.name
  vpc_zone_identifier       = [var.pri-sub1-id, var.pri-sub2-id]
  target_group_arns = [aws_lb_target_group.nlb-target-group.arn]

  tag {
    key                 = "Name"
    value               = "was-autoscaling"
    propagate_at_launch = false
  }
  lifecycle {
    create_before_destroy = true
  }
}

- 로드벨런서 (aws_lb)

alb HTTP HTTPS 트래픽 로드밸런싱

인터넷 게이트웨이로 들어온 트래픽을 WEB으로 분산시킨다. 가용영역을 public 서브넷으로 설정하고 vpc 보안그룹을 사용한다. HTTP 프로토콜의 80포트를 타고 타겟을 찾아가도록 설정하였으며, 타겟 그룹은 private 서브넷으로 설정한다.

Public -> application-load-balancing

내부 WEB으로 들어온 트래픽을 WAS로 분산시킨다. 가용영역은 private 서브넷(web instance)로 설정하고, web 보안그룹 사용을 타겟 그룹은 private 서브넷(was instance)으로 설정한다.

Private -> network-load-balancing ( internal 외부에서 접근이 가능한지 여부 )

####################################
#   Application Load Balancing
####################################
resource "aws_lb" "application-load-balancing" {
  name               = "application-load-balancing"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [var.web-sg-id]
  subnets            = [var.pub-sub1-id, var.pub-sub2-id]

  tags = {
    Name = "application-load-balancing"
  }
}

####################################
#   Load Balancing Listener
####################################
resource "aws_lb_listener" "alb-listener" {
  load_balancer_arn = aws_lb.application-load-balancing.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type = "fixed-response"

    fixed_response {
      content_type = "text/plain"
      message_body = "404: page not found"
      status_code  = 404
    }
  }
}

####################################
#   Load Balancing Target Group
####################################
resource "aws_lb_target_group" "alb-target-group" {
  name     = "alb-target-group"
  port     = 80
  protocol = "HTTP"
  vpc_id   = var.vpc-id

  health_check {
    path                = "/"
    protocol            = "HTTP"
    matcher             = "200"
    interval            = 15
    timeout             = 3
    healthy_threshold   = 2
    unhealthy_threshold = 2
  }
}

####################################
#   Load Balancing Rule
####################################
resource "aws_lb_listener_rule" "alb-rule" {
  listener_arn = aws_lb_listener.alb-listener.arn
  priority     = 100

  action {
    type = "forward"
    target_group_arn = aws_lb_target_group.alb-target-group.arn
  }

  condition {
    path_pattern {
      values = ["*"]
    }
  }
}
####################################
#   Network Load Balancing
####################################
resource "aws_lb" "network-load-balancing" {
  name               = "network-load-balancing"
  internal           = true
  load_balancer_type = "network"
  security_groups    = [var.was-sg-id]
  subnets            = [var.pri-sub1-id, var.pri-sub2-id]

  tags = {
    Name = "network-load-balancing"
  }
}

####################################
#   Load Balancing Listener
####################################
resource "aws_lb_listener" "nlb-listener" {
  load_balancer_arn = aws_lb.network-load-balancing.arn
  port              = "8080"
  protocol          = "TCP"

  default_action{
    type = "forward"
    target_group_arn = aws_lb_target_group.nlb-target-group.arn
  }
}

####################################
#   Load Balancing Target Group
####################################
resource "aws_lb_target_group" "nlb-target-group" {
  name     = "nlb-target-group"
  port     = 8080
  protocol = "TCP"
  vpc_id   = var.vpc-id

  health_check {
    path                = "/"
    protocol            = "HTTP"
    matcher             = "200"
    interval            = 15
    timeout             = 3
    healthy_threshold   = 2
    unhealthy_threshold = 2
  }
}
728x90

'Cloud' 카테고리의 다른 글

모니터링 구축  (2) 2024.01.05
Linux Git  (0) 2023.12.12
테라폼 3-Tier 아키텍처 구축(1) - 보안그룹  (0) 2023.11.26
테라폼 개발 환경 준비  (1) 2023.11.26
CI/CD 파이프라인 - GCP를 통한 Jenkins CI 구축  (0) 2023.10.30