Terraform

Terraform 개념 지도

State 내부 동작부터 팀 협업, 환경 분리, 시크릿 관리, State 수술, import/moved까지 — pposiraegi 실제 코드 기반 9개 개념
기반 Terraform 1.5+ AWS S3 DynamoDB KMS SSM IAM IRSA 프로젝트 pposiraegi-ecommerce pposiraegi-eks
이 문서를 읽는 방법 — 코드보다 "왜 이렇게 동작하는가"를 먼저 본다
1. State가 전부다
모든 Terraform 문제는 State와 실제 AWS의 불일치에서 출발한다. 에러를 보면 State를 먼저 의심.
2. 의존성 방향
리소스를 참조하면 자동으로 의존성이 생긴다. DAG가 실행 순서를 결정하고 병렬화 범위를 만든다.
3. 팀 충돌 원인
EntityAlreadyExistsException, zombie lock — 모두 State에 없는 리소스가 AWS에 있는 상황이다.
4. 시크릿 원칙
값이 코드/이미지/로그 어디에도 없어야 한다. SSM ARN만 노출하고 값은 런타임에만 존재.
01 State
Backend기초
S3 + DynamoDB — 원격 State의 전부
로컬 tfstate의 한계와 원격 backend가 해결하는 것들
핵심 기초 S3 state 저장 DynamoDB 분산 Lock
Terraform이 리소스 상태를 어디에 어떻게 저장하는가. DynamoDB Lock이 동시 apply를 막는 메커니즘, partial apply 후 State가 어떻게 남는가, zombie lock 판단 기준까지.
State를 이해했으면 → 코드가 실제로 어떤 순서로 실행되는지
06 Plan
Apply내부 동작
Plan → Apply 내부 5단계 메커니즘
init / refresh / DAG / apply / state write — 각 단계에서 무슨 일이 일어나는가
핵심 동작 DAG 병렬 실행 plan -out 결정적 apply pposiraegi 실행 파동
terraform plan이 단순 문법 검사가 아닌 이유. AWS API를 호출해 refresh하고 의존성 그래프를 그린 뒤 diff를 계산한다. pposiraegi의 7개 실행 파동(Wave), -out 플래그의 결정적 apply, .terraform.lock.hcl git commit 필수 이유.
실행 순서를 이해했으면 → 그 순서를 만드는 모듈 구조
04 Module
Structure구조 설계
모듈 의존성 — input/output이 실행 순서를 만든다
networking → eks → karpenter → security → storage 의 실제 이유
구조 설계 module input/output pposiraegi 5개 모듈 for_each 패턴
모듈 참조가 곧 의존성이다. pposiraegi-ecommerce의 5개 모듈이 왜 그 순서로 실행되는지, 각 모듈의 input/output이 어떻게 연결되는지. for_each로 4개 서비스를 반복하는 패턴, provider alias로 us-east-1 ACM을 만드는 이유.
혼자 구조를 잡았다면 → 팀이 함께 쓸 때 생기는 문제들
02
03
팀 협업
장애 대응2인 운영
두 사람이 Terraform을 함께 쓸 때
Lock 충돌, zombie lock, state drift, EntityAlreadyExistsException 복구까지
팀 협업 EntityAlreadyExists zombie lock 판단 import {} 블록
jihoon의 EKS Access Entry가 이미 AWS에 존재하는데 State에 없어서 apply가 터진 실제 사례. DynamoDB Lock이 정상 충돌과 좀비 Lock을 어떻게 구분하는가. terraform import {}로 복구하는 전체 흐름.
협업 패턴을 잡았다면 → dev/prod 환경을 어떻게 분리하는가
05 환경
분리전략
workspace vs 디렉토리 — 환경 분리 방법의 두 갈래
같은 S3 버킷에 key만 다른가, 디렉토리 자체를 분리하는가
환경 전략 terraform workspace environments/dev 구조 pposiraegi-eks 패턴
workspace는 State key 경로만 바꾼다. 실수로 prod에 apply될 위험이 있다. pposiraegi-eks는 environments/dev/ 디렉토리 방식으로 완전 격리. 언제 workspace를, 언제 디렉토리를 써야 하는지 판단 기준.
구조와 협업이 완성됐다면 → 코드에 절대 들어가면 안 되는 것들
07 시크릿
관리보안
민감정보가 코드 어디에도 없어야 하는 이유
tfvars 평문 → gitignore → TF_VAR_ → SSM → SOPS 5단계 위험도 계층
보안 tfvars 평문 절대 금지 SSM SecureString sensitive() 함수
pposiraegi가 jwt_secret과 db_password를 SSM SecureString으로 저장하고 ARN만 output으로 노출하는 실제 패턴. sensitive = true 마킹이 plan 출력은 가리지만 State 파일엔 평문으로 남는 이유와 S3 SSE-KMS 필요성. git 실수 커밋 방지 3중 방어선.
보안까지 잡았다면 → 이미 존재하는 State를 외과적으로 조작해야 할 때
08 State
수술심화
State 수술 명령어 — mv · rm · force-unlock
코드 리팩토링 없이 State만 바꿔야 하는 상황과 안전 절차
State 조작 force-unlock state mv / rm state pull/push
terraform plan/apply 없이 State 파일을 직접 수술하는 명령어들. 모듈 이동, 언트랙, stuck lock 해제, State 복구까지. 각 명령의 위험도와 취소 불가 지점, pposiraegi 실전 4가지 시나리오.
State 수술을 알았다면 → Terraform 밖의 리소스를 코드로 흡수하는 법
09 import
moved선언형
import {} / moved {} — 파괴 없이 재편성
기존 AWS 리소스를 코드로 흡수하고, 리팩토링을 destroy 없이 처리하는 선언형 방법
선언형 이관 import {} TF 1.5+ moved {} 코드 리팩토링 for_each 키 rename
CLI import의 한계 — 개인 로컬에서만 동작, 재현 불가. import {} 블록은 git에 기록되고 plan에서 미리보기 가능. moved {} 는 rename/모듈 이동을 AWS 리소스 변경 없이 처리. pposiraegi ECR for_each 키 rename 실전 패턴.