티스토리 뷰
요약
Terraform Drift는 Terraform 코드, 상태 파일, 실제 클라우드 리소스가 서로 다른 방향으로 움직이면서 생기는 운영 불일치다. 단순히 "누가 콘솔에서 바꿨다"의 문제가 아니라 장애 대응, 긴급 권한, 자동 확장, 외부 정책, 여러 도구의 동시 사용이 얽힌 결과인 경우가 많다.
이 글에서는 Terraform Drift가 왜 생기는지, AWS와 Azure 운영에서는 어떻게 드러나는지, 그리고 실무자가 어떤 절차로 탐지하고 대응해야 하는지 정리한다.
이 글이 필요한 사람
Terraform으로 AWS나 Azure 인프라를 관리하지만, 운영 중 콘솔 변경, 긴급 수정, 보안 정책 변경 때문에 terraform plan 결과가 예상과 달라지는 경험을 한 엔지니어를 위한 글이다.
또한 IaC를 도입했지만 아직 "코드가 진짜 기준인가, 실제 인프라가 기준인가"를 팀 안에서 명확히 합의하지 못한 조직에도 도움이 된다.
왜 지금 Drift를 다시 봐야 할까
IaC는 더 이상 신규 인프라를 한 번 배포하는 도구에 머물지 않는다. 랜딩존, Kubernetes 클러스터, 네트워크, 보안 그룹, IAM, 모니터링, 데이터 플랫폼까지 장기간 운영되는 리소스를 계속 관리한다.
문제는 실제 운영 환경이 항상 Terraform만 통해 바뀌지는 않는다는 점이다.
- 장애 중에 콘솔에서 보안 그룹을 임시로 열 수 있다.
- 운영자가 Azure Portal에서 태그나 진단 설정을 수정할 수 있다.
- 보안팀이 정책 도구로 리소스 설정을 자동 보정할 수 있다.
- 클라우드 서비스가 기본값이나 관리형 리소스를 자동으로 추가할 수 있다.
- 여러 Terraform workspace, CI/CD 파이프라인, 수동 CLI 작업이 같은 리소스를 건드릴 수 있다.
이런 변화가 쌓이면 Terraform은 다음 실행 시 실제 인프라를 다시 코드에 맞추려 하거나, 반대로 상태 파일만 실제 값에 맞추는 선택을 요구한다. 그래서 Drift 대응은 단순한 명령어 문제가 아니라 운영 프로세스 문제다.
Terraform Drift의 세 가지 기준
Drift를 이해하려면 세 가지 기준을 분리해서 봐야 한다.
| 기준 | 의미 | 어긋났을 때 생기는 문제 |
|---|---|---|
| Terraform 코드 | Git에 저장된 의도한 인프라 정의 | 코드 리뷰와 승인 없이 운영 변경이 누락됨 |
| Terraform state | Terraform이 알고 있는 현재 관리 대상과 속성 | Terraform이 잘못된 기준으로 변경 계획을 계산함 |
| 실제 클라우드 리소스 | AWS, Azure에 존재하는 실제 설정 | 운영 상태가 코드와 다르게 동작함 |
HashiCorp 문서에서도 Terraform 상태 파일은 Terraform이 관리하는 리소스 기록이며, Terraform 외부에서 리소스를 변경하면 상태와 실제 인프라가 어긋날 수 있다고 설명한다. 이 상태에서 Terraform이 조정 작업을 수행하면 의도하지 않은 삭제나 재생성이 발생할 수 있다.
중요한 점은 Drift가 항상 나쁜 변경을 뜻하지는 않는다는 것이다. 장애 대응 중 임시로 바꾼 설정은 당시에는 필요한 조치였을 수 있다. 다만 그 변경이 코드와 운영 기록으로 돌아오지 않으면 이후 배포에서 위험이 된다.
Drift가 자주 생기는 원인
1. 긴급 장애 대응 후 코드 반영이 누락된다
가장 흔한 사례는 장애 중 임시 조치다. 예를 들어 애플리케이션 연결 장애를 해결하려고 AWS Security Group 인바운드 규칙을 콘솔에서 수정하거나, Azure Network Security Group 규칙을 Portal에서 바꾸는 경우다.
장애는 해결됐지만 변경 이유, 만료 시점, Terraform 코드 반영 여부가 남지 않으면 다음 terraform plan에서 "되돌릴 변경"으로 나타난다. 이때 운영자는 두 가지 중 하나를 결정해야 한다.
- 임시 변경이 불필요하면 Terraform으로 원래 코드 상태로 되돌린다.
- 임시 변경이 정식 운영 요구사항이면 Terraform 코드에 반영하고 리뷰한다.
2. 콘솔과 CLI가 Terraform보다 빠르다고 느껴진다
IaC가 느리게 느껴지는 팀에서는 콘솔 변경이 계속 생긴다. 특히 태그, 모니터링 설정, 알람 임계값, 보안 그룹 규칙, IAM 정책처럼 작은 변경은 "잠깐만 수정"하기 쉽다.
하지만 이런 작은 변경이 반복되면 Terraform은 더 이상 운영 현실을 설명하지 못한다. IaC의 핵심 가치는 자동 배포가 아니라 재현 가능한 운영 기준을 유지하는 데 있다.
3. 자동화 도구끼리 같은 리소스를 관리한다
Terraform, CloudFormation, Azure Policy, Kubernetes 컨트롤러, 보안 자동화 도구, 비용 최적화 도구가 같은 속성을 건드릴 수 있다. 예를 들어 태그는 FinOps 도구가 붙이고, 보안 설정은 정책 도구가 보정하며, 네트워크는 Terraform이 관리하는 식이다.
이 경우 "누가 최종 소유자인가"가 명확하지 않으면 Drift는 계속 재발한다. 모든 리소스를 Terraform으로만 관리해야 한다는 뜻은 아니다. 다만 리소스별, 속성별 소유권은 정해야 한다.
4. 클라우드 서비스의 관리형 리소스를 코드로 과하게 통제한다
관리형 Kubernetes, 데이터베이스, 로드밸런서, 모니터링 서비스는 사용자가 직접 정의하지 않은 하위 리소스나 기본값을 만들 수 있다. Azure Deployment Stacks 문서도 AKS 같은 관리형 서비스가 내부적으로 생성하는 리소스는 사용자가 Bicep 파일에 명시한 리소스와 다르게 취급될 수 있음을 설명한다.
운영자는 "Terraform이 직접 관리해야 하는 리소스"와 "클라우드 서비스가 생성하고 관리하는 리소스"를 구분해야 한다. 그렇지 않으면 정상적인 플랫폼 동작을 Drift로 오해할 수 있다.
Drift를 탐지하는 기본 흐름
Terraform에서는 보통 terraform plan만으로도 실제 리소스와 상태를 비교하면서 변경 계획을 확인한다. 다만 운영 중 외부 변경이 의심될 때는 -refresh-only를 분리해서 보는 편이 안전하다.
terraform plan -refresh-only
Terraform 문서에 따르면 -refresh-only 모드는 원격 객체에서 발생한 외부 변경을 반영해 Terraform state와 루트 모듈 output을 업데이트하는 계획을 만든다. 즉 인프라를 코드에 맞춰 고치는 명령이 아니라, Terraform이 알고 있는 기록을 실제 인프라와 맞출지 검토하는 단계다.
실무에서는 다음 순서가 좋다.
- 정기적으로
terraform plan또는terraform plan -refresh-only를 실행한다. - 변경 결과를 리소스별로 분류한다.
- 장애 대응, 정책 자동화, 콘솔 변경, provider 기본값 변화 중 어떤 원인인지 확인한다.
- 되돌릴 변경과 코드에 반영할 변경을 나눈다.
- Git PR, Change Ticket, Incident Record 중 하나에 의사결정 근거를 남긴다.
HCP Terraform은 workspace health assessment에서 drift detection을 제공하며, 실제 인프라가 Terraform 구성과 달라진 상황을 식별하고 동기화에 필요한 변경을 제안하는 기능을 제공한다. 다만 HashiCorp 문서상 configuration drift와 state drift는 구분되므로, 도구가 무엇을 탐지하는지 범위를 확인해야 한다.
AWS 운영에서 보는 Drift
AWS에서는 Terraform만 Drift를 다루는 것이 아니다. CloudFormation도 stack drift detection 기능을 제공한다. AWS 문서에 따르면 CloudFormation은 스택 또는 개별 리소스의 실제 설정이 기대 설정과 다른지 탐지할 수 있고, 삭제된 리소스도 Drift로 볼 수 있다.
하지만 CloudFormation drift detection도 모든 리소스와 모든 속성을 완벽히 비교하는 것은 아니다. AWS 문서는 drift detection을 지원하지 않는 리소스는 NOT_CHECKED로 표시될 수 있으며, CloudFormation이 템플릿 속성과 실제 리소스 속성을 다시 매핑할 수 없는 경우도 있다고 설명한다.
Terraform을 AWS에서 운영할 때는 다음 관점을 같이 봐야 한다.
- Security Group, IAM Policy, Route Table, S3 Bucket Policy처럼 보안 영향이 큰 리소스는 Drift 알림 우선순위를 높인다.
- AWS Config, CloudTrail, EventBridge 같은 운영 로그와 변경 이벤트를 함께 확인한다.
- CloudFormation으로 만든 리소스와 Terraform으로 만든 리소스의 경계를 명확히 한다.
- 장애 대응으로 콘솔 변경을 허용하더라도 만료 시간과 코드 반영 책임자를 정한다.
특히 네트워크와 IAM의 Drift는 비용보다 보안과 장애 영향이 크다. Terraform plan 결과를 단순히 "변경 수"로만 보지 말고, 어떤 리소스 계층에서 발생했는지를 먼저 봐야 한다.
Azure 운영에서 보는 Drift
Azure에서는 ARM template과 Bicep을 사용할 때 what-if 기능이 중요하다. Microsoft 문서에 따르면 ARM what-if는 배포 전에 지정한 템플릿을 적용하면 어떤 변경이 생길지 미리 보여주며, 기존 리소스를 실제로 변경하지 않는다.
az deployment group what-if \
--resource-group <resource-group-name> \
--template-file main.bicep
what-if는 Terraform drift detection과 완전히 같은 기능은 아니지만, 배포 전에 예상 변경을 검토한다는 점에서 운영 안전장치로 유용하다. 다만 Microsoft 문서도 일부 기본값이나 템플릿에 없는 속성이 삭제처럼 보이는 noise가 있을 수 있다고 설명한다. 따라서 결과를 자동 승인 기준으로만 쓰기보다는 리뷰 입력값으로 다뤄야 한다.
Azure Deployment Stacks는 Bicep 기반 리소스 묶음을 관리하고, 관리되지 않게 된 리소스를 detach하거나 삭제하는 흐름을 제공한다. 또한 deny settings를 통해 관리 리소스에 대한 삭제나 수정 권한을 제한할 수 있다. 이 기능은 Drift를 사후에 찾는 것뿐 아니라, 애초에 잘못된 수동 변경을 줄이는 운영 통제 수단으로 볼 수 있다.
Terraform을 Azure에서 사용할 때도 같은 원칙이 적용된다. Azure Policy, Portal 변경, Bicep deployment, Terraform workspace가 같은 리소스를 동시에 관리하지 않도록 소유권을 나누는 것이 우선이다.
Drift 대응은 세 가지 중 하나다
Drift를 발견했을 때 선택지는 보통 세 가지다.
1. 코드 기준으로 되돌린다
변경이 실수였거나 임시 조치였고 더 이상 필요 없다면 Terraform apply로 실제 인프라를 코드 상태에 맞춘다. 이 방식은 가장 단순하지만, 장애 중 필요한 변경을 무심코 되돌릴 수 있으므로 리뷰가 필요하다.
2. 실제 변경을 코드에 반영한다
운영 중 변경이 정식 요구사항으로 확인되면 Terraform 코드에 반영한다. 새로 만들어진 리소스라면 terraform import나 configuration-driven import를 검토할 수 있다. 기존 리소스의 속성 변경이라면 코드 수정 후 plan 결과가 안정적인지 확인한다.
이 방법이 IaC 원칙에 가장 잘 맞는다. 실제 운영에서 생긴 학습을 코드로 되돌려 다음 배포부터 재현 가능하게 만들기 때문이다.
3. Terraform 관리 대상에서 제외하거나 소유권을 분리한다
모든 속성을 Terraform이 통제해야 하는 것은 아니다. 예를 들어 자동 스케일링으로 바뀌는 값, 운영 도구가 주기적으로 조정하는 설정, 관리형 서비스가 생성하는 내부 리소스는 Terraform의 직접 관리 범위에서 빼는 편이 나을 수 있다.
이때는 lifecycle ignore_changes 같은 기능을 사용할 수 있지만, 남용하면 Terraform 코드가 실제 운영 상태를 설명하지 못하게 된다. ignore_changes는 "우리가 이 속성의 소유자가 아니다"라는 설계 결정으로 기록해야 한다.
운영팀을 위한 Drift 관리 체크리스트
- 리소스별 소유권을 정한다. Terraform, CloudFormation, Bicep, Azure Policy, 수동 운영 중 누가 어떤 속성을 관리하는지 문서화한다.
- 정기 Drift 점검을 CI/CD 또는 예약 작업에 넣는다. 운영 계정은 최소 매일, 중요 네트워크와 IAM은 더 짧은 주기로 확인한다.
- Drift 결과를 심각도별로 나눈다. IAM, 네트워크, 공개 접근, 암호화, 백업, 로깅 설정은 우선순위를 높인다.
- 장애 대응 변경은 만료 시간을 둔다. 긴급 수정은 허용하되, 복구 후 Terraform 코드 반영 또는 원복 여부를 반드시 결정한다.
terraform apply -refresh-only는 자동화하지 않는다. 상태 파일 업데이트는 실제 인프라 변경 없이도 운영 기준을 바꾸는 일이므로 리뷰가 필요하다.- provider 버전과 모듈 버전을 고정하고 변경 이력을 남긴다. provider 기본 동작 변화가 Drift처럼 보일 수 있다.
- Drift를 사람 탓으로만 처리하지 않는다. 반복되는 Drift는 운영 프로세스나 도구 소유권 설계의 신호다.
흔한 실수
terraform plan에 차이가 나오면 무조건 apply한다. Drift의 원인이 장애 대응인지, 보안 자동화인지, 실수인지 확인하지 않으면 정상 조치를 되돌릴 수 있다.- state를 실제 인프라에 맞추는 것과 코드를 실제 인프라에 맞추는 것을 혼동한다. state만 맞추면 다음 사람이 코드를 봤을 때 운영 의도를 이해하지 못한다.
ignore_changes로 모든 잡음을 숨긴다. 당장은 plan이 조용해지지만, 장기적으로는 IaC가 운영 기준이라는 신뢰를 잃는다.- 콘솔 변경을 전면 금지하면 해결된다고 생각한다. 실제 장애 대응에서는 예외가 필요하다. 중요한 것은 예외를 기록하고 코드로 회수하는 절차다.
- Drift 탐지를 보안팀이나 플랫폼팀 한쪽 책임으로만 둔다. 서비스팀, 플랫폼팀, 보안팀이 같은 변경 기록을 봐야 한다.
실무적인 결론
Terraform Drift는 IaC 도입 실패의 증거가 아니라, IaC가 실제 운영과 만나기 시작했다는 신호에 가깝다. 중요한 것은 Drift를 없애겠다는 목표보다, Drift가 생겼을 때 어떤 기준으로 판단하고 누가 코드에 반영할지 정하는 것이다.
운영팀은 terraform plan 결과를 단순 변경 목록이 아니라 운영 의도와 실제 인프라의 차이를 보여주는 리뷰 자료로 봐야 한다. 콘솔 변경을 완전히 막는 것보다, 예외를 짧게 허용하고 코드로 되돌리는 루프를 만드는 것이 더 현실적인 IaC 운영 방식이다.
참고자료
- HashiCorp Developer, Manage resource drift: https://developer.hashicorp.com/terraform/tutorials/state/resource-drift
- HashiCorp Developer, Terraform plan command reference: https://developer.hashicorp.com/terraform/cli/commands/plan
- HashiCorp Developer, Health assessments in HCP Terraform: https://developer.hashicorp.com/terraform/cloud-docs/workspaces/health
- AWS CloudFormation User Guide, Detect unmanaged configuration changes with drift detection: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html
- Microsoft Learn, ARM template deployment what-if: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deploy-what-if
- Microsoft Learn, Azure deployment stacks in Bicep: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deployment-stacks
'IaC > Terraform' 카테고리의 다른 글
| [Terraform] 많이 사용 Meta Argument 4편 - max (0) | 2022.10.14 |
|---|---|
| [Terraform] 많이 사용 Meta Argument 3편 - element (0) | 2022.10.02 |
| [Terraform] 많이 사용 Meta Argument 2편 - format (0) | 2022.10.02 |
| [Terraform] 많이 사용 Meta Argument 1편 - count (0) | 2022.10.02 |
| Alicloud에서 Terraform을 활용하여 3tire 구축하기 (0) | 2021.06.17 |
- Total
- Today
- Yesterday
