이 글은 Velog에서 이전한 글입니다. Velog 원문 보기
Terraform으로 프로젝트 인프라를 구성하면서 가장 먼저 부딪히는 문제는 tfstate를 어디에 저장할 것인가입니다.
초기에는 로컬에서 tfstate를 관리할 수 있지만, 프로젝트가 커지거나 환경이 복잡해질수록 로컬 관리 방식은 여러 문제를 일으킵니다.
이번 글에서는 로컬 tfstate 대신 AWS S3 Backend + S3 Native State Locking을 선택한 이유와,
과거에 널리 사용되던 S3 + DynamoDB 조합에서 벗어나게 된 배경을 함께 정리합니다.
1. 요구사항 정리
Terraform 상태 파일(tfstate)은 인프라의 모든 리소스 상태를 포함하는 매우 중요한 파일입니다.
따라서 다음 요구사항을 충족해야 합니다.
기능적 요구사항
- tfstate를 안전하게 저장할 것
- 팀 구성이나 계정 이전 시에도 상태를 공유할 수 있을 것
- 수정 충돌을 방지하고 원자성 있게 상태를 관리할 것
비기능적 요구사항
- 비용을 가능한 최소화할 것 (프리티어 내에서 동작하면 더욱 좋음)
- 관리 오버헤드를 낮출 것
- Terraform Cloud 같은 외부 SaaS에 의존하지 않을 것
(AWS 계정 변경 가능성 고려)
제약 조건
- 여러 환경(sandbox, dev, prod)을 분리해야 함
- 인프라 규모가 앞으로 증가할 가능성이 높음
- Git으로 tfstate를 관리하는 방식은 금지(보안·충돌 문제)
2. tfstate 저장 전략 후보 비교
Terraform Backend 구성 방식은 다음과 같이 나눌 수 있습니다.
2-1. 로컬 파일(tfstate) 저장
| 장점 | 단점 |
|---|---|
| 가장 단순 | 협업 불가 |
| 설정 필요 없음 | 파일 충돌·동시 작업 불가 |
| 비용 없음 | 백업·버전 관리 직접 필요 |
| 개인 프로젝트 초기에는 편함 | 계정·PC 변경 시 상태 이관 필요 |
결론
로컬 파일 방식은 단일 개발자가 실험하는 단계까지만 적합합니다.
멀티 환경·멀티 계정·자동화를 고려한다면 유지가 불가능한 방식입니다.
2-2. AWS S3 Backend + S3 Native State Locking (현재 선택)
과거에는 S3에 tfstate를 저장하고, DynamoDB를 Lock 관리 용도로 함께 사용하는 방식이 사실상 표준이었습니다.
하지만 최근 HashiCorp 공식 문서에서는 S3 자체의 Native Locking(use_lockfile) 사용을 권장하고 있습니다.
참고 문서
https://developer.hashicorp.com/terraform/language/backend/s3#example-configuration
State Locking 변경 사항 요약
- S3 Backend의 State Locking은 옵션 기능(opt-in)
- Locking은 S3 Native 방식 또는 DynamoDB 방식 중 선택 가능
- DynamoDB 기반 Locking은 deprecated 상태이며,
향후 minor version에서 제거될 예정 - 기존 Terraform 버전과의 호환을 위해
S3 Locking과 DynamoDB Locking을 동시에 설정하는 것은 가능
즉, 신규 프로젝트에서는 DynamoDB에 의존할 이유가 사라졌습니다.
구성 요소
| 구성 요소 | 역할 |
|---|---|
| S3 | tfstate 저장 + Versioning + Native Lock |
| Lockfile | S3 객체 기반 Lock 관리 |
장점
- DynamoDB 제거 → 구성 단순화
- Lock 관리용 리소스 감소 → 관리 포인트 축소
- S3 단일 Backend로 상태·Lock 모두 처리
- Terraform 공식 문서 기준 최신 권장 방식
- GitHub Actions 등 CI 환경과 동일하게 동작
- 프리티어 내에서 사실상 무료
단점
- Terraform 1.5+ 이상 권장
- S3 Lockfile 방식에 대한 정보가 아직 상대적으로 적음
3. Terraform Cloud (Remote Backend)
| 장점 | 단점 |
|---|---|
| UI 제공, 상태 관리 간편 | Free Tier 제한 |
| 자동 Lock·버전 관리 | 외부 서비스 의존 |
| 팀 협업 최적화 | 비용 증가 가능 |
| VCS 연동 쉬움 | AWS 계정 이전에 취약 |
배제 이유
- tfstate 내부에 기존 AWS 계정 리소스 ID가 포함됨
- 계정 변경 시 state migration 난이도 높음
- SaaS 의존성 증가
- 장기 비용 불확실
4. Git 저장 방식 (비권장)
| 장점 | 단점 |
|---|---|
| 백업 쉬움 | 보안 위험 |
| 버전 관리 가능 | Lock 불가 |
| 단순함 | 상태 충돌 시 인프라 손상 |
Terraform 공식 문서에서도 강력히 비권장하는 방식입니다.
5. S3 Native Locking Backend 구성 개요
환경별로 S3 Bucket을 분리해 구성했습니다.
예:
sandbox-tfstate-<account_id>dev-tfstate-<account_id>prod-tfstate-<account_id>
적용 요소
- S3 Versioning 활성화 → 상태 변경 이력 보존
- SSE 암호화(AES256)
- Public Access Block 전면 차단
use_lockfile = true로 S3 Native Lock 사용- DynamoDB 리소스 제거
이로써 Backend 구성은 S3 단일 리소스로 완결됩니다.
6. 왜 S3 Native Locking을 선택했는가?
- Terraform 공식 문서 기준 최신 권장 방식
- DynamoDB 의존성 제거 → 구조 단순화
- Lock·상태 관리 일원화
- 프리티어 기반으로 비용 사실상 0원
- 멀티 환경·자동화 환경에서 안정적 동작
- AWS 계정 이전 시 Backend 재구성 용이
특히 본 프로젝트는
- 프리티어 만료 시 계정 변경 가능성 존재
- 여러 환경(sandbox/dev/prod) 운영
- GitHub Actions 기반 자동화 필요
이라는 특성을 가지므로,
S3 Native Locking Backend가 가장 합리적인 선택이었습니다.
비용 분석
S3 비용
tfstate는 수십 KB 수준의 파일이며, Versioning을 포함해도 사용량이 극히 적습니다.
| 항목 | 예상 수치 | 비용 |
|---|---|---|
| tfstate 50KB | 0.00005GB | 0원 |
| Versioning 200버전 | 약 10MB | 0원 |
| PUT/GET 월 수백 회 | 매우 적음 | 0원 |
결론: 월 0~1원 이하
DynamoDB 비용
- 사용하지 않음 (완전 제거)
최종 비용
| 서비스 | 월 비용 |
|---|---|
| S3 | 0 ~ 1원 이하 |
| DynamoDB | 0원 |
| 총합 | 0원(프리티어 기준) |
결론
Terraform Backend는 단순한 설정이 아니라,
인프라 안정성과 협업 생산성을 좌우하는 핵심 요소입니다.
이번 선택을 통해 다음 목표를 달성했습니다.
- 상태 파일 중앙화
- 충돌 없는 Terraform 실행
- 관리 리소스 최소화
- 비용 사실상 0원
- Terraform 공식 권장 방향에 부합
과거에는 S3 + DynamoDB 조합이 사실상 표준이었지만,
현재 기준에서는 S3 Native Locking이 더 단순하고, 더 미래지향적인 선택입니다.
신규 Terraform 프로젝트라면
DynamoDB 없이 S3 Backend 단독 구성을 우선 고려하는 것이 합리적입니다.
'Project > YAPP 27기' 카테고리의 다른 글
| [트러블슈팅] JPA 다중 Fetch Join과 List 사용 시 발생하는 데이터 중복 (Cartesian Product) (0) | 2026.08.04 |
|---|---|
| ECS(EC2) 환경에서 Grafana Cloud로 모니터링 구축하기 (Prometheus + Loki) (0) | 2026.08.04 |
| Terraform으로 구축한 초기 서비스 인프라: 비용 최적화를 위한 단일 AZ 아키텍처 설계 과정 (0) | 2026.08.03 |