Terraform/OpenTofu 기초 · plan 읽는 법 · 실습
계획을 읽고 자동으로 판정하기
목표
계획을 파일과 JSON 두 형태로 다루고, 동작·종료 코드·드리프트를 근거로 "이 계획은 사람이 봐야 한다"를 스크립트가 판정하게 만듭니다.
왜 중요한가
인프라 코드에서 가장 비싼 실수는 계획을 잘못 읽는 것입니다. 재생성(-/+)을 제자리 수정(~)으로 착각하면 리소스가 지워졌다 다시 만들어지고, 그 사이의 데이터는 돌아오지 않습니다. 그런데 계획 출력은 길고 배포는 대개 밤에 이뤄지므로, 사람의 눈에만 맡기는 방식은 언젠가 반드시 실패합니다. 그래서 두 가지 장치가 필요합니다. 첫째, 계획을 파일로 저장해 리뷰한 그 계획을 그대로 적용하는 것 — 저장하지 않으면 리뷰한 것과 적용되는 것이 다를 수 있습니다. 둘째, 계획을 기계가 읽는 형식으로 뽑아 규칙으로 판정하는 것 — -detailed-exitcode 의 0/1/2 와 JSON 의 resource_changes, resource_drift 가 그 재료입니다. 이 실습이 끝나면 "삭제가 하나라도 있으면 사람 승인" 같은 규칙을 파이프라인에 넣을 재료가 손에 남습니다.
단계
1. /root/tf/plan 에 local_file 하나와 terraform_data 하나를 포함해 리소스를 두 개 이상 선언하고 초기화하세요. 계획을 /root/tf/plan/plan.tfplan 파일로 저장한 뒤, 그 계획 파일을 JSON 으로 바꿔 /root/tf/plan/out/plan.json 에 저장합니다. .resource_changes 에 항목이 2개 이상이어야 합니다.
2. plan.json 의 .resource_changes[].change.actions 를 세어 /root/tf/plan/out/actions.json 을 만드세요. create, update, delete 세 키를 가진 JSON 이며, 숫자는 계획에서 센 값과 정확히 같아야 합니다.
3. 아직 적용하기 전에 -detailed-exitcode 를 붙여 계획을 실행하고, 그 종료 코드만 /root/tf/plan/out/exitcode-before.txt 에 적으세요. 그다음 적용하고 같은 명령을 다시 돌려 종료 코드를 /root/tf/plan/out/exitcode-after.txt 에 적습니다. 두 파일에는 숫자 하나씩만 들어갑니다.
4. local_file 의 인자를 바꿔 삭제 후 재생성이 나오게 하고, 동시에 terraform_data 의 input 만 바꿔 제자리 수정이 나오게 하세요. 두 변경이 한 계획 안에 함께 들어가도록 계획을 뽑아 JSON 으로 /root/tf/plan/out/replace.json 에 저장합니다.
5. 적용해 상태를 맞춘 뒤, 관리 중인 local_file 의 내용을 Terraform 을 거치지 않고 셸에서 직접 고치세요. 그 상태로 계획을 뽑아 JSON 으로 /root/tf/plan/out/drift.json 에 저장합니다. .resource_drift 에 그 local_file 주소가 잡혀 있어야 합니다.
6. 변경이 두 군데 이상 대기 중인 상태를 만든 뒤 -target 으로 딱 하나만 겨냥한 계획을 JSON 으로 /root/tf/plan/out/target.json 에 저장하세요 (no-op 이 아닌 변경이 정확히 1개). 같은 실행에서 도구가 내는 경고 문구를 /root/tf/plan/out/target-warning.txt 에 남깁니다.
7. /opt/lab/fixtures/terraform/broken/main.tf 를 /root/tf/plan/broken/main.tf 로 복사해 그대로 실행하고, 오류 출력을 /root/tf/plan/out/broken.txt 에 저장하세요 (인자 이름 contents 가 문제라는 메시지가 담겨야 합니다). 그다음 같은 파일을 /root/tf/plan/fixed/main.tf 로 복사해 contents 를 올바른 인자 content 로 고치고, 고친 설정의 계획을 JSON 으로 /root/tf/plan/out/fixed.json 에 저장합니다.
8. 마지막으로 /root/tf/plan 의 설정에서 리소스 하나를 통째로 지워 삭제가 포함된 계획을 만들고, JSON 으로 /root/tf/plan/out/final.json 에 저장하세요. 그 JSON 을 읽어 /root/tf/plan/out/review.json 을 만듭니다. add(동작에 create 가 든 변경 수), change(동작이 ["update"] 인 변경 수), destroy(동작에 delete 가 든 변경 수) 세 숫자와, 삭제 대상 주소를 모두 담은 destructive_addresses 배열, 그리고 verdict 를 needs-review 로 넣으세요.
참고
- 계획 파일은 사람이 읽는 형식이 아닙니다.
terraform show -json plan.tfplan으로 바꿔jq로 다루세요. -detailed-exitcode의 종료 코드는 0(변경 없음), 1(오류), 2(변경 있음)입니다. 명령 바로 뒤에서$?를 읽어야 하며,set -e가 걸린 스크립트에서는 먼저 멈추지 않게 처리해야 합니다.terraform_data는 프로바이더 없이 코어에 내장된 리소스라 이 오프라인 환경에서도 쓸 수 있습니다.input만 바꾸면 제자리 수정이고triggers_replace를 바꾸면 재생성입니다. 반대로local_file은 어느 인자를 바꿔도 재생성입니다.- 7번의
broken/과fixed/는 각각 독립된 작업 디렉터리입니다. 디렉터리마다 따로 초기화해야 계획이 나오고, 오류는 표준 오류로 나가므로2>&1로 함께 파일에 담으세요. - 흔한 실수 1:
-target을 평소 워크플로로 쓰는 것. 도구가 경고를 내는 이유는 그래프 일부만 반영해 상태가 어긋난 채 남을 수 있기 때문입니다. - 흔한 실수 2: 요약 줄에서 재생성을 한 건으로 세는 것. 재생성은 add 와 destroy 양쪽에 1씩 잡히므로 8번의 숫자도 그 기준으로 세야 맞습니다.
단계 8개
- 계획을 파일로 저장하고 JSON 으로 바꾸기
- 동작별 개수 세어 기록하기
- -detailed-exitcode 두 값 확인하기
- 제자리 수정과 재생성을 한 계획에 담기
- 코드 밖 변경을 드리프트로 잡기
- 대상을 좁히고 경고 읽기
- 고장난 설정의 오류 읽고 고치기
- 파괴적 변경 리뷰 보고서 만들기