목차
- Terraform State, 왜 중요한가요?
- S3 백엔드로 원격 State 관리하기
- 1. S3 버킷 생성하기
- 2. Terraform 구성 파일에 S3 백엔드 설정 추가하기
- 3. `terraform init` 실행하기
- DynamoDB로 State Locking 구현하기
- 1. DynamoDB 테이블 생성하기
- 2. Terraform 구성 파일에 DynamoDB 설정 추가하기
- 3. `terraform init` 다시 실행하기
- ⚠️ 삽질 경험: 흔한 실수와 해결책
- 검증 및 결과: 이제 안심하고 협업하세요!
- 마무리하며: 더 나은 IaC 여정을 위해
안녕하세요, 13년차의 서버실 주인장입니다. 오늘은 인프라 엔지니어라면 한 번쯤은 머리를 싸매고 고민했을 주제, 바로 Terraform State 관리에 대해 이야기해보려고 합니다.
제가 처음 Terraform을 접했을 때, 로컬에 생성되는 <code>terraform.tfstate 파일이 그렇게 귀찮을 수가 없더라고요. 혼자 작업할 때는 괜찮았는데, 팀원들과 함께 프로젝트를 진행하면서부터는 '이거 큰일 나겠다!' 싶었습니다. 서로 다른 사람이 동시에 terraform apply를 실행하면 어떻게 될까요? 네, 상상만 해도 끔찍하죠. State 파일이 꼬여서 인프라가 엉망진창이 되는 대참사를 막기 위해, 오늘은 AWS S3와 DynamoDB를 활용한 Terraform State 관리 모범 사례를 완벽하게 파헤쳐 보려고 합니다. 💡
Terraform State 관리의 전체 아키텍처 다이어그램입니다. S3와 DynamoDB가 어떻게 상호작용하는지 한눈에 볼 수 있습니다.
Terraform State, 왜 중요한가요?
Terraform State(테라폼 상태 파일)는 Terraform이 관리하는 실제 인프라 자원들의 현황을 기록한 파일입니다. 쉽게 말해, "지금 내가 관리하고 있는 인프라가 어떤 모습으로 생겼는지"를 알려주는 지도 같은 거죠. 이 파일이 있어야 Terraform은 다음에 apply를 실행했을 때, 현재 인프라 상태와 새로운 설정 파일(.tf) 간의 차이점을 파악하고, 필요한 변경 사항만 적용할 수 있습니다.
만약 State 파일이 없거나, 여러 사람이 각자 다른 버전을 가지고 있다면 어떻게 될까요? Terraform은 인프라의 실제 상태를 알 수 없어서 엉뚱한 자원을 생성하거나, 심지어는 멀쩡한 자원을 삭제해버리는 불상사가 발생할 수 있습니다. 그래서 안정적인 IaC(Infrastructure as Code, 코드형 인프라) 운영을 위해서는 Terraform State 관리가 정말 중요합니다. 특히 팀 협업 환경에서는 이 State 파일을 안전하고 일관되게 관리하는 것이 핵심 중의 핵심입니다.
S3 백엔드로 원격 State 관리하기
로컬에 State 파일을 두는 것은 개인적인 실험 환경에서는 괜찮지만, 실제 프로덕션 환경이나 팀 프로젝트에서는 절대 금물입니다. 제가 예전에 홈랩에서 이것저것 테스트하다가 USB를 날려먹으면서 State 파일도 같이 날려버린 적이 있었거든요. 그때 복구하느라 며칠 밤낮을 새웠던 걸 생각하면 아직도 아찔합니다. 😨
그래서 우리는 S3 백엔드(S3 backend)를 사용해서 Terraform State 파일을 원격으로 저장할 겁니다. AWS S3는 객체 스토리지 서비스로, 높은 내구성(durability), 가용성(availability), 그리고 버전 관리(versioning) 기능을 제공해서 Terraform State를 저장하기에 아주 적합합니다. S3에 State 파일을 저장하면 팀원 누구나 안전하게 접근할 수 있거든요.
1. S3 버킷 생성하기
먼저 Terraform State 파일을 저장할 S3 버킷을 생성해야 합니다. 버킷 이름은 전역적으로 고유해야 하며, 버전 관리(Versioning)를 활성화하는 것을 강력히 권장합니다. 혹시 모를 실수로 State 파일이 변경되거나 삭제되더라도 이전 버전으로 복구할 수 있거든요. 저도 예전에 실수로 terraform destroy를 잘못 날렸다가 S3 버전 관리 덕분에 한숨 돌린 적이 있습니다.
aws s3api create-bucket \
--bucket my-terraform-state-bucket-13years-infra \
--region ap-northeast-2 \
--create-bucket-configuration LocationConstraint=ap-northeast-2
aws s3api put-bucket-versioning \
--bucket my-terraform-state-bucket-13years-infra \
--versioning-configuration Status=Enabled
콘솔에서 직접 생성하셔도 됩니다. 이때 중요한 건, "버전 관리"를 꼭 켜주세요! 그리고 필요하다면 서버 측 암호화(Server-side encryption)도 적용하는 게 좋습니다. 💡
Terraform State 저장을 위한 AWS S3 백엔드 버킷 설정 화면입니다. 버전 관리와 암호화 설정이 중요합니다.
2. Terraform 구성 파일에 S3 백엔드 설정 추가하기
이제 Terraform 프로젝트의 main.tf (또는 별도의 backend.tf) 파일에 S3 백엔드 설정을 추가합니다.
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket-13years-infra" # 위에서 생성한 S3 버킷 이름
key = "global/terraform.tfstate" # S3 버킷 내 State 파일 경로
region = "ap-northeast-2" # S3 버킷 리전
encrypt = true # State 파일 암호화 활성화
# dynamodb_table = "my-terraform-locks" # State Locking을 위해 나중에 추가 (지금은 주석 처리)
}
}
# 예시: VPC를 생성하는 리소스
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "MyVPC-ManagedByTerraform"
}
}
여기서 key는 S3 버킷 내에서 State 파일이 저장될 경로와 파일명을 지정합니다. 저는 보통 프로젝트별로 또는 환경별로 구분해서 project-name/env/terraform.tfstate 이런 식으로 관리하곤 합니다.
3. `terraform init` 실행하기
설정을 추가했다면, 이제 terraform init 명령어를 실행해야 합니다. 이 명령어가 백엔드 설정을 초기화하고, S3 버킷에 State 파일을 생성하거나 기존 파일을 연결합니다.
terraform init
성공적으로 실행되면 다음과 같은 메시지를 볼 수 있습니다.
Initializing the backend...
Successfully configured the backend "s3"! Terraform will now
persist and retrieve its state from this configuration.
... (다른 초기화 메시지) ...
Terraform has been successfully initialized!
이제 여러분의 State 파일은 안전하게 S3에 저장됩니다. ✅
DynamoDB로 State Locking 구현하기
S3 백엔드만으로는 협업 시 발생할 수 있는 문제를 완전히 해결할 수 없습니다. 바로 동시성 문제(concurrency issue)죠. 여러 사람이 동시에 terraform apply를 실행하면 어떻게 될까요? State 파일이 꼬여버리거나, 한 사람이 작업하는 동안 다른 사람이 같은 자원을 변경해서 예상치 못한 결과가 나올 수 있습니다. 제가 처음 이 문제에 부딪혔을 때, "이거 진짜 난감하네..." 싶었습니다. 😅
그래서 필요한 게 바로 State Locking(상태 잠금)입니다. Terraform은 AWS DynamoDB를 활용하여 이 State Locking을 구현할 수 있습니다. DynamoDB는 NoSQL 데이터베이스 서비스로, 높은 성능과 가용성을 제공하며, 특히 잠금 메커니즘을 구현하기에 아주 적합합니다. 한 번에 한 사람만 State 파일을 변경할 수 있도록 잠금을 걸어주는 거죠.
1. DynamoDB 테이블 생성하기
DynamoDB 테이블을 생성합니다. 이때 테이블 이름은 자유롭게 지정할 수 있지만, 파티션 키(Partition Key)는 반드시 LockID로 설정해야 합니다. 이 LockID를 기준으로 잠금 레코드가 저장되기 때문입니다.
AWS CLI를 사용한 생성 예시입니다.
aws dynamodb create-table \
--table-name my-terraform-locks \
--attribute-definitions AttributeName=LockID,AttributeType=S \
--key-schema AttributeName=LockID,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
PAY_PER_REQUEST 모드를 사용하면 사용한 만큼만 비용을 지불하므로, 트래픽이 많지 않은 State Locking 용도로는 비용 효율적입니다.
2. Terraform 구성 파일에 DynamoDB 설정 추가하기
이제 이전에 설정했던 S3 백엔드 블록에 dynamodb_table 인자를 추가합니다.
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket-13years-infra"
key = "global/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
dynamodb_table = "my-terraform-locks" # 새로 생성한 DynamoDB 테이블 이름
}
}
# ... (나머지 리소스 정의) ...
3. `terraform init` 다시 실행하기
백엔드 설정을 변경했으니, terraform init 명령어를 다시 실행해야 합니다. Terraform이 변경된 백엔드 설정을 인식하고 DynamoDB 테이블을 활용하기 시작합니다.
terraform init
이제부터 terraform apply나 terraform destroy 같은 State를 변경하는 명령어를 실행할 때, Terraform은 DynamoDB 테이블에 잠금 레코드를 생성하여 다른 사용자가 동시에 작업을 하지 못하도록 막아줍니다. 협업 환경에서 안정성을 크게 높여주는 핵심 기능이죠! 🎉
⚠️ 삽질 경험: 흔한 실수와 해결책
제가 이 설정을 하면서 겪었던 몇 가지 삽질 경험과 그 해결책을 공유해 드릴게요. 여러분은 저처럼 고생하지 마시라고요! 😅
- S3 버킷 권한 문제:
terraform init이나apply시 "Access Denied" 오류가 발생하면, Terraform을 실행하는 IAM 사용자 또는 역할에 S3 버킷에 대한s3:GetObject,s3:PutObject,s3:ListBucket등의 권한이 제대로 부여되었는지 확인해야 합니다. 특히 S3 버킷 정책(Bucket Policy)이 설정되어 있다면 더욱 꼼꼼히 봐야 합니다. - DynamoDB 테이블 이름 오타 또는 권한 부족: DynamoDB 테이블 이름을
backend "s3"블록에 잘못 적거나, 테이블에 대한dynamodb:GetItem,dynamodb:PutItem,dynamodb:DeleteItem권한이 없으면 잠금 오류가 발생합니다. 반드시LockID파티션 키로 테이블이 생성되었는지, 그리고 IAM 권한이 충분한지 확인하세요. - `terraform init` 재실행 누락: 백엔드 설정을 변경하고
terraform init을 다시 실행하지 않아서 변경사항이 적용되지 않는 경우가 많습니다. 저도 자주 까먹어서 "분명히 설정했는데 왜 안 되지?" 하고 한참 헤맸던 적이 있습니다. 🤦♂️ 백엔드 설정이 바뀌면 무조건terraform init! 기억하세요. - S3 버전 관리 미활성화: 실수로
terraform state rm같은 명령어를 잘못 실행해서 State 파일이 삭제되었을 때, S3 버전 관리가 활성화되어 있다면 이전 버전으로 복구할 수 있습니다. 이거 정말 생명줄 같은 기능이니 꼭 활성화하세요!
이런 작은 실수가 큰 문제로 이어질 수 있으니, 항상 주의 깊게 확인하는 습관을 들이는 것이 중요합니다.
Terraform State 관리 모범 사례를 요약한 인포그래픽입니다. 핵심 원칙들을 한눈에 파악할 수 있습니다.
검증 및 결과: 이제 안심하고 협업하세요!
모든 설정이 완료되었다면, 이제 팀원들과 함께 걱정 없이 Terraform을 사용할 수 있습니다. State Locking이 제대로 작동하는지 확인하는 가장 좋은 방법은, 두 명의 사용자가 동시에 terraform apply를 실행해보는 것입니다. 한 명의 작업이 진행되는 동안 다른 한 명은 잠금 오류 메시지를 받게 될 거예요. 이렇게 되면 성공입니다!
또한, terraform state list 명령어를 통해 S3에 저장된 State 파일의 내용을 확인하거나, AWS 콘솔에서 S3 버킷과 DynamoDB 테이블의 항목들을 직접 확인해볼 수도 있습니다. DynamoDB 테이블에는 LockID를 가진 항목이 잠금 상태를 나타냅니다.
terraform state list
이제 여러분의 IaC 상태 관리(IaC state management)는 훨씬 더 안정적이고 견고해졌을 겁니다. 팀원들과의 Terraform 협업(Terraform collaboration)도 한층 부드러워질 거고요. 드디어 됐다! 이 안정감, 진짜 편하더라고요. 👍
Terraform 명령어를 실행하여 State가 성공적으로 관리되고 있음을 보여주는 스크린샷입니다. DynamoDB 락도 확인해볼 수 있습니다.
마무리하며: 더 나은 IaC 여정을 위해
오늘은 Terraform State를 S3와 DynamoDB를 활용하여 안전하게 관리하는 방법에 대해 자세히 알아봤습니다. 13년차 엔지니어로서 직접 겪었던 경험과 삽질까지 솔직하게 공유해 드렸는데, 도움이 되셨으면 좋겠습니다.
Terraform State 관리는 단순한 파일 저장을 넘어, 안정적인 인프라 운영과 효율적인 팀 협업을 위한 필수적인 요소입니다. S3의 내구성과 버전 관리, 그리고 DynamoDB의 강력한 잠금 기능을 활용하면, 여러분의 IaC 여정은 훨씬 더 순탄해질 거예요.
다음 글에서는 Terraform State 파일을 더욱 안전하게 보호하기 위한 추가적인 보안 설정(예: IAM 정책 강화, S3 버킷 정책, VPC Endpoint 활용 등)에 대해 더 깊게 다뤄볼 예정입니다. 기대해주세요! 😊
'IT > Cloud' 카테고리의 다른 글
| [Cloud] GitHub Actions 모노레포: 매트릭스 빌드로 CI/CD 최적화하기 (0) | 2026.05.12 |
|---|---|
| [Cloud] Terraform AWS EKS 모듈 활용: 프로덕션 클러스터 배포 및 관리 가이드 (1) | 2026.05.12 |
| [AWS 배포] GitHub Actions로 S3/CloudFront 정적 웹사이트 배포 자동화 가이드 (0) | 2026.05.12 |
| [클라우드 비용 관리] Terraform Cloud 비용 최적화: RUM 모델과 절감 전략 (0) | 2026.05.10 |
| [Cloud] Cloudflare Workers 실전 가이드: 서버리스 엣지 컴퓨팅 활용 전략 (1) | 2026.05.09 |
| [Cloud] Podman vs Docker: Rootless 컨테이너 보안 및 활용 가이드 (1) | 2026.05.09 |