1. VPC 및 서브넷 생성
2. VPC 보안 그룹 생성
3. DB 서브넷 그룹 생성
만들어야 하는 사양
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p ${var.server_port} &
IaC 작성 참고 : Terraform Registry
기존과 같이 진행해야 할 순서를 정한 후 테라폼을 작성했습니다.
순서는 아래와 같이 작성했습니다.
가장 먼저 프라이빗 서브넷에 위치할 RDS를 생성했습니다.
가장 주의할 점은 RDS를 프라이빗 서브넷으로 올바르게 위치시켜야 했기에
프라이빗 서브넷 그룹을 명시해줬습니다.
#RDS 생성
resource "aws_db_instance" "Sprint_terraform_RDS" {
allocated_storage = 10
db_name = "Sprint_terraform_RDS"
availability_zone = "ap-northeast-2c"
db_subnet_group_name = "sprint_subnetgroup"
vpc_security_group_ids = [aws_security_group.Sprint_security_DB.id]
engine = "mysql"
engine_version = "8.0"
instance_class = "db.t3.micro"
username = "admin"
password = "admin1234"
skip_final_snapshot = true
// deletion_protection = true
tags = {
Name = "Sprint_terraform_RDS"
}
}
다음은 탄력적 IP주소를 생성해줬습니다. 프라이빗 서브넷에 위치한 RDS와의 통신을 위해 퍼블릭 서브넷에 유동적인 IP가 아닌 고정 IP가 필요했기에 이 작업을 진행했습니다.
# 탄력적 IP 생성
resource "aws_eip" "sprint_eip" {
vpc = true
tags = {
Name = "sprint_eip"
}
}
프라이빗 서브넷에 위치한 RDS가 외부와 통신하기 위해 NAT Gateway를 이용했습니다.
# NAT Gateway 생성
resource "aws_nat_gateway" "sprint_natgw" {
allocation_id = aws_eip.sprint_eip.id
subnet_id = aws_subnet.sprint_public2.id
tags = {
Name = "sprint_natgw"
}
depends_on = [aws_internet_gateway.sprint_gw]
}
다음으로 라우팅 테이블을 세팅하여 프라이빗 서브넷과 NAT Gateway를 연결해 줬습니다.
# 프라이빗 서브넷 라우팅 테이블 생성
resource "aws_route_table" "Sprint_route_table_private" {
vpc_id = aws_vpc.Sprint_Terraform_VPC.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.sprint_natgw.id
}
tags = {
Name = "Sprint_route_table_private"
}
}
# 라우팅 테이블 - 서브넷 private1 연결
resource "aws_route_table_association" "Connect_rt_pv1" {
subnet_id = aws_subnet.sprint_private1.id
route_table_id = aws_route_table.Sprint_route_table_private.id
}
# 라우팅 테이블 - 서브넷 private2 연결
resource "aws_route_table_association" "Connect_rt_pv2" {
subnet_id = aws_subnet.sprint_private2.id
route_table_id = aws_route_table.Sprint_route_table_private.id
}
위의 작업을 진행 후 ec2 인스턴스로 rds에 접속이 가능함을 확인했고 최종적으로 오토스케일링 작업을 위해 로드밸런서를 생성하기로 했습니다.
그래서 그 이전 타겟 그룹을 생성했습니다.
# 타겟 그룹 생성
resource "aws_lb_target_group" "SprintTg" {
name = "SprintTg"
port = 8080
protocol = "HTTP"
vpc_id = aws_vpc.Sprint_Terraform_VPC.id
health_check {
enabled = true
healthy_threshold = 3
interval = 10
matcher = 200
path = "/"
port = "traffic-port"
protocol = "HTTP"
timeout = 3
unhealthy_threshold = 2
}
}
# 타겟 그룹과 인스턴스 연결(sprint_terraform_EC2_2a)
resource "aws_lb_target_group_attachment" "SprintTg_attachment_2a" {
target_group_arn = aws_lb_target_group.SprintTg.arn
target_id = aws_instance.sprint_terraform_EC2_2a.id
port = 8080
}
# 타겟 그룹과 인스턴스 연결(sprint_terraform_EC2_2c)
resource "aws_lb_target_group_attachment" "SprintTg_attachment_2c" {
target_group_arn = aws_lb_target_group.SprintTg.arn
target_id = aws_instance.sprint_terraform_EC2_2c.id
port = 8080
}
resource "aws_lb" "SprintAlb" {
name = "SprintAlb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.Sprint_security_PW.id]
subnets = [aws_subnet.sprint_public1.id, aws_subnet.sprint_public2.id]
tags = {
Environment = "SprintAlb"
}
}
# 로드밸런서 리스너 생성
resource "aws_lb_listener" "Sprint_alb_listner" {
load_balancer_arn = aws_lb.SprintAlb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.SprintTg.arn
}
}
해당 작업을 완료 후
로드밸런서를 통한 DNS주소 접속이 가능함을 확인했습니다.
오토스케일링 작업을 수행하기 위해 필요한 사전구성을 작성해줬습니다.
기존의 EC2를 생성할때 사용한 내용을 기반으로 동일한 인스턴스를 생성할 수 있도록 만들어줍니다.
# 오토스케일링 시작 템플릿 설정
resource "aws_launch_configuration" "sprint_as_config" {
name = "sprint_as_config"
image_id = "ami-0cb1d752d27600adb" # ap-northeast-2
instance_type = "t2.micro"
associate_public_ip_address = true
security_groups = [aws_security_group.Sprint_security_PW.id]
key_name = "sprint_1234"
# 사용자 데이터 입력
user_data = <<-EOF
#!/bin/bash
echo "Hello, World" > index.html
nohup busybox httpd -f -p ${var.server_port} &
EOF
depends_on = [
aws_key_pair.sprint_1234
]
lifecycle {
create_before_destroy = true
}
}
사전 구성을 마쳤다면 실제로 오토스케일링 그룹을 생성해 인스턴스가 잘 생성되는지를 확인해줍니다.
# 오토스케일링 그룹 생성
resource "aws_autoscaling_group" "sprint_as_group" {
name = "sprint_as_group"
max_size = 10
min_size = 2
health_check_grace_period = 300
health_check_type = "ELB"
force_delete = true
launch_configuration = aws_launch_configuration.sprint_as_config.name
vpc_zone_identifier = [aws_subnet.sprint_public1.id, aws_subnet.sprint_public2.id]
target_group_arns = [aws_lb_target_group.SprintTg.arn]
tags = [{
key = "Name"
value = "${var.instance_name}"
propagate_at_launch = true
}]
}
위의 작업까지 성공적으로 끝났을때 인스턴스가 4개가 존재하고 있었습니다.
타겟그룹에도 4개의 인스턴스가 위치하고 있었죠 그래서 기존에 인스턴스를 생성하는 리소스와 타겟그룹에 인스턴스를 추가하는 리소스를 삭제했습니다.
테라폼을 활용해 실습을 하면서 레지스트리를 정말 많이 뒤져가면서 대부분을 하드코딩으로 진행했습니다. 하지만 Variable, data, Output, backend, lockfile등 테라폼을 통해 활용할 수 있는 많은 기능이 있는것을 작업이 끝난 후에야 알게되어서ㅠㅠ 테라폼을 더 깊게 공부해야 겠다는 생각이 들었습니다.!