이번 주차에서는 Terraform을 사용해 aws 인프라를 단계적으로 구축했다.
구성한 인프라는 아래와 같다.
- VPC 생성
- Public Subnet 2개 생성
- EC2 2대 생성
- ALB(Application Load Balancer) 생성
- Target Group 및 Listener 연결
- Auto Scaling Group 생성
- ALB와 ASG를 연결하여 트래픽 분산 확인
처음에는 EC2를 직접 생성해서 ALB에 연결했고
이후에는 Auto Scaling Group을 도입하면서 EC2를 직접 연결하는 방식에서 ASG가 자동으로 인스턴스를 생성하고 대상 그룹에 등록하는 방식으로 변경했다.
디렉토리 구조
이번 실습은 리소스 종류별로 디렉토리를 나누어 관리했다.
terraform/
├─ vpc/
├─ ec2/
├─ alb/
└─ asg/
이렇게 나눈 이유는 역할을 명확하게 분리하기 위해서다.
vpc: 네트워크 리소스
ec2 : EC2 인스턴스 생성
alb : ALB, Target Group, Listener
asg : Launch Template, Auto Scaling Group
Terraform은 한 디렉토리 안의 .tf 파일들을 하나의 프로젝트처럼 인식한다.
따라서 디렉토리를 나누면 리소스 단위로 독립적으로 생성, 수정, 삭제할 수 있다는 장점이 있다.
실습 과정
이번 실습은 아래 순서로 진행했다.
1. VPC 생성
먼저 사용자 정의 VPC와 Public Subnet 2개를 생성했다.
2. EC2 생성
VPC 위에 EC2 인스턴스 2대를 생성했다.
이때 user_data를 이용해 nginx를 설치하고, 접속 시 어떤 서버인지 구분할 수 있도록 간단한 HTML을 출력하게 했다.
3. ALB 생성
ALB를 생성하고, EC2 2대를 Target Group에 직접 연결했다.
이후 브라우저에서 ALB DNS로 접속했을 때 새로고침마다 서로 다른 인스턴스가 응답하는 것을 확인했다.
4. ASG 생성
기존의 고정 EC2 구조 대신 Auto Scaling Group을 도입했다.
이제부터는 ASG가 Launch Template을 바탕으로 인스턴스를 자동 생성하고 Target Group에 자동 등록하도록 변경했다.
1. VPC 디렉토리
vpc/ 디렉토리는 네트워크의 뼈대를 만드는 역할을 한다.
여기서 만든 대표 리소스는 다음과 같다.
- VPC
- Public Subnet 2개
- Internet Gateway
- Route Table
- Route Table Association
즉, EC2나 ALB가 올라갈 기반 네트워크를 먼저 만든 것이다.
VPC에서 중요한 점
이번 실습에서는 ALB와 ASG를 모두 Public Subnet 위에 구성했다.
ALB는 외부 인터넷 트래픽을 받아야 하므로 Public Subnet에 위치해야 하고
EC2도 테스트를 위해 Public Subnet에 두었다.
VPC 파일 분리 예시
보통 vpc/ 안에는 아래처럼 파일을 나눌 수 있다.
├─ provider.tf
├─ variables.tf
├─ main.tf
└─ terraform.tfvars
provider.tf
AWS 리전을 설정한다.
provider "aws" {
region = "ap-northeast-2"
}
variables.tf
변수 선언 파일이다.
CIDR이나 이름 등을 변수로 선언해 재사용하기 쉽게 한다.
terraform.tfvars
실제 값을 넣는 파일이다.
main.tf
실제 리소스를 작성하는 핵심 파일이다.
2. EC2 디렉토리
ec2/ 디렉토리에서는 ALB에 연결하기 전 단계로
고정된 EC2 인스턴스 2대를 생성했다.
즉 이 단계에서는 Auto Scaling 없이 직접 인스턴스를 만들었다.
EC2 실습에서 구성한 것
- Ubuntu AMI 조회
- EC2 보안 그룹 생성
- EC2 2대 생성
- nginx 설치 및 HTML 페이지 출력
왜 user_data를 사용했는가
EC2가 생성된 직후 자동으로 서버 설정을 하기 위해서다.
예를 들어 아래처럼 nginx를 설치하고 HTML 파일을 생성하면
EC2에 접속하지 않아도 웹서버가 바로 동작하게 된다.
#!/bin/bash
apt-get update -y
apt-get install -y nginx
cat > /var/www/html/index.html <<EOF
<h1>Served by $(hostname)</h1>
<p>Private IP: $(hostname -I | awk '{print $1}')</p>
EOF
systemctl enable nginx
systemctl restart nginx
이렇게 하면 ALB 뒤에 여러 대의 서버가 있더라도
어느 인스턴스가 응답했는지 쉽게 확인할 수 있다.
EC2 보안 그룹
EC2 보안 그룹에서는 보통 다음 규칙을 넣는다.
- SSH 22 : 내 IP만 허용
- HTTP 80 : ALB 또는 외부 허용
실습 초반에는 테스트를 위해 HTTP를 열어두고
이후 ALB와 연동할 때는 ALB 보안 그룹만 EC2의 80번 포트에 접근 가능하도록 설정하는 것이 더 적절하다.
3. ALB 디렉토리
alb/ 디렉토리는 로드밸런서를 만드는 역할을 한다.
여기서는 다음 리소스를 생성했다.
- ALB
- Target Group
- Listener
- ALB 보안 그룹
초기에는 여기에 추가로 aws_lb_target_group_attachment도 작성해서
EC2 2대를 수동으로 Target Group에 연결했다.
ALB 핵심
ALB는 직접 EC2를 생성하지 않는다.
ALB는 들어온 요청을 Target Group으로 전달하고
Target Group에 등록된 대상들에게 트래픽을 분산한다.
즉 관계는 아래와 같다.
target_group_attachment를 삭제한 이유
초기에는 아래처럼 EC2를 직접 Target Group에 연결했다.
resource "aws_lb_target_group_attachment" "web1" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = data.aws_instances.web.ids[0]
port = 80
}
하지만 ASG를 도입한 뒤에는 이 구조가 더 이상 맞지 않는다.
왜냐하면 이제 EC2는 Terraform이 직접 고정 생성하는 것이 아니라
Auto Scaling Group이 자동 생성/삭제하기 때문이다.
따라서 ALB는 Target Group만 유지하고
ASG가 해당 Target Group에 인스턴스를 자동 등록하도록 변경했다.
즉 구조가 아래처럼 바뀐 것이다.
변경 전
변경 후
4. ASG 디렉토리
asg 디렉토리는 Auto Scaling Group 관련 리소스를 담당한다.
실제로는 아래 파일만 있어도 충분했다.
├─ main.tf
├─ provider.tf
├─ variables.tf
├─ terraform.tfvars
└─ userdata.sh
ASG에서 만든 리소스
- ASG용 보안 그룹
- Launch Template
- Auto Scaling Group
즉 ASG는 인스턴스를 직접 정의하는 것이 아니라, 어떤 방식으로 인스턴스를 만들지에 대한 템플릿을 바탕으로 자동 생성하는 구조다.
Auto Scaling 동작 확인

Terraform을 이용해 Auto Scaling Group을 생성한 뒤, 실제로 인스턴스가 자동으로 관리되는지 확인해 보았다.
먼저 Terraform으로 생성된 Auto Scaling Group을 콘솔에서 확인했다.

이후 Auto Scaling Group의 용량을 증가시켜 인스턴스 수가 실제로 늘어나는지 테스트하였다.

설정한 값에 따라 EC2 인스턴스가 추가로 생성된 것을 확인할 수 있었다.

또한 ALB의 Target Group에서도 새로 생성된 인스턴스들이 정상적으로 등록되고 헬스 체크가 통과된 것을 확인할 수 있었다.




이후 ALB DNS 주소로 접속하여 새로고침을 반복했을 때, 여러 인스턴스가 번갈아 응답하는 것을 확인할 수 있었다.
실습 중 겪은 오류와 해결
subnet ID does not exist
ASG 생성 중 아래 오류가 발생했다.
원인은 terraform.tfvars에 입력한 subnet ID가 잘못되었기 때문이다.
해결 방법
vpc 디렉토리에서 terraform state show로 정확한 subnet ID를 다시 확인하고 올바른 값을 asg/terraform.tfvars에 반영해야 한다.
이 과정에서 디렉토리를 나누면 편하지만,=
그 대신 다른 디렉토리의 값을 수동으로 넘겨야 한다는 점을 체감할 수 있었다.
Provided Target Groups may not be valid
원인은 target_group_arn 값을 정확하지 않게 넣었기 때문이다.
또한 이 과정을 통해 ALB에서 output "target_group_arn"을 만들어두면
ASG 디렉토리에서 값 복사 시 훨씬 편하다는 점도 알게 되었다.
해결 방법
alb.tf에 target_group_arn output 추가하고 콘솔 또는 terraform output으로 정확한 ARN 확인하여 ASG의 terraform.tfvars에 반영해야 한다.
SSH timeout
실습 도중 Terraform이 설치된 EC2에 SSH 접속이 갑자기 되지 않는 상황도 있었다.
처음에는 인스턴스 문제로 보였지만 실제 원인은 잠깐 다른 Wi-Fi에 연결했다가 다시 돌아오면서 공인 IP가 바뀐 것이었다.
보안 그룹에서 SSH를 my_ip/32로 제한해 두었기 때문에
공인 IP가 바뀌는 순간 접속이 막힌 것이다.
이 경험을 통해 보안 그룹에서 내 IP 허용 방식은 안전하지만
네트워크가 바뀌면 바로 접속이 막힐 수 있다는 점을 알게 되었다.
destroy 순서
Terraform으로 생성한 리소스를 삭제할 때는 의존성의 반대 순서로 삭제해야 한다.
삭제 순서는 asg → alb → ec2 → vpc
이 순서가 중요한 이유는
예를 들어 VPC를 먼저 삭제하려고 하면 그 안에 ALB나 EC2, Subnet 등이 남아 있어 실패하기 때문이다.
이번 실습에서 배운 점
이번 실습을 통해 단순히 Terraform 문법을 사용하는 것에 그치지 않고 AWS 인프라 리소스들이 서로 어떤 구조로 연결되어 동작하는지 함께 이해할 수 있었다. 특히 VPC는 모든 리소스가 올라가는 기반 네트워크라는 점이 인상적이었다. EC2, ALB, Auto Scaling Group 등 다양한 서비스가 결국 하나의 VPC 위에서 서로 연결되어 동작한다는 구조를 직접 확인할 수 있었다.
또한 ALB는 트래픽을 직접 처리하는 것이 아니라 Target Group으로 요청을 전달하고, Target Group이 실제로 트래픽을 처리할 대상 인스턴스들을 관리한다는 흐름도 이해할 수 있었다. 초기에는 EC2 인스턴스를 Target Group에 직접 연결하는 방식으로 구성했지만 이후 Auto Scaling Group을 적용하면서 EC2를 직접 관리하기보다는 ASG가 인스턴스를 자동으로 생성하고 관리하는 구조가 훨씬 유연하고 확장성이 높다는 점을 체감할 수 있었다.
마지막으로 Terraform 디렉토리를 VPC, EC2, ALB, ASG와 같이 역할별로 나누어 관리하면 구조를 이해하기 쉽고 관리도 편해진다는 것을 느꼈다. 다만 디렉토리를 분리할 경우 서로 다른 디렉토리에서 생성된 리소스의 값을 어떻게 전달할지 고민해야 한다는 점도 함께 배울 수 있었다.
마무리
이번 실습은 처음에는 단순한 EC2 생성부터 시작했지만
최종적으로는 ALB + ASG 기반의 기본적인 웹 서비스 아키텍처까지 확장할 수 있었다.
즉 단순히 서버 한 대를 띄우는 수준이 아니라
다중 인스턴스와 로드밸런싱, 자동 인스턴스 관리까지 포함된 구조를 직접 구성해 본 셈이다.
이 구조는 AWS 실무와 SAA 시험에서도 매우 자주 등장하는 기본 패턴이기 때문에
이번 실습을 통해 네트워크-컴퓨트-로드밸런서-오토스케일링의 흐름을 한 번에 정리할 수 있었다.
본 후기는 [카카오엔터프라이즈x스나이퍼팩토리] 카카오클라우드로 배우는 AIaaS 마스터 클래스 4기(B-log) 리뷰로 작성되었습니다.
'카카오클라우드' 카테고리의 다른 글
| [스나이퍼팩토리] 카카오클라우드 AIaaS 4기 12주차 특강 - Kubernetes Engine 실습 정리 (0) | 2026.03.22 |
|---|---|
| [스나이퍼팩토리] 카카오클라우드 AIaaS 4기 11주차 - Ansible Semaphore 설치 및 플레이북 실행 (0) | 2026.03.15 |
| [스나이퍼팩토리] 카카오클라우드 AIaaS 4기 9주차– AWS ECS & Fargate 컨테이너 배포 실습 (0) | 2026.02.25 |
| [스나이퍼팩토리] 카카오클라우드 AIaaS 마스터 클래스 4기 - 8주차 EC2 & Docker 기반 웹 서버 구축 (0) | 2026.02.22 |
| [스나이퍼팩토리] 카카오클라우드 AIaaS 마스터 클래스 4기 – 7주차 오토스케일링과 k6 부하테스트 (0) | 2026.02.15 |