백엔드 — Terraform 상태를 어디에 둘까
백엔드 — Terraform 상태를 어디에 둘까
Terraform은 관리하는 리소스를 추적하려고 상태(state) 데이터 파일을 쓴다는 걸 떠올려 보세요. 그 상태 파일을 어디에 저장할지 정하는 게 바로 backend 블록이에요. 팀으로 작업할 때 상태를 로컬 파일에만 두면 여럿이 함께 다루기 어려워요. 그래서 상태를 원격 객체 저장소에 두고 여러 사람이 같은 인프라 컬렉션을 함께 작업하게 하는 거죠.
출처: https://developer.hashicorp.com/terraform/language/backend
본문
backend 블록 정의하기
구성을 HCP Terraform이나 Terraform Enterprise의 워크스페이스에 연결할 때는 backend를 구성하지 마세요. 그 시스템들은 구성과 연결된 워크스페이스에서 상태를 자동으로 관리해요. 구성에 cloud 블록이 있다면 backend 블록을 포함할 수 없어요.
backend를 구성하려면 최상위 terraform 블록 안에 중첩된 backend 블록을 추가해요. 다음 예시는 remote 백엔드를 구성해요.
terraform {
backend "remote" {
organization = "example_corp"
workspaces {
name = "my-app-prod"
}
}
}
backend 구성에는 중요한 제한이 몇 가지 있어요.
- 구성은 backend 블록을 하나만 제공할 수 있어요.
- backend 블록은 이름 있는 값(입력 변수, locals, 데이터 소스 속성)을 참조할 수 없어요.
- backend 블록 안에 선언한 값은 구성의 다른 곳에서 참조할 수 없어요.
기본 백엔드
Terraform은 기본적으로 local이라는 백엔드를 사용해요. local 백엔드 타입은 상태를 로컬 디스크의 파일로 저장해요.
백엔드 타입
Terraform은 여러 내장 백엔드 타입을 제공해요. 어떤 백엔드는 상태 파일의 원격 디스크처럼 동작하고, 어떤 백엔드는 Terraform 작업 중 상태를 잠가서 충돌과 불일치를 막아요. 백엔드를 플러그인으로 추가로 불러오지는 못해요.
백엔드 타입은 backend 블록의 라벨로 지정해요. 다음 예시는 원격 백엔드를 쓰라고 지시해요.
backend "remote" {
organization = "example_corp"
. . .
}
지정한 백엔드는 사용 중인 Terraform 버전에서 사용할 수 있어야 해요.
백엔드 인자
backend 블록 본문의 인자는 백엔드 타입마다 달라요. 상태 구성을 어디에 어떻게 저장할지 지정하죠. 어떤 백엔드 타입은 추가 동작을 구성할 수 있게 해요. 자세한 내용은 각 백엔드 문서를 보세요.
일부 백엔드는 구성의 일부로 접근 자격 증명을 넣게 허용하는데, 구성에 접근 자격 증명을 직접 넣는 건 권장하지 않아요. 자격 증명 관련 인자는 비워 두고, 대상 시스템의 관례에 맞는 자격 증명 파일이나 환경 변수로 제공하는 게 좋아요.
자격 증명과 민감한 데이터
백엔드는 상태를 원격 서비스에 저장하므로 여러 사람이 접근할 수 있어요. 상태 데이터는 극도로 민감한 정보를 담고 있어서, 원격 상태에 접근하려면 일반적으로 접근 자격 증명이 필요해요.
경고: 자격 증명과 민감한 데이터는 환경 변수로 제공하는 걸 권장해요. -backend-config를 쓰거나 구성을 직접 하드코딩하면, Terraform이 그 값들을 .terraform 하위 디렉터리와 플랜 파일 양쪽에 포함시켜요. 민감한 자격 증명이 새어나갈 수 있으니 주의해야 해요.
Terraform은 백엔드 구성을 평문으로 두 개의 파일에 기록해요.
.terraform/terraform.tfstate파일 — 현재 작업 디렉터리의 백엔드 구성- 플랜 파일 — 플랜을 만들 당시의
.terraform/terraform.tfstate정보를 담음. Terraform이 플랜을 만들었던 당시의 백엔드 구성을 그대로 사용해 올바른 인프라 집합에 적용하도록 보장
이전에 파일로 저장해 둔 플랜을 적용할 때 Terraform은 그 파일에 담긴 백엔드 구성(현재 백엔드 설정이 아니라)을 사용해요. 거기에 유효기간이 있는 자격 증명이 들어 있다면 플랜을 적용하기 전에 만료될 수 있어요. 플랜 단계와 apply 단계에서 다른 값을 써야 한다면 환경 변수로 자격 증명을 전달하세요.
백엔드 초기화
백엔드 구성을 바꾸면 플랜·apply·상태 작업 전에 terraform init을 다시 실행해서 백엔드를 검증하고 구성해야 해요.
초기화 후 Terraform은 로컬에 .terraform/ 디렉터리를 만들어요. 이 디렉터리에는 가장 최근 백엔드 구성과 Terraform CLI에 제공한 인증 매개변수까지 포함돼요. 원격 백엔드의 민감한 자격 증명이 담길 수 있으니 Git에 커밋하지 마세요.
로컬 백엔드 구성은 실제 인프라에 대한 상태 데이터를 담는 terraform.tfstate 파일과는 완전히 별개예요. Terraform은 terraform.tfstate 파일을 원격 백엔드에 저장해요.
백엔드를 바꾸면 Terraform이 기존 상태를 새 백엔드로 마이그레이션할지 물어봐요. 이 덕분에 기존 상태를 잃지 않고 백엔드를 바꿀 수 있어요. 중요: 새 백엔드로 마이그레이션하기 전에 terraform.tfstate 파일을 다른 위치로 복사해 상태를 수동으로 백업해 두는 걸 강력히 권장해요.
부분 구성(partial configuration)
백엔드 구성에서 모든 필수 인자를 다 지정하지 않아도 돼요. 어떤 인자는 Terraform을 실행하는 자동화 스크립트가 자동으로 제공한다면 생략하는 게 좋을 수 있어요. 인자의 일부 또는 전부가 생략된 상태를 부분 구성이라고 해요.
부분 구성일 때 남은 구성 인자는 초기화 과정에서 제공해야 해요. 남은 인자를 공급하는 방법은 여러 가지예요.
- 파일:
init명령줄에서-backend-config=PATH옵션으로 구성 파일을 지정해요. 부분 구성은 키가 빈 값으로 설정된backend블록이 있어야 해요.terraform init -backend-config="<path-to-remaining-configuration>"을 실행하면 Terraform이 부분backend구성의 키를 지정한 구성 파일의 매칭 키 값으로 채워요. 다음 예시에서state.tf구성 파일의backend블록 키는state.config구성의 값으로 채워져요.
# state.tf
terraform {
backend "s3" {
bucket = ""
key = ""
region = ""
profile = ""
}
}
# state.config
bucket = "your-bucket"
key = "your-state.tfstate"
region = "eu-central-1"
profile = "Your_Profile"
구성 파일에 비밀이 담길 때는 Vault 같은 안전한 데이터 저장소에 보관하고, Terraform 실행 전에 로컬 디스크로 내려받으면 돼요.
- 명령줄 키/값 쌍:
init명령줄에서-backend-config="KEY=VALUE"옵션으로 키/값 쌍을 지정해요. 많은 셸이 명령줄 플래그를 히스토리 파일에 남기므로, 비밀값에는 이 방법을 권장하지 않아요. - 대화식: 인터랙티브 입력이 비활성화되지 않았다면 Terraform이 필요한 값을 대화식으로 물어봐요. 선택 인자는 물어보지 않아요.
backend 설정이 여러 위치에서 제공되면 최상위 설정이 병합돼요. 명령줄 옵션이 기본 구성의 설정을 덮어쓰고, 명령줄 옵션끼리는 입력 순서대로 처리되어 나중 옵션이 이전 옵션이 설정한 값을 덮어써요.
병합된 최종 구성은 .terraform 디렉터리에 저장되므로 버전 관리에서 무시해야 해요. 즉 민감한 정보를 버전 관리에서 빼두되, Terraform을 실행할 때는 로컬 디스크에 평문으로 존재하게 돼요.
부분 구성을 쓸 때 Terraform은 최소한 루트 Terraform 구성 파일 중 하나에 빈 백엔드 구성을 지정해서 백엔드 타입을 명시하도록 요구해요. 예를 들어:
terraform {
backend "consul" {}
}
백엔드 구성 파일은 backend 블록의 내용을 최상위 속성으로 갖고, 다른 terraform 블록이나 backend 블록으로 감쌀 필요가 없어요.
address = "demo.consul.io"
path = "example_app/terraform_state"
scheme = "https"
*.backendname.tfbackend(예: config.consul.tfbackend)가 권장 이름 패턴이에요. Terraform이 다른 이름을 막지는 않지만, 이 규칙을 따르면 에디터가 내용을 이해해서 더 좋은 편집 경험을 주는 경우가 많아요.
같은 설정을 명령줄로 지정하려면 이렇게 해요.
$ terraform init \
-backend-config="address=demo.consul.io" \
-backend-config="path=example_app/terraform_state" \
-backend-config="scheme=https"
Consul 백엔드는 Consul 접근 토큰도 필요해요. 위 권장사항대로 구성에서 자격 증명을 빼고 다른 메커니즘을 쓰려면 CONSUL_HTTP_TOKEN 또는 CONSUL_HTTP_AUTH 환경 변수로 토큰을 제공하면 돼요. 백엔드마다 자격 증명을 주는 방법은 해당 백엔드 문서를 확인하세요.
구성을 변경하고 백엔드 제거하기
백엔드 구성은 언제든 바꿀 수 있어요. 구성 자체뿐 아니라 백엔드 타입도 바꿀 수 있어요(예: consul에서 s3로). Terraform은 구성의 변경을 자동으로 감지하고 재초기화를 요청해요. 재초기화 과정에서 기존 상태를 새 구성으로 마이그레이션할지 물어봐요. 이걸로 한 백엔드에서 다른 백엔드로 쉽게 전환할 수 있어요.
워크스페이스를 여러 개 쓰면 Terraform이 모든 워크스페이스를 대상으로 복사할 수 있어요. 워크스페이스가 여러 개 있다고 감지하면 그렇게 할지 물어봐요. 같은 백엔드를 재구성하는 경우에도 Terraform은 상태를 마이그레이션할지 물어보는데, 이때는 "아니오"라고 답하면 돼요.
구성에서 backend 블록을 제거하고 재초기화하면, 기본 local 백엔드로 상태를 마이그레이션할지도 물어봐요.