PF-01 · AWS · IaC
AWS 멀티 리전 Terraform
리전별 locals 맵 하나를 고치면 16개 AWS 리전에 같은 인프라가 만들어지는 Terraform 모듈 모음입니다.
- 역할
- 설계 · 구현
- 기간
- 개인 프로젝트 · 2026.11 공개
- CSP
- AWS
- 규모
- 16개 리전 · 모듈 24종 · 예제 3개
- 핵심 기술
- Terraform · AWS · EKS · CloudWatch · AWS Chatbot
- 16
- 리전별 provider 별칭
- 24
- 공개한 Terraform 모듈
- 3
- 검증한 예제
한눈에 보기
문제
같은 형태의 리소스를 여러 리전에 만들어야 했습니다. 리전이 늘수록 복사한 코드가 늘고 리전마다 설정이 달라질 위험이 커졌습니다.
접근
리전별 locals 맵에 원하는 상태를 선언하고 module과 for_each로 일괄 생성합니다. provider는 리전마다 별칭을 두고 같은 role을 assume합니다. for_each가 provider를 동적으로 고를 수 없어 리전별 module 블록은 반복합니다.
결과
변경은 맵 항목 하나로 끝나고, 키가 고정이라 순서를 바꿔도 리소스가 다시 생성되지 않습니다. 모듈 24종에 암호화, IMDSv2, 비공개 S3 같은 기본값을 넣었고 EKS와 알림 예제까지 3종을 공개했습니다.
자세히 보기
리전별 locals 맵
이 코드가 하는 일: 리전별로 원하는 네트워크 상태를 맵으로 선언합니다. 바깥 키는 리전(seoul), 그 안의 키는 VPC 이름(demo-seoul)이고, 값에는 VPC의 CIDR과 서브넷 목록(이름, CIDR, 가용 영역, 공인 IP 자동 할당 여부)이 들어갑니다. 리전이나 VPC를 늘릴 때는 이 맵에 항목 하나를 더하면 되고, 리소스를 만드는 코드는 바뀌지 않습니다.
# Declare the wanted state per region. Adding a region or a VPC is one more map entry.
locals {
networks = {
seoul = {
demo-seoul = {
cidr_block = "10.0.0.0/16"
subnets = [
{ subnet_name = "demo-seoul-a", subnet_cidr = "10.0.1.0/24", ipv6_cidr_block = null, availability_zone = "ap-northeast-2a", autoassign_public = "false", tags = {} },
{ subnet_name = "demo-seoul-c", subnet_cidr = "10.0.2.0/24", ipv6_cidr_block = null, availability_zone = "ap-northeast-2c", autoassign_public = "false", tags = {} },
]
}
}
맵을 읽는 module과 for_each
이 코드가 하는 일: 서울 리전 맵(local.networks.seoul)의 항목마다 VPC 모듈을 한 번씩 실행합니다. 맵의 키(each.key)가 VPC 이름이 되고, 값(each.value)에서 CIDR과 서브넷 목록을 꺼내 모듈에 넘깁니다. providers로 서울 리전 별칭(aws.seoul)을 연결하므로 이 블록이 만드는 리소스는 모두 서울 리전에 생기고, 키가 리소스의 주소가 되어 맵의 순서를 바꿔도 기존 VPC가 다시 만들어지지 않습니다.
module "seoul_vpc" {
source = "../../modules/vpc"
for_each = local.networks.seoul
providers = { aws = aws.seoul }
vpc_name = each.key
cidr_block = each.value.cidr_block
instance_tenancy = "default"
use_ipv6_cidr_block = false
subnets = each.value.subnets
}배운 점
반복을 줄이는 것만큼 리소스를 가리키는 키를 고정하는 것이 중요했습니다. count는 목록의 위치로 리소스를 구분해 항목을 끼워 넣거나 순서를 바꾸면 뒤쪽 리소스가 다시 만들어질 수 있지만, for_each는 맵의 키로 구분하므로 순서와 상관없이 같은 리소스를 가리킵니다. provider를 for_each로 고를 수 없다는 Terraform의 제약은 억지로 감추지 않고 리전별 module 블록을 반복해 드러냈고, 그 편이 읽고 고치기 쉬웠습니다. 이후로는 같은 구조를 여러 곳에 만들 때 데이터(맵)와 코드(모듈)를 먼저 나누고, 변경이 맵 항목 하나로 끝나는지를 설계의 기준으로 삼습니다.