본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 30. · 0 Views
Terraform 상태 파일 관리 완벽 가이드
인프라를 코드로 관리할 때 가장 중요한 상태 파일의 역할부터 원격 저장, 백업, 잠금까지 실무에서 꼭 알아야 할 핵심 개념을 이북처럼 술술 읽히는 스타일로 정리했습니다.
목차
1. 상태 파일의 역할
입사 2개월 차 김인프라 씨가 Terraform으로 처음 서버를 배포했습니다. 성공적으로 배포가 완료되었고, AWS 콘솔에서 인스턴스가 잘 떠 있는 것을 확인했습니다.
그런데 프로젝트 폴더를 보니 terraform.tfstate라는 낯선 파일이 생성되어 있었습니다.
Terraform의 상태 파일은 인프라의 현재 상태를 기록하는 일종의 장부입니다. 마치 은행이 고객의 계좌 잔액을 정확히 기록하듯이, Terraform은 이 파일을 통해 어떤 리소스가 생성되었고 어떤 설정값을 가지고 있는지 추적합니다.
이 파일이 없다면 Terraform은 현재 인프라가 어떤 상태인지 전혀 알 수 없습니다.
다음 코드를 살펴봅시다.
# main.tf - 간단한 EC2 인스턴스 생성
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "MyWebServer"
}
}
# terraform apply 실행 후 생성되는 terraform.tfstate
# 이 파일에는 실제 생성된 리소스의 ID, IP 주소 등 모든 정보가 저장됩니다
김인프라 씨는 궁금증을 참지 못하고 선배 개발자 박데브옵스 씨에게 물어봤습니다. "이 파일은 뭐고, 지워도 되나요?" 박데브옵스 씨가 웃으며 대답했습니다.
"절대 안 돼요! 그 파일이 바로 Terraform의 심장이라고 할 수 있죠." 상태 파일이란 무엇일까요?
쉽게 비유하자면, 상태 파일은 마치 건물 설계도와 실제 시공 기록이 합쳐진 문서와 같습니다. 설계도에는 이렇게 짓겠다는 계획이 담겨 있고, 시공 기록에는 실제로 어떻게 지어졌는지가 담겨 있습니다.
Terraform도 마찬가지입니다. 코드 파일에는 원하는 인프라 상태가 정의되어 있고, 상태 파일에는 실제로 생성된 리소스의 정보가 저장되어 있습니다.
왜 이런 파일이 필요할까요? Terraform이 없던 시절, 인프라 엔지니어들은 무엇을 만들었는지 일일이 메모하거나 기억해야 했습니다.
서버 10대를 만들었다면 어떤 서버를 만들었는지, IP는 무엇인지, 보안 그룹은 어떻게 설정했는지 모두 기록해야 했죠. 사람이 하는 일이라 실수도 많았고, 인수인계할 때도 혼란스러웠습니다.
더 큰 문제는 변경 작업이었습니다. 서버 한 대의 스펙을 업그레이드하려면 현재 설정을 정확히 알아야 합니다.
하지만 기록이 부정확하거나 오래되면 무엇을 변경해야 할지 판단하기 어려웠습니다. 바로 이런 문제를 해결하기 위해 상태 파일이 등장했습니다.
상태 파일을 사용하면 Terraform이 현재 인프라를 정확히 파악할 수 있습니다. 코드를 수정하고 terraform plan을 실행하면, Terraform은 상태 파일에 기록된 현재 상태와 코드에 정의된 원하는 상태를 비교합니다.
그리고 "아, EC2 인스턴스의 타입을 t2.micro에서 t2.small로 바꿔야 하는구나"라고 정확히 판단합니다. 상태 파일의 구조를 들여다보면 JSON 형식으로 되어 있습니다.
여기에는 리소스의 고유 ID, 현재 설정값, 리소스 간 의존성 정보 등이 담겨 있습니다. 예를 들어 EC2 인스턴스를 생성하면 실제 AWS가 부여한 인스턴스 ID, 퍼블릭 IP 주소, 프라이빗 IP 주소 등이 모두 기록됩니다.
김인프라 씨가 다시 물었습니다. "그럼 이 파일을 실수로 지우면 어떻게 되나요?" 박데브옵스 씨가 심각한 표정으로 대답했습니다.
"그럼 큰일 나죠. Terraform 입장에서는 아무것도 만든 적이 없다고 생각하게 됩니다.
terraform plan을 실행하면 모든 리소스를 새로 만들겠다고 나올 거예요. 실제로는 이미 서버가 떠 있는데 말이죠." 실제 현업에서는 어떻게 활용할까요?
예를 들어 개발 환경, 스테이징 환경, 운영 환경을 각각 관리한다고 가정해봅시다. 각 환경마다 별도의 상태 파일이 생성됩니다.
개발 환경의 상태 파일에는 개발 서버들의 정보가, 운영 환경의 상태 파일에는 운영 서버들의 정보가 저장됩니다. 이렇게 환경별로 분리하면 실수로 운영 환경을 건드릴 위험이 줄어듭니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 상태 파일을 Git에 커밋하는 것입니다.
상태 파일에는 리소스의 민감한 정보가 담길 수 있습니다. 데이터베이스 비밀번호, API 키 같은 것들이죠.
따라서 .gitignore에 반드시 추가해야 합니다. 다시 김인프라 씨의 이야기로 돌아가 봅시다.
박데브옵스 씨의 설명을 들은 김인프라 씨는 고개를 끄덕였습니다. "아, 그래서 이 파일이 이렇게 중요하군요!" 상태 파일을 제대로 이해하면 Terraform이 어떻게 인프라를 추적하고 관리하는지 알 수 있습니다.
이것이 바로 인프라를 코드로 안전하게 관리할 수 있는 비결입니다.
실전 팁
💡 - 상태 파일은 절대 수동으로 편집하지 마세요. Terraform 명령어로만 관리해야 합니다.
- .gitignore에 *.tfstate와 *.tfstate.backup을 추가하여 Git에 올라가지 않도록 주의하세요.
2. 로컬 상태 vs 원격 상태
김인프라 씨는 혼자 작업할 때는 문제가 없었습니다. 그런데 팀에 새로운 동료 이클라우드 씨가 합류하면서 문제가 생겼습니다.
같은 인프라를 둘이서 관리하려다 보니 상태 파일이 충돌하기 시작한 것입니다.
로컬 상태는 개발자의 컴퓨터에 저장되는 상태 파일이고, 원격 상태는 S3나 Terraform Cloud 같은 중앙 저장소에 저장되는 상태 파일입니다. 마치 개인 노트에 메모하는 것과 팀 공유 문서에 기록하는 차이와 같습니다.
팀으로 작업한다면 반드시 원격 상태를 사용해야 합니다.
다음 코드를 살펴봅시다.
# backend.tf - 로컬 상태 (기본값, 별도 설정 없으면 자동)
# terraform.tfstate가 현재 디렉토리에 저장됨
# backend.tf - S3를 사용한 원격 상태
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
dynamodb_table = "terraform-lock" # 상태 잠금용
}
}
어느 날 김인프라 씨가 서버 설정을 변경하고 퇴근했습니다. 다음 날 이클라우드 씨가 출근해서 작업을 시작했는데, 이상한 일이 벌어졌습니다.
terraform plan을 실행하니 어제 김인프라 씨가 변경한 내용이 다시 되돌아가겠다고 나오는 겁니다. 박데브옵스 씨가 상황을 파악하고 말했습니다.
"아, 여러분이 각자 자기 컴퓨터에 있는 상태 파일을 보고 있으니까 그런 거예요. 원격 상태를 써야죠." 로컬 상태와 원격 상태는 무엇이 다를까요?
쉽게 비유하자면, 로컬 상태는 마치 각자의 수첩에 메모하는 것과 같습니다. 김인프라 씨는 자기 수첩에 "서버 타입을 t2.small로 변경했음"이라고 적었지만, 이클라우드 씨의 수첩에는 그 내용이 없습니다.
당연히 이클라우드 씨는 서버 타입이 여전히 t2.micro라고 생각하겠죠. 반면 원격 상태는 팀 공유 게시판에 글을 올리는 것과 같습니다.
김인프라 씨가 변경 사항을 기록하면, 이클라우드 씨도 즉시 그 내용을 볼 수 있습니다. 모두가 같은 문서를 보니까 혼선이 생기지 않습니다.
로컬 상태만 사용하면 어떤 문제가 생길까요? 첫째, 팀원마다 다른 상태 파일을 가지게 됩니다.
A가 서버를 만들어도 B는 그 사실을 모릅니다. B가 terraform apply를 실행하면 같은 서버를 또 만들려고 시도할 수 있습니다.
둘째, 상태 파일 백업이 어렵습니다. 개발자의 노트북이 고장 나거나 분실되면 상태 파일도 함께 사라집니다.
그러면 Terraform은 어떤 리소스를 관리하고 있는지 알 수 없게 됩니다. 셋째, 보안에 취약합니다.
상태 파일에는 민감한 정보가 담길 수 있는데, 개인 컴퓨터에 평문으로 저장되면 위험합니다. 바로 이런 문제를 해결하기 위해 원격 상태를 사용합니다.
원격 상태를 설정하면 여러 장점이 생깁니다. 가장 큰 장점은 모든 팀원이 같은 상태 파일을 공유한다는 것입니다.
누가 무엇을 변경했든 즉시 반영됩니다. 또한 자동 백업이 됩니다.
S3를 사용한다면 버저닝 기능으로 이전 상태를 모두 보관할 수 있습니다. 실수로 잘못된 변경을 했다면 이전 버전으로 되돌릴 수도 있습니다.
보안도 강화됩니다. S3에 저장할 때 암호화를 활성화하면 상태 파일이 안전하게 보관됩니다.
IAM 권한으로 누가 접근할 수 있는지도 정밀하게 제어할 수 있습니다. 위의 코드를 살펴보겠습니다.
backend 블록에서 S3 버킷 이름과 키를 지정합니다. 버킷은 미리 만들어져 있어야 하고, 키는 상태 파일이 저장될 경로입니다.
encrypt를 true로 설정하면 저장 시 자동으로 암호화됩니다. dynamodb_table은 뒤에서 배울 상태 잠금 기능에 사용됩니다.
실제 현업에서는 어떻게 활용할까요? 대부분의 기업에서는 환경별로 별도의 S3 키를 사용합니다.
개발 환경은 dev/terraform.tfstate, 스테이징은 staging/terraform.tfstate, 운영은 prod/terraform.tfstate 같은 식이죠. 이렇게 분리하면 각 환경의 상태를 독립적으로 관리할 수 있습니다.
하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 backend 설정을 변경하고 terraform init을 실행하지 않는 것입니다.
backend 설정을 바꾸면 반드시 terraform init을 다시 실행해서 새로운 백엔드로 마이그레이션해야 합니다. 또 다른 실수는 같은 S3 키를 여러 프로젝트에서 공유하는 것입니다.
이렇게 하면 한 프로젝트의 상태가 다른 프로젝트의 상태를 덮어쓸 수 있습니다. 반드시 프로젝트마다 고유한 키를 사용해야 합니다.
다시 김인프라 씨와 이클라우드 씨의 이야기로 돌아가 봅시다. 박데브옵스 씨의 도움으로 S3 원격 상태를 설정한 후, 두 사람은 더 이상 충돌 없이 협업할 수 있게 되었습니다.
원격 상태를 제대로 설정하면 팀 전체가 안전하고 효율적으로 인프라를 관리할 수 있습니다. 혼자 작업할 때도 백업과 보안을 위해 원격 상태를 사용하는 것이 좋습니다.
실전 팁
💡 - S3 버킷은 반드시 버저닝을 활성화하여 상태 파일의 이력을 보관하세요.
- 로컬에서 원격으로 전환할 때는 terraform init이 자동으로 마이그레이션을 도와줍니다.
3. 상태 파일 구조 이해
김인프라 씨는 호기심이 생겨 terraform.tfstate 파일을 열어봤습니다. JSON 형식으로 되어 있긴 한데, 뭔가 복잡해 보였습니다.
"이걸 이해하면 Terraform이 어떻게 동작하는지 더 잘 알 수 있을 것 같은데..." 그때 박데브옵스 씨가 다가왔습니다.
상태 파일은 JSON 형식으로 구성되어 있으며, 버전 정보, 리소스 정보, 의존성 정보를 담고 있습니다. 마치 건물의 설계도와 시공 기록이 합쳐진 것처럼, 어떤 리소스가 어떤 설정으로 생성되었는지 상세히 기록합니다.
직접 편집하지는 않지만 구조를 이해하면 문제 해결에 큰 도움이 됩니다.
다음 코드를 살펴봅시다.
{
"version": 4,
"terraform_version": "1.6.0",
"serial": 3,
"lineage": "abc123-def456",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_instance",
"name": "web",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"id": "i-0abc123def456",
"ami": "ami-0c55b159cbfafe1f0",
"instance_type": "t2.micro",
"public_ip": "54.180.123.45"
}
}
]
}
]
}
박데브옵스 씨가 김인프라 씨의 화면을 보며 설명을 시작했습니다. "이 파일의 구조를 이해하면 Terraform의 내부 동작 원리를 알 수 있어요.
한번 살펴볼까요?" 상태 파일의 구조는 어떻게 되어 있을까요? 쉽게 비유하자면, 상태 파일은 마치 병원의 환자 차트와 같습니다.
맨 위에는 차트 버전과 작성 날짜가 있고, 그 아래에는 환자의 상세 정보가 기록되어 있습니다. 진료 기록, 처방 내역, 검사 결과 등이 체계적으로 정리되어 있죠.
Terraform의 상태 파일도 마찬가지입니다. 맨 위에는 메타데이터가 있습니다.
version 필드는 상태 파일의 형식 버전입니다. Terraform이 업그레이드되면서 상태 파일 형식도 진화했는데, 현재는 버전 4를 사용합니다.
terraform_version은 이 상태 파일을 생성한 Terraform의 버전입니다. serial은 매우 중요한 필드입니다.
이것은 상태 파일이 몇 번째로 업데이트되었는지를 나타내는 일련번호입니다. terraform apply를 실행할 때마다 1씩 증가합니다.
만약 두 사람이 동시에 작업하면 serial 번호로 충돌을 감지할 수 있습니다. lineage는 상태 파일의 고유 ID입니다.
처음 상태 파일이 생성될 때 무작위로 만들어지며, 이후로는 변하지 않습니다. 이것으로 서로 다른 프로젝트의 상태 파일이 섞이는 것을 방지합니다.
그다음은 리소스 정보입니다. resources 배열에 실제로 생성된 모든 리소스가 담겨 있습니다.
각 리소스는 type과 name으로 식별됩니다. 위 예시에서는 aws_instance.web이라는 리소스입니다.
instances 배열에는 실제 인스턴스의 정보가 들어갑니다. count나 for_each를 사용하면 여러 개의 인스턴스가 생성될 수 있기 때문에 배열 형태입니다.
attributes 객체가 핵심입니다. 여기에 리소스의 모든 속성값이 저장됩니다.
id는 AWS가 부여한 실제 인스턴스 ID이고, ami, instance_type은 우리가 코드에서 지정한 값입니다. public_ip처럼 AWS가 자동으로 할당한 값도 여기에 기록됩니다.
김인프라 씨가 물었습니다. "그럼 이 파일을 직접 수정하면 안 되나요?" 박데브옵스 씨가 단호하게 대답했습니다.
"절대 안 됩니다! 수동으로 편집하면 실제 인프라 상태와 불일치가 생길 수 있어요.
Terraform 명령어로만 관리해야 합니다." 실제 현업에서는 어떻게 활용할까요? 상태 파일의 구조를 이해하면 문제를 디버깅할 때 유용합니다.
예를 들어 terraform plan이 이상하게 동작한다면, 상태 파일을 열어서 어떤 값이 저장되어 있는지 확인할 수 있습니다. 물론 직접 수정하지는 않고, terraform state 명령어를 사용해서 안전하게 조작합니다.
또한 outputs 섹션도 중요합니다. 코드에서 output으로 정의한 값들이 여기에 저장됩니다.
다른 모듈이나 프로젝트에서 이 값을 참조할 수 있습니다. 의존성 정보도 기록됩니다.
예를 들어 EC2 인스턴스가 특정 보안 그룹에 연결되어 있다면, 그 관계가 상태 파일에 저장됩니다. Terraform이 리소스를 삭제할 때는 이 의존성을 역순으로 따라가며 안전하게 제거합니다.
하지만 주의할 점도 있습니다. 상태 파일이 너무 커지면 성능 문제가 생길 수 있습니다.
수천 개의 리소스를 관리한다면 상태 파일도 몇 MB가 될 수 있습니다. 이럴 때는 워크스페이스를 분리하거나 모듈을 나누는 것이 좋습니다.
또한 상태 파일에는 민감한 정보가 평문으로 저장될 수 있습니다. RDS 비밀번호, API 키 같은 것들이죠.
따라서 상태 파일 자체를 암호화하고 접근 권한을 엄격히 관리해야 합니다. 다시 김인프라 씨의 이야기로 돌아가 봅시다.
박데브옵스 씨의 설명을 들은 김인프라 씨는 "아, 이제 Terraform이 어떻게 상태를 추적하는지 이해가 됩니다!"라고 말했습니다. 상태 파일의 구조를 이해하면 Terraform의 내부 동작을 파악할 수 있고, 문제가 생겼을 때 더 빠르게 해결할 수 있습니다.
직접 편집은 하지 않지만 읽고 이해하는 능력은 중요합니다.
실전 팁
💡 - 상태 파일을 읽기 전용으로만 보세요. 수정이 필요하면 terraform state 명령어를 사용하세요.
- jq 같은 도구를 사용하면 큰 상태 파일도 쉽게 탐색할 수 있습니다.
4. 상태 조회 및 수정
어느 날 김인프라 씨는 실수로 코드를 잘못 작성해서 리소스가 의도치 않게 삭제될 뻔했습니다. 다행히 terraform plan에서 미리 확인했지만, 상태 파일에 이미 잘못된 정보가 들어간 것 같았습니다.
"이럴 때는 어떻게 해야 하지?" 고민하던 차에 박데브옵스 씨가 조언을 건넸습니다.
terraform state 명령어는 상태 파일을 안전하게 조회하고 수정할 수 있는 도구입니다. 마치 데이터베이스의 SQL처럼, 상태를 직접 편집하지 않고 명령어로 관리합니다.
list로 리소스 목록을 보고, show로 상세 정보를 확인하며, mv와 rm으로 안전하게 조작할 수 있습니다.
다음 코드를 살펴봅시다.
# 상태 파일의 모든 리소스 목록 조회
terraform state list
# 특정 리소스의 상세 정보 조회
terraform state show aws_instance.web
# 리소스 이름 변경 (코드와 상태 파일 동기화)
terraform state mv aws_instance.web aws_instance.web_server
# 상태에서 리소스 제거 (실제 인프라는 유지)
terraform state rm aws_instance.web
# 외부에서 생성된 리소스를 상태에 추가
terraform import aws_instance.web i-0abc123def456
박데브옵스 씨가 말했습니다. "상태 파일을 직접 편집하면 안 된다고 했죠?
대신 terraform state 명령어를 사용하면 안전하게 관리할 수 있어요." terraform state 명령어는 무엇일까요? 쉽게 비유하자면, 은행 계좌를 관리하는 것과 같습니다.
직접 장부에 손으로 숫자를 고치면 실수할 위험이 큽니다. 대신 은행 시스템을 통해 입금, 출금, 조회를 하면 안전하게 관리됩니다.
Terraform도 마찬가지입니다. state 명령어가 바로 그 안전장치입니다.
가장 기본적인 명령어는 terraform state list입니다. 이 명령어를 실행하면 현재 상태 파일에 기록된 모든 리소스의 목록이 나옵니다.
"aws_instance.web", "aws_security_group.web_sg" 같은 식으로 말이죠. 프로젝트가 커지면 수십, 수백 개의 리소스가 나올 수 있는데, 이때 grep과 조합하면 원하는 리소스를 찾을 수 있습니다.
특정 리소스의 상세 정보를 보려면 terraform state show를 사용합니다. 예를 들어 terraform state show aws_instance.web을 실행하면, 그 인스턴스의 모든 속성값이 출력됩니다.
ID, IP 주소, 보안 그룹, 태그 등 모든 것이 보기 좋게 정리되어 나옵니다. 디버깅할 때 매우 유용합니다.
때로는 리소스 이름을 바꿔야 할 때가 있습니다. 코드에서 리소스 이름을 변경하면 Terraform은 기존 리소스를 삭제하고 새로 만들려고 합니다.
하지만 실제로는 같은 리소스인데 이름만 바꾸고 싶을 때가 있습니다. 이럴 때 terraform state mv를 사용합니다.
terraform state mv aws_instance.web aws_instance.web_server를 실행하면, 상태 파일에서 리소스 이름이 변경됩니다. 그다음 코드에서도 이름을 맞춰주면 실제 인프라는 그대로 두고 이름만 바꿀 수 있습니다.
가끔은 상태에서 리소스를 제거해야 할 때도 있습니다. 예를 들어 어떤 리소스를 Terraform 관리 대상에서 제외하고 싶다면 terraform state rm을 사용합니다.
중요한 점은 이 명령어가 실제 인프라를 삭제하지는 않는다는 것입니다. 상태 파일에서만 제거됩니다.
실제 AWS 콘솔에 가보면 리소스는 여전히 존재합니다. 반대로 외부에서 수동으로 만든 리소스를 Terraform 관리 대상에 추가할 수도 있습니다.
terraform import 명령어를 사용하면 됩니다. 예를 들어 AWS 콘솔에서 직접 만든 EC2 인스턴스를 Terraform으로 관리하고 싶다면, terraform import aws_instance.web i-0abc123def456 같은 식으로 실행합니다.
그러면 해당 인스턴스의 현재 상태가 상태 파일에 기록됩니다. 김인프라 씨가 물었습니다.
"그럼 언제 이런 명령어를 사용하나요?" 박데브옵스 씨가 실제 사례를 들려줬습니다. "예를 들어 개발자가 실수로 AWS 콘솔에서 리소스를 수동으로 만들었다고 해봅시다.
나중에 Terraform으로 관리하고 싶으면 import를 사용하면 됩니다." 또 다른 사례는 리소스를 다른 모듈로 옮길 때입니다. 기존에는 하나의 파일에서 관리하던 리소스를 별도 모듈로 분리하고 싶다면, state mv를 사용해서 상태 파일에서도 위치를 옮겨줘야 합니다.
실제 현업에서는 어떻게 활용할까요? 대규모 인프라를 관리할 때는 상태 파일이 복잡해질 수 있습니다.
이럴 때 state list로 전체 구조를 파악하고, 필요한 부분만 show로 확인하는 식으로 작업합니다. 또한 리팩토링할 때 mv를 많이 사용합니다.
하지만 주의할 점도 있습니다. state 명령어는 강력한 만큼 위험할 수도 있습니다.
특히 rm이나 mv는 실수하면 인프라에 예상치 못한 변경을 일으킬 수 있습니다. 따라서 반드시 실행 전에 terraform plan으로 영향을 미리 확인해야 합니다.
또한 팀으로 작업한다면 state 명령어를 실행하기 전에 팀원들과 소통해야 합니다. 한 사람이 상태를 변경하는 동안 다른 사람이 apply를 실행하면 충돌이 생길 수 있습니다.
다시 김인프라 씨의 이야기로 돌아가 봅시다. 박데브옵스 씨의 도움으로 terraform state 명령어를 익힌 김인프라 씨는, 이제 상태 파일을 안전하게 관리할 수 있게 되었습니다.
terraform state 명령어를 제대로 활용하면 상태 파일을 직접 편집하지 않고도 안전하게 관리할 수 있습니다. 특히 대규모 인프라를 운영할 때는 필수적인 기술입니다.
실전 팁
💡 - state 명령어 실행 전에는 반드시 상태 파일을 백업하세요.
- terraform plan으로 영향을 미리 확인한 후 state 명령어를 실행하세요.
5. 상태 파일 백업
어느 금요일 저녁, 김인프라 씨는 급하게 인프라 변경 작업을 하다가 실수로 중요한 리소스를 삭제해 버렸습니다. 얼굴이 하얗게 질린 김인프라 씨를 본 박데브옵스 씨가 침착하게 말했습니다.
"괜찮아요. 백업이 있으니까요."
상태 파일 백업은 인프라 복구의 생명줄입니다. Terraform은 자동으로 로컬 백업을 생성하고, S3를 사용하면 버저닝으로 모든 이력을 보관합니다.
마치 게임의 세이브 포인트처럼, 문제가 생기면 이전 상태로 되돌릴 수 있습니다. 백업 전략을 잘 세워두면 어떤 실수도 복구할 수 있습니다.
다음 코드를 살펴봅시다.
# S3 백엔드에서 버저닝 활성화
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
# S3 버킷에 버저닝이 활성화되어 있어야 함
}
}
# 로컬 백업 파일 확인
# terraform apply 실행 시 자동으로 terraform.tfstate.backup 생성됨
# 수동으로 상태 파일 백업
terraform state pull > backup-$(date +%Y%m%d-%H%M%S).tfstate
# 이전 상태로 복구 (조심해서 사용)
terraform state push backup-20231201-143000.tfstate
박데브옵스 씨가 차분하게 설명했습니다. "Terraform은 기본적으로 백업을 자동으로 만들어줍니다.
로컬에서는 terraform.tfstate.backup 파일이 생성되고, S3를 쓰면 버저닝으로 모든 이력이 남아요." 상태 파일 백업은 왜 중요할까요? 쉽게 비유하자면, 백업은 마치 타임머신과 같습니다.
무언가 잘못되었을 때 과거로 돌아가서 다시 시작할 수 있습니다. 인프라 관리에서 실수는 언제든 일어날 수 있습니다.
잘못된 명령어 한 번으로 운영 데이터베이스가 삭제될 수도 있죠. 하지만 백업이 있다면 걱정할 필요가 없습니다.
로컬에서 작업할 때는 어떻게 백업될까요? terraform apply를 실행하면 Terraform은 기존 상태 파일을 terraform.tfstate.backup으로 자동 복사한 후 새로운 상태를 terraform.tfstate에 저장합니다.
즉, 항상 최근 두 개 버전을 보관하는 셈입니다. 실수로 잘못된 변경을 했다면 .backup 파일을 .tfstate로 복사해서 되돌릴 수 있습니다.
하지만 로컬 백업은 한계가 있습니다. 오직 한 단계 이전으로만 돌아갈 수 있고, 컴퓨터가 고장 나면 백업도 함께 사라집니다.
그래서 원격 백엔드를 사용하는 것이 좋습니다. S3를 백엔드로 사용하고 버킷에 버저닝을 활성화하면, 모든 상태 변경이 이력으로 남습니다.
첫 번째 apply부터 최근 apply까지 모든 버전이 보관됩니다. AWS 콘솔에서 S3 버킷을 열어보면 같은 키에 여러 버전이 존재하는 것을 확인할 수 있습니다.
필요하다면 특정 시점의 상태로 되돌릴 수도 있습니다. S3에서 원하는 버전을 다운로드한 후, terraform state push로 복원하면 됩니다.
물론 매우 조심스럽게 사용해야 하는 기능입니다. 김인프라 씨가 물었습니다.
"그럼 수동으로 백업할 수도 있나요?" 박데브옵스 씨가 고개를 끄덕였습니다. "물론이죠.
terraform state pull 명령어로 현재 상태를 파일로 저장할 수 있어요." 위의 코드처럼 날짜와 시간을 포함한 파일명으로 저장하면, 여러 시점의 백업을 보관할 수 있습니다. 중요한 변경 작업 전에는 이렇게 수동 백업을 만들어두는 것이 좋습니다.
실제 현업에서는 어떻게 활용할까요? 대부분의 기업에서는 S3 버저닝을 기본으로 사용하고, 중요한 변경 전에는 수동 백업도 만듭니다.
예를 들어 데이터베이스 업그레이드나 대규모 리팩토링 같은 위험한 작업 전에는 반드시 백업을 확인합니다. 또한 정기적으로 백업을 테스트합니다.
백업이 있어도 복원이 안 되면 소용없으니까요. 개발 환경에서 백업을 복원해보고 제대로 동작하는지 확인하는 것이 좋습니다.
일부 기업에서는 백업을 다른 리전의 S3 버킷에 복제하기도 합니다. 리전 장애에 대비하기 위해서죠.
S3의 크로스 리전 복제 기능을 사용하면 자동으로 백업됩니다. 하지만 주의할 점도 있습니다.
너무 오래된 백업 버전은 용량을 차지할 수 있습니다. S3 라이프사이클 정책을 설정해서 일정 기간이 지난 버전은 자동으로 삭제하거나 Glacier로 이동시키는 것이 좋습니다.
예를 들어 30일 이상 된 버전은 삭제하는 식으로 말이죠. 또한 백업을 복원할 때는 극도로 조심해야 합니다.
잘못된 백업으로 복원하면 최근 변경 사항이 모두 사라질 수 있습니다. 반드시 terraform plan으로 영향을 확인한 후 apply해야 합니다.
다시 김인프라 씨의 이야기로 돌아가 봅시다. 박데브옵스 씨의 도움으로 S3 버전 이력을 확인한 김인프라 씨는, 실수하기 직전의 상태를 찾아서 안전하게 복구할 수 있었습니다.
상태 파일 백업을 제대로 관리하면 어떤 실수도 두렵지 않습니다. 자동 백업을 활성화하고, 중요한 작업 전에는 수동 백업도 만드는 습관을 들이세요.
실전 팁
💡 - S3 버킷에는 반드시 버저닝을 활성화하세요. 비용은 얼마 안 들지만 안전성은 크게 높아집니다.
- 중요한 변경 전에는 terraform state pull로 수동 백업을 만드세요.
6. 상태 잠금 개념
어느 날 김인프라 씨와 이클라우드 씨가 동시에 같은 인프라를 수정하려고 했습니다. 둘 다 terraform apply를 실행했는데, 이상하게도 한 명은 "상태 잠금을 획득할 수 없습니다"라는 에러가 나왔습니다.
"이게 무슨 뜻이죠?" 김인프라 씨가 당황해하자 박데브옵스 씨가 미소 지으며 설명했습니다.
상태 잠금은 여러 사람이 동시에 인프라를 변경하는 것을 방지하는 메커니즘입니다. 마치 화장실 문에 자물쇠를 거는 것처럼, 한 사람이 작업하는 동안 다른 사람은 대기해야 합니다.
DynamoDB나 Consul 같은 저장소를 사용해서 누가 잠금을 가지고 있는지 추적하며, 충돌과 데이터 손실을 방지합니다.
다음 코드를 살펴봅시다.
# DynamoDB를 사용한 상태 잠금 설정
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
# DynamoDB 테이블로 상태 잠금 활성화
dynamodb_table = "terraform-state-lock"
}
}
# DynamoDB 테이블은 미리 생성되어 있어야 함
# 테이블 이름: terraform-state-lock
# 파티션 키: LockID (String 타입)
# 작업 중 강제로 잠금 해제 (위험! 신중하게 사용)
terraform force-unlock <LOCK_ID>
박데브옵스 씨가 설명했습니다. "상태 잠금은 마치 한 번에 한 사람만 들어갈 수 있는 전화부스 같은 거예요.
누군가 들어가 있으면 다른 사람은 기다려야 하죠." 상태 잠금은 왜 필요할까요? 쉽게 비유하자면, 상태 잠금은 마치 도서관에서 책을 대출하는 시스템과 같습니다.
한 사람이 책을 빌려가면 다른 사람은 그 책을 대출할 수 없습니다. 만약 두 사람이 동시에 같은 책을 빌릴 수 있다면 누가 가지고 있는지 알 수 없겠죠.
Terraform에서도 마찬가지입니다. 두 명의 개발자가 동시에 terraform apply를 실행하면 어떻게 될까요?
둘 다 상태 파일을 읽고, 각자 변경하고, 다시 저장하려고 합니다. 이 과정에서 한 사람의 변경이 다른 사람의 변경을 덮어쓸 수 있습니다.
상태 잠금이 없던 시절에는 어떤 문제가 있었을까요? 가장 큰 문제는 경쟁 조건이었습니다.
A가 서버 하나를 추가하고, 동시에 B도 서버 하나를 추가하려고 합니다. 둘 다 현재 상태를 읽고 "현재 서버가 5대니까 6대로 만들자"라고 판단합니다.
그런데 둘 다 실행되면 총 7대가 되어야 하는데, 실제로는 6대만 생길 수 있습니다. 한 사람의 변경이 사라진 것이죠.
더 심각한 경우는 리소스 삭제입니다. A가 리소스를 삭제하는 동안 B가 그 리소스를 수정하려고 하면, 예측할 수 없는 상황이 벌어집니다.
운영 중인 데이터베이스가 의도치 않게 삭제될 수도 있습니다. 바로 이런 문제를 해결하기 위해 상태 잠금이 등장했습니다.
상태 잠금을 활성화하면 terraform apply나 terraform plan을 실행할 때 자동으로 잠금을 획득합니다. 잠금을 가진 사람만 상태 파일을 수정할 수 있고, 다른 사람들은 잠금이 해제될 때까지 대기합니다.
Terraform에서는 주로 DynamoDB를 사용해서 잠금을 구현합니다. DynamoDB는 AWS의 NoSQL 데이터베이스인데, 매우 빠르고 안정적입니다.
잠금 정보만 저장하면 되므로 비용도 거의 들지 않습니다. 위의 코드를 살펴보겠습니다.
backend 블록에 dynamodb_table을 추가하면 상태 잠금이 활성화됩니다. DynamoDB 테이블은 미리 만들어져 있어야 하고, LockID라는 파티션 키가 있어야 합니다.
terraform apply를 실행하면 Terraform은 먼저 DynamoDB 테이블에 잠금 레코드를 생성합니다. 이 레코드에는 누가 잠금을 가지고 있는지, 언제 획득했는지 같은 정보가 담겨 있습니다.
작업이 끝나면 잠금이 자동으로 해제됩니다. 김인프라 씨가 물었습니다.
"그럼 만약 작업 중에 컴퓨터가 꺼지면 어떻게 되나요? 잠금이 계속 남아있나요?" 박데브옵스 씨가 고개를 끄덕였습니다.
"좋은 질문이에요. 그럴 수도 있죠.
그래서 terraform force-unlock이라는 명령어가 있습니다. 하지만 매우 조심해서 사용해야 해요." force-unlock은 강제로 잠금을 해제하는 명령어입니다.
예를 들어 네트워크 문제로 작업이 중단되었는데 잠금이 남아있다면, LOCK_ID를 입력해서 수동으로 해제할 수 있습니다. 하지만 다른 사람이 실제로 작업 중인데 강제 해제하면 충돌이 생길 수 있으니 주의해야 합니다.
실제 현업에서는 어떻게 활용할까요? 대부분의 팀에서는 S3 백엔드와 DynamoDB 잠금을 함께 사용합니다.
초기 설정은 조금 번거롭지만, 한 번 설정해두면 모든 팀원이 안전하게 협업할 수 있습니다. CI/CD 파이프라인에서도 상태 잠금이 중요합니다.
자동화된 배포가 동시에 여러 번 실행되면 문제가 생길 수 있는데, 잠금이 있으면 순차적으로 실행됩니다. 일부 팀에서는 잠금 타임아웃을 설정하기도 합니다.
예를 들어 30분 이상 잠금을 유지하면 자동으로 해제되도록 하는 것이죠. 이렇게 하면 누군가 작업을 시작하고 퇴근해버려도 다른 사람이 작업할 수 있습니다.
하지만 주의할 점도 있습니다. 잠금은 apply와 destroy에만 적용됩니다.
terraform plan은 기본적으로 잠금을 획득하지 않습니다. 하지만 -lock=true 플래그를 추가하면 plan도 잠금을 획득할 수 있습니다.
또한 모듈별로 별도의 상태 파일을 사용한다면, 각각 독립적인 잠금을 가집니다. 한 모듈에서 작업 중이어도 다른 모듈은 동시에 작업할 수 있습니다.
다시 김인프라 씨와 이클라우드 씨의 이야기로 돌아가 봅시다. 상태 잠금의 개념을 이해한 두 사람은, 이제 서로 소통하며 순서대로 작업하게 되었습니다.
"제가 작업 중이니 10분만 기다려주세요!" 상태 잠금을 제대로 설정하면 팀 협업 시 발생할 수 있는 대부분의 충돌을 방지할 수 있습니다. 특히 운영 환경에서는 필수적인 안전장치입니다.
실전 팁
💡 - 운영 환경에서는 반드시 상태 잠금을 활성화하세요. DynamoDB 비용은 거의 안 들지만 안전성은 크게 높아집니다.
- force-unlock은 정말 필요한 경우에만 사용하고, 실행 전에 팀원들과 소통하세요.
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Terraform 변수와 출력값 완벽 가이드
Terraform의 입력 변수와 출력값을 활용하여 재사용 가능하고 유연한 인프라 코드를 작성하는 방법을 배웁니다. 변수 타입, 검증, 파일 분리부터 민감한 출력값 처리까지 실무에 필요한 모든 내용을 다룹니다.
Terraform 프로바이더와 리소스 완벽 가이드
Terraform의 핵심인 프로바이더와 리소스 개념을 실무 중심으로 설명합니다. AWS 프로바이더 설정부터 리소스 정의, 의존성 관리, 멀티 프로바이더 구성까지 초급 개발자도 쉽게 이해할 수 있도록 스토리텔링 방식으로 풀어냈습니다.
HCL 문법과 기본 구조 완벽 가이드
Terraform의 핵심 언어인 HCL을 처음 배우는 초급 개발자를 위한 가이드입니다. 기본 문법부터 블록 구조, 데이터 타입, 주석, 포맷팅까지 실무에 필요한 모든 것을 다룹니다. 점프 투 자바 스타일로 쉽고 재미있게 배워보세요.
Terraform 소개 및 설치 완벽 가이드
인프라를 코드로 관리하는 IaC의 개념부터 Terraform의 특징, 설치 방법, 그리고 첫 번째 리소스 생성까지 초급 개발자를 위한 친절한 입문 가이드입니다. 실무에서 바로 활용할 수 있는 예제와 팁을 담았습니다.
Ansible 소개 및 설치 완벽 가이드
서버 수십 대를 손쉽게 관리하는 자동화 도구 Ansible의 기초부터 설치, 첫 명령어 실행까지 배웁니다. 초급 개발자를 위한 실무 중심 입문 가이드입니다.