Terraform에서 상태 파일(State)을 안전하게 관리하는 것은 인프라 일관성을 유지하는 핵심이에요. 동시에 여러 Terraform 프로세스가 같은 상태 파일을 수정하면 파일 손상이 발생할 수 있기 때문에 상태 잠금(State Locking) 기능이 필수적이에요. 이를 통해 Terraform은 작업 시작 시 상태 파일을 잠그고 종료 시 해제하는데요.
지금까지 AWS S3를 백엔드로 사용할 때는 DynamoDB 테이블을 "보조 락 저장소"로 활용했어요. Terraform이 상태를 변경하기 전 DynamoDB에 고유 식별자와 함께 잠금 항목을 생성하고, 작업 완료 후 해당 항목을 삭제하는 방식이었죠. DynamoDB의 강한 일관성과 조건부 쓰기 덕분에 한 시점에 하나의 작업만 상태를 변경할 수 있었어요.
그러나 DynamoDB 기반 잠금에는 몇 가지 단점이 있었죠. 추가 인프라 리소스가 필요하여 설정 복잡성이 증가했고, 비용과 운영 부담이 있었으며, 특히 여러 프로젝트나 환경을 운영할 경우 이러한 문제가 더 두드러졌어요.
Terraform 1.10의 S3 네이티브 잠금 기술적 원리
Terraform 1.10에서는 S3 자체만으로 상태 잠금을 구현하는 기능이 추가되었어요. 이는 AWS가 2024년 8월 S3에 조건부 쓰기(Conditional Writes) 지원을 공식 발표한 것과 연결되어요.
S3의 조건부 쓰기는 HTTP 헤더인 If-None-Match 등을 사용해 동일한 키의 객체가 없을 때만 쓰기를 성공시키는 기능인데요. S3 네이티브 잠금은 이 메커니즘을 활용한다고 해요.
S3 백엔드 설정에서 use_lockfile = true 옵션을 활성화하면, Terraform은 실행 시 .tflock 확장자의 잠금 파일을 S3에 생성해요. 이때 조건부 쓰기를 적용해 해당 경로의 .tflock 객체가 존재하지 않을 경우에만 생성되도록 요청해요.
잠금 파일은 JSON 형식으로 메타데이터를 포함하며, 이미 잠금 파일이 존재한다면 S3는 객체 생성 요청을 거부하고 Terraform은 "다른 프로세스에 의해 잠겨 있다"는 오류를 발생시켜요. 성공적으로 잠금 파일을 생성하면 상태 변경 작업을 진행하고, 작업 종료 시 파일을 삭제해 잠금을 해제해요.
현재 1.10에서는 실험적 기능이라 기본값은 비활성화되어 있으며, 수동으로 use_lockfile을 설정해야 해요. 만약 기존 DynamoDB 락과 함께 사용하고 싶다면 dynamodb_table과 use_lockfile을 동시 지정할 수 있어다. HashiCorp는 미래 버전에서 DynamoDB 기반 잠금 지원을 완전히 제거할 계획이에요.
실제 적용 방법: AS-IS와 TO-BE 비교
기존(AS-IS) 방식에서는 상태 관리를 위해 S3 버킷과 DynamoDB 테이블을 모두 생성해야 했어요.
resource "aws_s3_bucket" "terraform_state" {
bucket = "terraform-state-bucket"
lifecycle {
prevent_destroy = true
}
}
resource "aws_s3_bucket_versioning" "terraform_state_versioning" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_dynamodb_table" "terraform_state_lock" {
name = "TFStateLock"
hash_key = "LockID"
billing_mode = "PAY_PER_REQUEST"
attribute {
name = "LockID"
type = "S"
}
}
HCL
복사
그리고 백엔드 설정에서 DynamoDB 테이블을 지정도 일일이 해야했구요.
terraform {
backend "s3" {
bucket = "terraform-state-bucket"
key = "terraform.tfstate"
region = "ap-northeast-2"
dynamodb_table = "terraform-lock-table"
encrypt = true
}
}
HCL
복사
이제 Terraform 1.10부터는(TO-BE) DynamoDB 없이 S3만으로 상태 잠금을 구현할 수 있어요.
resource "aws_s3_bucket" "terraform_state" {
bucket = "terraform-state-bucket"
lifecycle {
prevent_destroy = true
}
}
resource "aws_s3_bucket_versioning" "terraform_state_versioning" {
bucket = aws_s3_bucket.terraform_state.id
versioning_configuration {
status = "Enabled"
}
}
HCL
복사
백엔드 설정은 단순히 use_lockfile = true 옵션을 추가하는 것만으로 S3 네이티브 상태 잠금 기능을 활성화할 수 있게 되었네요!
terraform {
backend "s3" {
bucket = "terraform-state-bucket"
key = "terraform.tfstate"
region = "ap-northeast-2"
use_lockfile = true
encrypt = true
}
}
HCL
복사
S3 네이티브 잠금의 이점과 고려사항
S3의 Native Locking 기능을 이용하면 어떤 이점이 있을까요? 먼저 DynamoDB 테이블 생성 및 관리 필요성이 사라져 설정이 단순해집니다. 이는 특히 CI/CD 파이프라인이나 자동화된 환경에서 초기 설정을 더 쉽게 만듭니다. 따라서 DynamoDB 사용에 따른 비용이 절감되지요.
개별 비용은 작지만 여러 프로젝트와 환경에 걸쳐 누적되면 무시할 수 없는 효율화가 됩니다. Sionic AI 처럼 AWS, OCI 등 여러 멀티 클라우드를 활용해야 하는 상황이라면 특정 클라우드 벤더사의 제품에 종속될 필요도 없어지지요. 설정도 용이해집니다. 백엔드 설정에 간단히 use_lockfile = true 옵션만 추가하면 됩니다. 기존처럼 별도 리소스를 생성하고 IAM 권한을 설정하는 복잡한 과정이 필요하지 않습니다. 마지막으로, 현재는 DynamoDB 잠금과 S3 네이티브 잠금이 동시에 사용할 수 있으므로 점진적인 마이그레이션이 가능합니다.
하지만 S3 네이티브 잠금을 사용하려면 Terraform v1.10 이상으로 업그레이드해야 합니다. 기존에 S3+DynamoDB 백엔드를 사용했다면, 버전 업 후 terraform init -reconfigure를 실행해야 합니다. 따라서 팀에서 여러 사람이 Terraform을 사용한다면 모두 동일한 버전으로 업그레이드하는 것이 중요합니다. 구버전과 혼용 시 충돌 가능성이 있기 떄문이에요.
마지막으로 S3 네이티브 잠금으로 전환 시 .tflock 파일 경로에 대해 s3:GetObject, s3:PutObject, s3:DeleteObject 권한이 필요한데요. Terraform 상태용 S3 버킷에 버전 관리를 활성화하는 것이 권장되기 때문에. 또한 S3의 Object Lock 기능을 사용하는 경우 Terraform 잠금과 충돌 가능성이 있으니 주의하세요!
마이그레이션 필요성과 미래 방향
HashiCorp는 향후 마이너 업데이트에서 DynamoDB 기반 잠금 지원을 완전히 제거할 계획을 밝혔습니다. 따라서 가능한 빨리 S3 네이티브 잠금으로 마이그레이션하는 것을 권장해볼게요.
특히 MLOps 인프라 관리와 같이 클라우드 자원 변경이 빈번하고 대규모로 이루어지는 환경에서, 이러한 단순화와 효율화는 운영 부담을 크게 줄이고 인프라 관리의 신뢰성을 높이는데 기여할 것이라고 생각합니다!
참고 자료
•
Terraform Upgrading to v1.10 가이드 (Upgrading to Terraform v1.10 | Terraform | HashiCorp Developer) (Upgrading to Terraform v1.10 | Terraform | HashiCorp Developer)
•
•
AWS 머신러닝 블로그 - Terraform으로 ML 파이프라인 배포 사례 (Deploy and manage machine learning pipelines with Terraform using Amazon SageMaker | AWS Machine Learning Blog)
•