목차
로컬 tfstate 파일, 언제까지 쓸 건가요?
Terraform을 처음 배울 때 저도 그냥 로컬에 terraform.tfstate 파일 두고 썼거든요. 혼자 쓸 때는 문제없었는데, 팀원이 생기고 나서 진짜 지옥이 시작됐습니다. 누군가 apply 해놓고 상태 파일 커밋을 깜빡한 거예요. 그 다음 날 제가 apply 했더니... 리소스 중복 생성 오류가 펑펑 터졌습니다. 😅
그때부터 Terraform 원격 상태 관리를 제대로 공부하기 시작했어요. S3, GCS, Azure Blob — 클라우드별로 백엔드 설정 방법이 다 다르거든요. 오늘은 실제 현업에서 직접 써본 경험을 바탕으로, 세 가지 백엔드를 한 번에 정리해드리겠습니다.
▲ Terraform 원격 백엔드 구성 개요 — 여러 팀원이 동일한 원격 상태 파일을 공유하며 협업하는 구조입니다.
Terraform 상태(State)란 뭔가요? — 개념부터 잡고 가기
쉽게 말해서, Terraform은 자기가 만든 인프라를 상태 파일(state file)에 기록해둡니다. 다음에 plan이나 apply를 실행할 때 "지금 실제로 뭐가 있는지"를 이 파일 보고 판단하는 거예요. 일종의 인프라 장부 같은 거죠.
기본값은 로컬 파일(terraform.tfstate)인데, 여기서 문제가 생깁니다.
- 팀원끼리 상태 파일이 달라지는 상태 불일치(State Drift) 발생
- 동시에 apply하면 상태 파일이 깨지는 동시성 문제
- 상태 파일에 민감한 정보(비밀번호, 키 등)가 포함될 수 있는 보안 문제
- 로컬 파일 분실 시 인프라 관리 불가능해지는 복구 불가 리스크
이 모든 걸 해결해주는 게 바로 원격 백엔드(Remote Backend)입니다. 상태 파일을 클라우드 스토리지에 저장하고, 잠금(Lock) 메커니즘으로 동시 접근을 막는 방식이에요.
백엔드별 잠금 메커니즘 비교
| 백엔드 | 상태 저장소 | 상태 잠금 | 암호화 | 주요 클라우드 |
|---|---|---|---|---|
| S3 백엔드 | AWS S3 | DynamoDB 테이블 | SSE-S3 / SSE-KMS | AWS |
| GCS 백엔드 | Google Cloud Storage | GCS 내장 | Google 관리 키 / CMEK | GCP |
| Azure Blob 백엔드 | Azure Blob Storage | Blob 리스(Lease) | Azure Storage 암호화 | Azure |
GCS는 별도 잠금 인프라 없이 내장 기능으로 처리해줘서 가장 설정이 간단하더라고요. S3는 DynamoDB를 따로 만들어야 해서 초반에는 좀 번거롭긴 한데, 한 번 설정하면 정말 탄탄합니다.
AWS S3 백엔드 설정 — Terraform 원격 상태 관리 실전 가이드
AWS를 메인으로 쓰신다면 S3 백엔드가 가장 표준적인 선택입니다. 저도 현업에서 가장 많이 써본 조합이고, 안정성도 검증된 방식이거든요.
1단계: S3 버킷과 DynamoDB 테이블 생성
먼저 상태 파일을 저장할 S3 버킷과 잠금용 DynamoDB 테이블을 만들어야 합니다. 이걸 직접 Terraform으로 만들어도 되는데, 닭이 먼저냐 달걀이 먼저냐 문제가 생기거든요. 저는 보통 AWS CLI로 먼저 만듭니다.
# S3 버킷 생성 (버전 관리 활성화 필수!)
aws s3api create-bucket \
--bucket my-terraform-state-prod \
--region ap-northeast-2 \
--create-bucket-configuration LocationConstraint=ap-northeast-2
# 버전 관리 활성화 — 상태 파일 롤백을 위해 반드시 켜세요
aws s3api put-bucket-versioning \
--bucket my-terraform-state-prod \
--versioning-configuration Status=Enabled
# 퍼블릭 액세스 차단 — 보안상 필수
aws s3api put-public-access-block \
--bucket my-terraform-state-prod \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
# DynamoDB 테이블 생성 (LockID가 파티션 키여야 합니다)
aws dynamodb create-table \
--table-name terraform-state-lock \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST \
--region ap-northeast-2
2단계: backend.tf 설정 파일 작성
# backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state-prod"
key = "prod/ap-northeast-2/vpc/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true # 서버 사이드 암호화 활성화
dynamodb_table = "terraform-state-lock" # 잠금용 DynamoDB 테이블
# KMS 키로 암호화하려면 아래 추가
# kms_key_id = "arn:aws:kms:ap-northeast-2:123456789:key/your-key-id"
}
}
💡 key 경로 설계 팁: 환경/리전/서비스명/terraform.tfstate 형태로 계층 구조를 잡으면 나중에 상태 파일이 수십 개 생겨도 관리하기 훨씬 편합니다. 저는 이 규칙 안 지켰다가 나중에 상태 파일 찾느라 정말 고생했거든요. 🤦
3단계: 백엔드 초기화
terraform init
# 기존 로컬 상태를 원격으로 마이그레이션할 때
terraform init -migrate-state
S3 백엔드용 IAM 최소 권한 정책
팀원들이 Terraform을 실행할 때 필요한 최소 권한만 부여하세요. 과도한 권한은 보안 위험이거든요.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketVersioning"
],
"Resource": "arn:aws:s3:::my-terraform-state-prod"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::my-terraform-state-prod/prod/*"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem"
],
"Resource": "arn:aws:dynamodb:ap-northeast-2:123456789012:table/terraform-state-lock"
}
]
}
⚠️ 중요: 123456789012는 여러분의 AWS 계정 ID로 바꿔야 합니다. 또한 /prod/* 경로만 허용해서 다른 환경의 상태 파일은 건드리지 못하게 제한하는 게 좋습니다.
'IT > Cloud' 카테고리의 다른 글
| [Cloud] AWS 비용 최적화: EC2, S3, RDS 절감 전략 및 Cost Explorer 활용 가이드 (1) | 2026.05.01 |
|---|---|
| [Cloud] Terraform으로 AWS/GCP/Azure 멀티 클라우드 환경 구축 가이드 (0) | 2026.04.29 |
| [Cloud] Cloudflare Workers로 서버리스 API 및 엣지 컴퓨팅 구축 가이드 (0) | 2026.04.28 |
| [Cloud] Terraform 멀티 클라우드 IaC 자동화 가이드 — AWS/GCP/Azure 통합 관리 (0) | 2026.04.21 |
| [Cloud] Terraform 멀티 클라우드 관리 가이드 - AWS/GCP/Azure 한 번에 관리하기 (0) | 2026.04.21 |
| [Cloud] Ansible Playbook 디버깅: 흔한 오류 해결 및 실전 팁 (1) | 2026.04.16 |