Terraform - tfstate
1. tfstate의 역할
- 현재 인프라 상태 저장 – Terraform이 관리하는 모든 리소스의 정보를 JSON 형식으로 저장
- 변경 사항 추적 – Terraform 실행 시 기존 인프라와 새로운 코드의 차이를 비교하여 필요한 변경만 적용
- 동일한 상태 공유 – 여러 팀원과 동일한 인프라 상태를 공유할 수 있도록 원격 저장소(예: AWS S3, Terraform Cloud) 사용 가능
2. tfstate 파일의 주요 구조
{
"version": 4,
"terraform_version": "1.6.0",
"serial": 3,
"lineage": "abcd-efgh-ijkl-mnop",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_instance",
"name": "example",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"attributes": {
"id": "i-1234567890abcdef",
"ami": "ami-0abcdef1234567890",
"instance_type": "t2.micro",
"tags": {
"Name": "example-instance"
}
}
}
]
}
]
}
- "version": tfstate 파일의 버전
- "terraform_version": 해당 상태 파일을 생성한 Terraform 버전
- "serial": tfstate가 업데이트될 때마다 증가하는 번호
- "resources": Terraform이 관리하는 리소스 목록
- "outputs": Terraform 코드에서 정의한 output 변수 값 저장
3. tfstate 파일 관리 방식
(1) 로컬 상태 파일 (Local State)
- 기본적으로 terraform apply 실행 시 현재 디렉토리에 terraform.tfstate 파일 생성됨
- 단점: 협업이 어렵고, 여러 사람이 동시에 변경하면 충돌 가능
(2) 원격 상태 파일 (Remote State)
- Terraform은 원격 스토리지를 이용해 tfstate 파일을 저장할 수 있음
- 대표적인 원격 백엔드:
- AWS S3 + DynamoDB
- Terraform Cloud
- HashiCorp Consul
- Google Cloud Storage (GCS)
예제: AWS S3에 tfstate 저장
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "eks/Vincent-dev.tfstate"
region = "ap-northeast-2"
profile = "my-profile"
dynamodb_table = "TerraformStateLock"
}
}
- bucket: S3 버킷 이름
- key: tfstate 파일 경로
- dynamodb_table: 상태 잠금 기능을 위한 DynamoDB 테이블
막간) 상태 잠금(State Locking)이란?
Terraform이 terraform apply 또는 terraform plan을 실행할 때 여러 사용자가 동시에 동일한 Terraform 작업을 수행하는 경우를 방지하기 위해 잠금(Locking)을 사용
잠금이 없다면?
- 두 명 이상의 사용자가 동시에 terraform apply를 실행하면 충돌 발생
- Terraform이 tfstate를 읽고 업데이트하는 도중에 다른 사용자가 변경하면 데이터가 손상될 위험
- 예를 들어, 한 사용자가 terraform destroy 실행 중인데 다른 사용자가 terraform apply를 실행하면 예상치 못한 결과 발생
잠금이 있으면?
- Terraform은 DynamoDB 테이블을 사용해 "현재 다른 프로세스가 Terraform을 실행 중인지" 확인
- 만약 다른 사용자가 실행 중이라면, 새 실행 요청을 차단하고 "잠금 중(Locked)" 메시지 출력
- 충돌 없이 안전하게 tfstate를 관리 가능
4. tfstate 보안 및 주의사항
(1) Git에 tfstate 파일을 올리지 말 것
- terraform.tfstate에는 AWS Access Key, Database Password 등 민감한 정보가 포함될 수 있음
- .gitignore에 추가하여 Git에 올라가지 않도록 설정
*.tfstate
*.tfstate.backup
(2) 원격 저장소와 잠금(Locking) 기능 사용
- 여러 사용자가 동시에 Terraform을 실행하면 충돌 가능
5. tfstate 파일이 손상되었을 때 복구 방법
- 백업 파일 사용 (terraform.tfstate.backup)
- Terraform은 terraform.tfstate를 변경할 때마다 .backup 파일을 자동 생성
- 손상되었을 경우 .backup 파일을 원래 terraform.tfstate로 복사
- terraform refresh (Terraform 1.5 이하)
- terraform refresh 명령어를 실행하면 현재 클라우드 상태를 기반으로 tfstate 파일을 갱신
- Terraform 1.5 이후부터는 terraform apply -refresh-only 사용
- 수동으로 JSON 파일 수정
- tfstate 파일은 JSON이므로 직접 수정 가능하지만, 매우 신중하게 다뤄야 함
그러면 이런 문제도 가정해보자
만약 AWS 콘솔에서 EC2 인스턴스를 수동으로 삭제했지만, Terraform의 tfstate 파일에는 삭제되지 않은 상태로 남아 있다면?
terraform apply 시에 문제가 발생할 것이고 terraform plan을 실행하면 리소스를 새로 생성하려고 할 것이다
terraform refresh명령은 모든 관리되는 원격 객체의 현재 설정을 읽고 일치하도록 Terraform 상태를 업데이트
실제 원격 객체는 수정되지 않지만 Terraform 상태(tfstate) 는 수정됨
terraform apply -refresh-only
참조: https://developer.hashicorp.com/terraform/cli/commands/refresh
Command: refresh | Terraform | HashiCorp Developer
The `terraform refresh` command reads the current settings from all managed remote objects and updates the Terraform state to match.
developer.hashicorp.com