Terraform state 파일 보안: 인프라 코드의 그림자 데이터
state 파일에 남는 비밀값과 인프라 구조 정보를 보호하기 위해 암호화, 접근 통제, 분리 저장소를 점검한다. Terraform·IaC Security·Secrets 관점에서 구성 요소의 역할부터 적용 순서, 운영 확인 항목, 복구 기준까지 단계별로 설명한다.
핵심 요약
Terraform state는 단순 캐시가 아니라 리소스 식별자, 네트워크 구조, 출력값, 때로는 비밀값까지 담는 민감한 운영 데이터다. 원격 저장, 암호화, 최소 권한, 버전 관리, 잠금, 접근 로그와 복구 테스트를 적용하고, sensitive 표시가 state 자체를 암호화하지 않는다는 점을 전제로 설계해야 한다.
Terraform 코드는 검토와 버전 관리가 잘 돼 있어도 state 파일은 같은 수준으로 관리되지 않는 경우가 많다. 로컬 노트북의 terraform.tfstate, CI 작업 디렉터리, 백업 파일, 디버그 아티팩트, terraform_remote_state를 통해 인프라 구조와 민감한 값이 여러 곳에 복제될 수 있다.
state는 Terraform이 실제 리소스와 구성을 연결하기 위해 필요한 운영 기록이다. 따라서 삭제하거나 숨길 대상이 아니라 고권한 데이터 저장소로 분류해 수명주기 전체를 통제할 대상이다. 백엔드와 Terraform 버전에 따라 기능이 다르므로 적용 전 공식 문서와 클라우드 저장소 설정을 확인한다.
state에 무엇이 들어가는지 가정하지 말고 검사한다
state에는 다음 정보가 포함될 수 있다.
- 클라우드 리소스 ID, 계정·프로젝트·리전, 네트워크 주소와 엔드포인트
- 데이터베이스 사용자명, 연결 문자열, 인증서 메타데이터
- provider가 반환한 속성과 모듈 output
sensitive = true로 표시했지만 state에는 저장되는 값- 과거 버전에 남은 삭제 전 비밀과 리소스 정보
- 다른 워크스페이스가 읽을 수 있는 root output
sensitive 표시는 CLI와 UI 출력에서 값을 가리는 데 도움을 주지만 state 파일 안의 값을 자동으로 암호화하거나 제거하지 않는다. 가능한 경우 비밀을 Terraform이 직접 생성·보관하지 않도록 외부 비밀 관리 서비스, 짧은 수명 자격 증명, ephemeral 기능을 검토한다.
안전한 백엔드의 최소 조건
| 통제 | 요구사항 | 검증 방법 |
|---|---|---|
| 원격 저장 | 개인 노트북과 CI 로컬 디스크에 영구 보관하지 않음 | 저장 위치와 작업 종료 후 파일 확인 |
| 저장 암호화 | 관리형 또는 고객 관리 키로 암호화 | 저장소·키 정책과 암호화 상태 조회 |
| 전송 보호 | TLS를 통한 접근 | 백엔드 엔드포인트와 프록시 설정 점검 |
| 최소 권한 | 계획·적용·읽기·관리 권한 분리 | 역할별 실제 허용 작업 테스트 |
| 상태 잠금 | 동시 apply 충돌 방지 | 병렬 실행에서 잠금 동작 확인 |
| 버전 관리 | 손상·오삭제 시 이전 버전 복구 | 이전 state 복원 리허설 |
| 감사 로그 | 읽기·쓰기·삭제·정책 변경 기록 | SIEM 수집과 경보 테스트 |
| 삭제 보호 | 버킷·컨테이너·워크스페이스 오삭제 방지 | 보호 설정과 비상 해제 승인 |
백엔드 접근 권한은 인프라 변경 권한과 동일하지 않을 수 있다. state를 읽는 것만으로도 민감한 정보가 노출될 수 있으므로 “읽기 전용”을 저위험 권한으로 취급하면 안 된다.
환경과 영향 범위를 분리한다
하나의 거대한 state에 모든 환경과 서비스를 넣으면 한 번의 손상과 잠금 문제가 전체 인프라로 확장된다. 다음 경계를 고려한다.
- 운영과 비운영 환경의 별도 계정·프로젝트·백엔드
- 서비스 또는 수명주기가 다른 리소스의 별도 state
- 네트워크 기반과 애플리케이션 리소스의 변경 권한 분리
- 보안·감사 인프라를 일반 배포 state와 분리
- 고객·리전별 격리가 필요한 경우 별도 워크스페이스 또는 백엔드
분할이 지나치면 원격 state 참조와 운영 복잡도가 늘어난다. 경계는 팀 구조가 아니라 장애 반경, 권한, 변경 빈도, 복구 순서에 맞춰 정한다.
CI/CD 자격 증명을 짧게 만든다
CI에 장기 클라우드 키와 백엔드 비밀번호를 저장하는 대신 OIDC 기반 연합 또는 짧은 수명 역할을 사용한다. 계획 단계와 적용 단계의 권한을 분리하고, 운영 apply는 승인된 브랜치·환경·런너에서만 수행한다.
- PR 계획 작업은 가능한 읽기와 plan에 필요한 권한만 갖는다.
- apply 토큰은 승인 후에만 발급하고 작업 종료 시 만료된다.
- 백엔드 자격 증명을 HCL 파일이나 CLI 히스토리에 남기지 않는다.
- plan 파일도 민감한 값이 포함될 수 있으므로 아티팩트 접근과 보존을 제한한다.
- CI 로그에서 provider 디버그 출력과 환경 변수를 마스킹한다.
- 자체 호스팅 러너의 작업 디렉터리와 캐시를 종료 후 정리한다.
terraform_remote_state 사용을 최소화한다
다른 state의 output 몇 개를 읽기 위해 원격 state 전체에 접근 권한을 주는 구조는 과도한 노출이 될 수 있다. 가능하면 DNS, 파라미터 저장소, 비밀 관리 서비스, provider 데이터 소스처럼 필요한 값만 게시하고 읽는 인터페이스를 사용한다.
반드시 remote state를 사용해야 한다면 다음을 적용한다.
- 소비 워크스페이스를 명시적으로 허용한다.
- 공개할 output을 최소화하고 비밀값을 넣지 않는다.
- 읽기 관계를 서비스 지도와 소유자 목록에 기록한다.
- 사용하지 않는 state 공유 권한을 정기적으로 회수한다.
- state 분할·이동 때 참조 관계와 롤백을 테스트한다.
실패 모드와 탐지 신호
| 신호 | 의심할 문제 | 우선 대응 |
|---|---|---|
| 사람 계정의 원시 state 다운로드 | 조사·편의 목적의 과도한 접근 | 사유 확인, 세션·다운로드 경로 점검 |
| CI 외 IP·시간대의 state 읽기 | 자격 증명 탈취 | 토큰 폐기, 접근 로그와 클라우드 활동 조사 |
| 버전 관리·암호화 설정 변경 | 방어 통제 약화 | 변경자·승인 티켓·후속 접근 확인 |
| 잠금 없는 동시 apply | state 손상과 충돌 | 실행 중단, 최신 정상 버전 식별 |
.tfstate가 Git·아티팩트에 등장 | 로컬 또는 CI 유출 | 저장소 이력 제거, 비밀 회전 |
| state 크기·리소스 수 급변 | 잘못된 workspace·대량 삭제 | plan과 실제 클라우드 리소스 비교 |
| backend 정책이 광범위해짐 | 권한 경계 붕괴 | 최근 IAM 변경과 사용 주체 확인 |
비밀 패턴 스캔은 Git 저장소뿐 아니라 CI 아티팩트, 지원 번들, 채팅 첨부, 백업 위치까지 확장한다.
state 유출이 의심될 때
- state 저장소를 삭제하지 말고 접근 로그와 버전을 보존한다.
- 누가 어떤 버전을 읽었는지와 외부 공유 여부를 확인한다.
- state에 존재할 수 있는 비밀·토큰·인증서를 목록화한다.
- 영향이 큰 자격 증명부터 회전하되 서비스 중단 순서를 계획한다.
- 짧은 수명 토큰이 이미 발급됐는지 클라우드 감사 로그를 조사한다.
- 백엔드·CI·개인 계정의 권한을 최소화하고 의심 세션을 폐기한다.
- 과거 state 버전과 백업에도 폐기된 비밀이 남아 있음을 고려한다.
- 사고 커뮤니케이션 절차에 따라 확인 범위를 관리한다.
state 복원과 백엔드 장애는 재해복구 탁상훈련에 포함한다. 복원 파일이 있다고 끝내지 말고 격리 환경에서 plan을 실행해 실제 리소스와 안전하게 맞는지 확인한다.
운영 체크리스트
- 모든 운영 state가 승인된 원격 백엔드에 있다.
- 저장·전송 암호화, 버전 관리, 잠금, 삭제 보호가 켜져 있다.
- state 읽기 권한을 고위험 권한으로 분류한다.
- 운영·비운영과 주요 장애 반경이 별도 state로 나뉜다.
- CI는 짧은 수명 자격 증명을 사용하고 plan/apply 권한이 분리된다.
- plan·state 아티팩트의 접근과 보존 기간을 제한한다.
-
sensitive표시가 state 값을 제거하지 않는다는 점을 리뷰 기준에 넣는다. - 원시 state 다운로드와 백엔드 정책 변경을 경보로 만든다.
- 이전 정상 버전 복원 절차를 정기적으로 시험한다.
함께 읽을 글
state 접근에 사용하는 최고 권한은 관리자 비상 계정 운영과 분리해야 한다. 비정상 리소스 생성은 클라우드 비용 이상 징후와 함께 탐지하면 빠르다.
참고 기준
- HashiCorp: Manage Sensitive Data
- HashiCorp: Remote State
- HashiCorp: Backend Credentials and Sensitive Data
- HashiCorp: Sensitive State Best Practices
결론
Terraform state는 코드의 부산물이 아니라 인프라의 그림자 데이터베이스다. 암호화된 원격 저장, 최소 권한, 짧은 자격 증명, 감사 로그, 버전 복구와 비밀 최소화를 함께 적용해야 IaC가 편리함 때문에 새로운 비밀 저장소가 되는 것을 막을 수 있다.
전체 댓글 0개