| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- 프로그래머스
- network
- AWS Active Directory
- AWS 아키텍처 분석
- C
- AWS 3 Tier Architecture
- terraform
- AWS
- reversing.kr
- TryHackMe
- operating system
- dreamhack
- IAM Federation
- 운영체제
- AWS IAM Role
- reversing
- programmers
- AWS 사고 사례 분석
- AWS 인프라 아키텍처
- AWS 보안 사고 사례 모음
- Amazon S3
- python
- 드림핵
- AWS 침해 사고 사례 분석
- AWS 침해사고 사례 분석
- AWS 보안 아키텍처 분석
- 침입 차단 시스템(IPS)
- 리버싱
- AWS 인프라 분석
- 네트워크
- Today
- Total
lhywk 님의 블로그
Terraform으로 AWS 리소스 생성 - VPC 본문
참고 자료: https://terraform101.inflearn.devopsart.dev/cont/vpc-intro/
Amazon VPC
Amazon VPC는 Amazon에서 제공하는 Private한 네트워크 망.
- Virtual Private Cloud(VPC) : 사용자의 AWS 계정 전용 가상 네트워크.
- 서브넷 : VPC의 IP 주소 범위.
- 라우팅 테이블 : 네트워크 트래픽을 전달할 위치를 결정하는 데 사용되는 라우팅이라는 규칙 집합.
- 인터넷 게이트웨이 : VPC의 리소스와 인터넷 간의 통신을 활성화하기 위해 VPC에 연결하는 게이트웨이.
- NAT 게이트웨이 : 네트워크 주소 변환을 통해 프라이빗 서브넷에서 인터넷 또는 기타 AWS 서비스에 연결하는 게이트웨이.
- 보안 그룹 : 인스턴스에 대한 인바운드 및 아웃바운드 트래픽을 제어하는 가상 방화벽 역할을 하는 규칙 집합.
- VPC 엔드포인트 : 인터넷 게이트웨이, NAT 디바이스, VPN 연결 또는 AWS Direct Connect 연결을 필요로 하지 않고 PrivateLink 구동 지원 AWS 서비스 및 VPC 엔드포인트 서비스에 VPC를 비공개로 연결할 수 있다. VPC의 인스턴스는 서비스의 리소스와 통신하는 데 퍼블릭 IP 주소를 필요로 하지 않는다. VPC와 기타 서비스 간의 트래픽은 Amazon 네트워크를 벗어나지 않는다.
VPC 기본 생성
Terraform을 통해서 VPC를 생성한다.
VPC를 생성할 때는 aws_vpc 리소스를 사용하면 되고 필수적으로 필요한 설정은 cidr_block이다.
main.tf

Provider (공급자) 설정
테라폼이 어떤 클라우드 서비스와 통신할지 결정하는 부분이다.
- provider "aws": AWS 클라우드를 사용하겠다는 선언이다.
- region = "ap-northeast-2": 리소스를 생성할 위치를 설정한다. ap-northeast-2는 서울 리전을 뜻한다.
Resource (리소스) 정의
실제로 어떤 인프라를 만들지 정의하는 부분이다.
- resource "aws_vpc": 생성할 리소스의 타입이 VPC임을 명시한다.
- "main": 테라폼 코드 안에서 이 리소스를 지칭하는 별명이다. 나중에 다른 리소스를 만들 때 이 VPC를 참조하기 위해 사용한다.
- cidr_block = "10.0.0.0/16": VPC가 사용할 IP 주소 범위를 지정한다. 10.0.0.0부터 10.0.255.255까지의 사설 IP 대역을 가지게 된다.
- tags: AWS 관리 콘솔에서 리소스를 쉽게 식별하기 위해 붙이는 꼬리표다. 여기서는 VPC의 이름을 "terraform-101"로 지정한다.
Terraform plan
생성되는 리소스를 확인한다.

Terraform apply
리소스를 생성한다.


Subnet 생성
Subnet은 특정 Availability Zone에 속한 네트워크 그룹으로 VPC 내에서도 나눠진 독립적인 네트워크 구역이다.
Subnet을 생성할 때는 aws_subnet이라는 리소스를 사용하면 된다.
필요한 설정은 해당 서브넷을 연결할 VPC의 ID와 해당 서브넷의 cidr block이다.
서브넷의 cidr block은 반드시 VPC의 cidr block 내에 속해 있어야 한다.

- resource "aws_subnet" "first_subnet":
- VPC 내의 실제 서버가 들어갈 수 있는 하위 네트워크 공간(Subnet)을 정의한다.
- vpc_id = aws_vpc.main.id: 아까 만든 main VPC 안에 이 서브넷을 넣겠다는 의미이다.
- cidr_block:
- 첫 번째는 10.0.1.0/24, 두 번째는 10.0.2.0/24를 사용했다.
- VPC(10.0.0.0/16)의 큰 범위를 작은 단위로 쪼개서 관리하는 것.
- availability_zone:
- ap-northeast-2a와 2b로 나눴다. 이는 서울 리전의 서로 다른 AZ에 자원을 분산 배치하여, 한쪽 센터에 장애가 나도 서비스가 유지되도록 하는 고가용성(High Availability) 설계다.
Internet Gateway 생성
인터넷 게이트웨이는 VPC 내부와 외부 인터넷이 통신하기 위한 게이트웨이 중 하나이다.
인터넷 게이트웨이가 연결된 서브넷은 public 서브넷이라고 한다.

- resource "aws_internet_gateway" "igw":
- AWS의 인터넷 게이트웨이 리소스를 생성하겠다는 선언. igw는 테라폼 안에서 이 문을 부르는 이름.
- vpc_id = aws_vpc.main.id:
- 어떤 VPC에 설치할 것인지 지정한다.
- 아까 생성했던 main VPC의 ID를 연결.
- tags = { Name = "main" }:
- AWS 콘솔에서 "main"이라는 이름을 붙여준다.
이쯤에서 terraform plan



우리가 설정한 리소스인 인터넷 게이트웨이와 두 개의 서브넷이 추가된다.
terraform apply을 적용해 보고 콘솔을 확인해 본다.

101 subnet-1과 2가 각각 생성된다.

main이라는 이름의 인터넷 게이트웨이도 생성된다.
Route Table 생성
Route Table은 트래픽을 규칙에 맞게 전달해 주기 위해 필요한 인종의 테이블이다.
Route Table은 여러 서브넷에서 동시에 사용할 수 있으며 이렇게 연결하는 작업은 Association이라고 한다.
Route Table은 aws_route_table 리소스를 생성하면 되고 서브넷과 연결할 때는 aws_route_table_ssociation을 사용하면 된다.

aws_route_table (라우팅 테이블)
- vpc_id = aws_vpc.main.id: 이정표를 main VPC 전용으로 만들겠다는 의미
- 현재 이 코드 블록 내부에는 구체적인 경로(Route)가 정의되어 있지 않다. 기본적으로는 VPC 내부끼리만 통신할 수 있는 '로컬 라우팅'만 포함된 상태다.
aws_route_table_association (라우팅 테이블 연결)
위에서 만든 '이정표'를 실제 서브넷에 적용하는 과정
- subnet_id: 연결할 대상 서브넷(첫 번째, 두 번째 서브넷)을 지정한다.
- route_table_id: 방금 만든 route_table을 사용하도록 설정한다.
terraform plan

설정한 라우팅 테이블이 main으로 추가되고 첫 번째 서브넷과 두 번째 서브넷이 라우팅 테이블과 연결된다.

apply 이후 main이라는 라우팅 테이블이 설정되고 두 개의 서브넷과 연결되었다.
Private Subnet 및 NAT 구성
Private 서브넷은 Public 서브넷과 다르게 인터넷과 통신이 되지 않는 IP 대역이다.
즉, 인터넷 게이트웨이와 연결이 되어 있지 않은 곳이라서 외부에서 Private 서브넷으로 접근하는 것은 불가능하다.
생성하는 방법은 위에서 서브넷 생성했던 방식과 동일하다.
같은 코드이지만 인터넷 게이트웨이와 연결되어 있느냐 여부에 따라 속성이 달라진다는 점을 기억해야 한다.

- 리소스 정의 (aws_subnet):
- first_private_subnet, second_private_subnet: 테라폼 안에서 이 서브넷들을 구분할 논리적 이름.
- IP 대역 (cidr_block):
- 각각 10.0.3.0/24와 10.0.4.0/24를 사용했다. 앞서 만든 서브넷들(10.0.1.0, 10.0.2.0)과 겹치지 않게 순차적으로 할당한다.
- 가용 영역 분산 (availability_zone):
- ap-northeast-2a와 2b에 하나씩 배치했다. 한쪽 데이터 센터에 문제가 생겨도 서비스가 죽지 않도록 하는 고가용성(HA) 설계.
- 태그 (tags):
- 이름에 "private"를 명시해서 나중에 AWS 콘솔에서 봤을 때 용도를 바로 알 수 있게 했다.
terraform plan

2개의 프라이빗 서브넷을 추가한다.

2개의 프라이빗 서브넷이 정상적으로 생성된다.
Nat Gateway는 Private 서브넷에서 외부와 통신하기 위해서 필요한 게이트웨이이다.
외부에서 Private 서브넷으로는 접근이 불가능하고 사실 외부에서 접근하지 말아야 하는 서비스는 Private 서브넷에 들어가는 것이 좋다.
하지만 Private 서브넷에 있는 서버에서는 외부와 통신해야 하는 경우가 발생한다.
예를 들면 필요한 패키지를 다운로드받거나 써드파티 API를 사용하는 경우에는 반드시 인터넷으로 요청을 보내야 한다.
이럴 때 필요한 것이 바로 NAT Gateway이다.
Nat Gateway는 반드시 고정 IP를 가지고 있어야 하고 private subnet에서 보내는 모든 요청이 외부로 나갈 때는 내부 IP가 아닌 고정 IP를 사용한다.
예를 들어 고정 IP가 13.1.1.1이라면 외부로 나가는 모든 요청은 13.1.1.1에서 보낸 요청으로 표시된다.
ex) 10.0.4.1(내부 IP) -> 13.1.1.1(고정 IP) -> (외부 IP)
따라서 Nat Gateway를 만들 때는 AWS Elastic IP도 함께 생성해야 한다.
Nat Gateway는 Public 서브넷에 위치하지만 연결은 private 서브넷과 한다.
Public 서브넷에 위치하는 이유는 Nat Gateway 자체는 인터넷과 통신이 되어야 하기 때문이다.

Elastic IP (aws_eip)
- domain = "vpc": 이 IP가 VPC 환경에서 사용될 고정 공인 IP(Elastic IP)임을 명시한다.
- lifecycle { create_before_destroy = true }: 기존 IP를 삭제하기 전에 새로운 IP를 먼저 생성하여 인프라 중단 시간을 최소화한다.
NAT Gateway (aws_nat_gateway)
- allocation_id: 위에서 만든 고정 IP(EIP)를 NAT 게이트웨이에 할당한다. NAT 게이트웨이는 외부와 통신할 때 이 IP를 대표로 사용한다.
- subnet_id: NAT 게이트웨이는 반드시 퍼블릭 서브넷(Internet Gateway와 연결된 곳)에 위치해야 한다. first_subnet과 second_subnet에 연결한다.

프라이빗용 라우팅 테이블 생성
resource "aws_route_table" "route_table_private_1" { ... }
resource "aws_route_table" "route_table_private_2" { ... }
- 퍼블릭 서브넷과는 별개로 프라이빗 서브넷들만 사용할 전용 Route Table를 두 개 만든다.
서브넷과 라우팅 테이블 연결
resource "aws_route_table_association" "route_table_association_private_1" { ... }
- 아까 생성한 프라이빗 서브넷들에 위에서 만든 프라이빗 전용 테이블을 각각 연결한다.
- first_private_subnet은 1번 테이블을, second_private_subnet은 2번 테이블을 쓰게 된다.
NAT 게이트웨이 경로 추가
resource "aws_route" "private_nat_1" {
route_table_id = aws_route_table.route_table_private_1.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat_gateway_1.id
}
- 외부 인터넷(0.0.0.0/0)으로 가려면 아까 만든 NAT 게이트웨이로 가라는 구체적인 길 안내를 추가한다.
- 이제 프라이빗 서브넷 내부의 서버들은 외부에서 직접 접속할 수는 없지만 업데이트 등을 위해 인터넷에 나갈 때는 이 NAT 게이트웨이를 타고 나갈 수 있게 된다.
terraform plan






| 리소스 종류 | 수량 | 역할 |
| aws_eip | 2 | NAT 게이트웨이가 외부와 통신할 때 사용할 고정 공인 IP |
| aws_nat_gateway | 2 | 프라이빗 서브넷의 트래픽을 인터넷으로 전달하는 중계기 |
| aws_route_table | 2 | 프라이빗 서브넷 전용 이정표(라우팅 테이블) |
| aws_route_table_association | 2 | 프라이빗 서브넷과 위 이정표를 연결 |
| aws_route | 2 | "인터넷으로 갈 때는 NAT GW를 타라"는 상세 경로 규칙 |

2개의 nat gateway가 생성된다.

2개의 라우팅 테이블이 생성된다.


첫 번째 프라이빗 서브넷은 라우팅 테이블을 타 NAT gateway 1로 연결되고
두 번째 프라이빗 서브넷은 라우팅 테이블을 타 NAT gateway 2로 연결된다.

마지막으로 main 라우팅 테이블에서 인터넷 게이트웨이로 연결을 설정한다.
- resource "aws_route" "public_internet_access":
- 라우팅 테이블 내에 개별 경로(Route)를 생성하는 리소스다. public_internet_access는 테라폼 내에서 이 경로를 식별하기 위한 이름이다.
- route_table_id = aws_route_table.route_table.id:
- 이 경로 규칙을 어느 테이블에 적용할지 지정한다. 앞서 만들었던 퍼블릭용 라우팅 테이블의 ID를 참조한다.
- destination_cidr_block = "0.0.0.0/0":
- 목적지 주소를 의미한다 VPC 내부 대역을 제외한 모든 외부 트래픽을 처리하겠다는 의미다.
- gateway_id = aws_internet_gateway.igw.id:
- 트래픽을 보낼 목적지(Target)다. 아까 만든 인터넷 게이트웨이(IGW)로 트래픽을 던지도록 설정한다.

외부 인터넷과 연결할 수 있게 된다.
모든 실습을 마쳤다면 terraform destroy 명령으로 리소스를 삭제한다.
'AWS' 카테고리의 다른 글
| Terraform Advanced (0) | 2026.03.10 |
|---|---|
| Terraform으로 AWS 리소스 생성 - AWS IAM (1) | 2026.03.10 |
| Terraform으로 AWS 리소스 생성 - S3 (0) | 2026.03.10 |
| Amazon S3 (0) | 2026.03.10 |
| Terraform 알아보기 (0) | 2026.03.10 |