우당탕탕 개발일지
테라폼 3-Tier 아키텍처 구축(2) - VPC, EC2 본문
[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
}
}
'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 |