LabHub

Terraform 실전 · 라이프사이클과 드리프트 · 실습

라이프사이클로 통제하고 드리프트 되돌리기

LabHub 에서 이어서 보기

목표

lifecycle 네 가지 인자로 교체·삭제·무시를 통제하고, 코드 밖에서 생긴 변경을 감지해 두 가지 방향으로 대응한 뒤 그 판정을 스크립트로 자동화합니다.

왜 중요한가

인프라 코드가 어긋나는 방식은 늘 같습니다 — 급한 일이 생겨 누군가 콘솔에서 직접 고치고, 그 변경이 코드로 돌아오지 않는 것입니다. 그 상태로 며칠이 지나면 전혀 다른 이유로 실행된 apply 가 새벽의 응급 조치를 조용히 되돌립니다. 그래서 드리프트 대응에서 진짜 어려운 부분은 명령어가 아니라 방향을 정하는 판단입니다. 응급 조치가 잘못이었다면 코드 기준으로 되돌리고, 옳은 판단이었다면 코드를 실물에 맞춰 고쳐야 합니다. 이 판단 없이 자동 복구를 돌리는 것이 가장 위험합니다. lifecycle 블록은 이 흐름에 미리 개입하는 장치입니다. 특히 ignore_changes 는 오토스케일러처럼 의도적으로 코드 밖에서 변하는 값을 감지 대상에서 빼서 거짓 경보를 줄이고, prevent_destroy 는 지워지면 안 되는 자원에 브레이크를 겁니다. 마지막으로 판정은 사람 눈이 아니라 -detailed-exitcode 로 해야 크론과 CI 에 얹을 수 있습니다.

단계

1. /root/tf/lifecycle/main.tflocal_file 리소스 endpoint 를 선언하세요. 파일 경로는 /root/tf/lifecycle/out/endpoint.txt, 내용은 줄바꿈 없는 한 줄 문자열입니다. 이 리소스의 lifecycle 블록에 create_before_destroy = true 를 넣고 tofu init 후 적용하세요.
2. local_file 리소스 statefile_guard(파일 /root/tf/lifecycle/out/guard.txt)를 추가하고 lifecycleprevent_destroy = true 를 넣어 적용하세요. 그다음 그 리소스만 대상으로 삭제를 시도하고(tofu destroy -target=local_file.statefile_guard) 출력을 표준 오류까지 포함해 /root/tf/lifecycle/out/prevent.txt 로 저장하세요. 거부 메시지가 남아야 하고, 상태의 statefile_guardguard.txt 는 그대로 살아 있어야 합니다.
3. local_file 리소스 하나를 파일 /root/tf/lifecycle/out/managed-note.txt 로 만들되 내용을 ignored-value 로 두고 적용하세요. 그다음 lifecycleignore_changes = [content] 를 넣고 코드의 내용 값만 다른 문자열로 바꾼 뒤 tofu plan 출력을 /root/tf/lifecycle/out/ignore-plan.txt 로 저장하세요. 계획은 No changes 여야 하고 실제 파일 내용은 여전히 ignored-value 여야 합니다.
4. null_resource 리소스 하나를 triggers 로 버전 값을 물고 있게 만들고, local_file 리소스 checksum(파일 /root/tf/lifecycle/out/checksum.txt)에 replace_triggered_by = [null_resource.<이름>] 을 거세요. checksum 자신의 인자는 그대로 둔 채 버전 값만 바꾸고 tofu plan -out=<계획파일> 로 저장한 뒤 tofu show -json <계획파일> 결과를 /root/tf/lifecycle/out/trigger-plan.json 으로 저장하세요. JSON 의 resource_changes 에서 local_file.checksum 의 동작이 두 개(삭제와 생성)여야 합니다. 확인 후 적용하세요.
5. 코드를 거치지 않고 /root/tf/lifecycle/out/endpoint.txt 를 직접 고쳐 내용에 hand-edited 가 들어가게 하세요. 그다음 tofu plan -refresh-only -detailed-exitcode -out=<계획파일> 을 실행해 종료 코드만 /root/tf/lifecycle/out/drift-exit.txt 에 적고(2 여야 합니다), tofu show -json <계획파일> 결과를 /root/tf/lifecycle/out/drift.json 으로 저장하세요. JSON 의 resource_drift 에 endpoint 가 들어 있어야 합니다. 이 계획은 적용하지 마세요.
6. tofu apply 로 실물을 코드 기준으로 되돌리고 출력을 /root/tf/lifecycle/out/remediate.txt 로 저장하세요. Apply complete 문구가 남아야 하고, endpoint.txt 에서 hand-edited 가 사라지고 파일 내용이 상태에 기록된 content 값과 정확히 같아야 합니다.
7. local_file 리소스 quota(파일 /root/tf/lifecycle/out/quota.txt)를 내용 256 으로 적용해 두세요. 이번에는 파일을 손으로 512 로 고친 뒤 되돌리지 말고 main.tf 의 값을 512 로 바꿔 코드에 흡수하고 적용하세요. 그다음 tofu plan 출력을 /root/tf/lifecycle/out/accept-plan.txt 로 저장하면 No changes 여야 하고, quota.txtmain.tf 모두 512 를 담고 있어야 합니다.
8. /root/tf/lifecycle/drift-report.sh 를 만들고 실행 권한을 주세요. 이 스크립트는 -detailed-exitcode 를 쓰는 계획 명령으로 드리프트를 판정하고, 결과를 /root/tf/lifecycle/out/drift-report.jsonexit_code, drift, checked_at, addresses 네 필드로 남겨야 합니다. 실습을 마무리한 시점에는 드리프트가 없어야 하므로 exit_code0, driftfalse 여야 합니다.

참고

단계 8개

  1. create_before_destroy 걸기
  2. prevent_destroy 로 삭제 막기
  3. ignore_changes 로 특정 속성 무시하기
  4. 다른 자원 변경으로 재생성 유발하기
  5. 코드 밖 변경을 드리프트로 감지하기
  6. 코드 기준으로 실물 되돌리기
  7. 드리프트를 코드에 흡수하기
  8. 드리프트 감지 스크립트와 보고서 만들기