변경 계획과 구성 차이
75분 안팎
학습 목표
교체·삭제 영향과 상태 파일 보호를 확인합니다.
개념
계획을 읽는 목적은 영향을 확인하는 것입니다
plan에 변경이 있다는 사실만으로 위험한 배포라고 부르지는 않습니다. 새 실습 네트워크를 만드는 작업과 데이터를 가진 볼륨을 지우는 작업은 영향이 다릅니다. 이번 목표는 변경 종류와 대상 주소를 읽고 자동 적용 가능한 좁은 정책을 만드는 것입니다. 포트 변경이 컨테이너 교체를 유발할 수 있고 서비스가 잠시 중단될 수 있음을 설명합니다. 실제 엔진의 계획 결과를 보지 않고 모든 속성 변경이 같은 방식으로 처리된다고 외우지 않습니다.
기호보다 JSON의 actions를 검사합니다
사람용 plan 화면의 더하기와 빼기는 빠르게 훑기 좋지만 자동 검사는 show -json 결과의 resource_changes를 읽습니다. 각 change.actions에는 create, no-op, update, delete 등이 배열로 들어갑니다. 교체는 delete와 create가 함께 나타나며 순서는 삭제 후 생성 또는 생성 후 삭제일 수 있습니다. 문자열에 delete가 있는지만 화면에서 찾으면 출력 형식과 색 코드에 의존하게 됩니다. JSON 키와 배열을 기준으로 정책을 적고 사람이 원래 화면도 읽어 영향을 확인합니다.
허용 목록은 대상과 동작을 함께 제한합니다
이번 정책은 docker_network.notice, docker_volume.data, docker_container.notice 세 주소만 허용합니다. 동작은 create 또는 no-op 단독 배열만 통과시킵니다. 처음 자원을 만들거나 이미 수렴한 상태는 이 정책에 맞지만 update는 내용에 따라 의미가 달라 차단합니다. 예상 밖 docker_container.other가 단순 create여도 거부합니다. 변경이 비파괴적이라는 이유만으로 다른 프로젝트를 자동 수정할 수 있게 만들지 않습니다. 대상 범위와 변경 종류는 독립적인 제한입니다.
교체 순서 둘 다 막습니다
starter는 delete 다음 create를 허용 동작에 포함해 교체 하나를 통과시킵니다. 새 컨테이너를 만들기 전에 기존 컨테이너를 지우면 서비스 중단이 생길 수 있습니다. 생성 후 삭제도 자동으로 무해하지 않습니다. 동일 이름이나 호스트 포트를 동시에 사용할 수 없을 수 있고 볼륨 쓰기가 겹치면 데이터 문제가 남습니다. check-review.py는 두 배열 순서를 별도 fixture로 검사합니다. 한 순서만 거부하는 수정 대신 허용할 동작만 명시하는 방식으로 결함을 고칩니다.
빈 변경과 누락 자료를 구분합니다
resource_changes가 빈 배열이면 자원 변경이 없는 자료로 읽습니다. 키 자체가 없으면 자료가 불완전하거나 다른 형식일 수 있어 거부합니다. malformed JSON은 파싱 단계에서 실패하며 오류 계획의 errored=true도 차단합니다. 모든 JSON을 빈 변경으로 기본 처리하면 다운로드가 잘못되었거나 다른 파일을 읽어도 배포가 허용됩니다. 성공하기 쉬운 기본값보다 판단할 근거가 충분한지를 먼저 확인합니다. deferred_changes가 있으면 이번 정책은 미뤄진 변경을 별도 리뷰 대상으로 보냅니다.
fixture의 주장 범위를 지킵니다
제공된 port-change.json은 Docker provider를 실행하여 얻은 실제 plan이 아니라 delete와 create가 함께 있는 교육 fixture입니다. 포트 변경의 실제 actions는 외부 환경에서 tofu plan과 show로 관찰합니다. Python 검사 성공은 정책 함수가 정해진 입력을 분류했다는 의미입니다. HCL 파싱·Docker 자원 생성·드리프트 탐지를 완료했다는 뜻은 아닙니다. 보고서에 fixture 결과와 실제 자원 검증 결과를 나누어 적어야 검토자가 남은 위험을 파악할 수 있습니다.
드리프트는 원하는 설정과 실제의 차이입니다
동료가 Docker 화면에서 포트나 라벨을 바꾸면 저장소 설정과 실제 자원이 다를 수 있습니다. 기본 plan은 현재 원격 자원을 읽고 차이를 비교합니다. 설정 변경으로 생긴 차이와 수동 변경으로 생긴 차이를 둘 다 조사합니다. -refresh=false로 외부 변경을 숨긴 계획을 수렴 증거로 쓰지 않습니다. 비상 작업으로 실제 구성을 바꿨다면 어느 값을 코드에 반영할지, 원래 설정으로 되돌릴지 판단하고 변경 기록을 남깁니다. 상태만 갱신하는 절차도 의도와 다르게 설정을 고치지는 않습니다.
두 번째 plan 종료 상태를 정확히 읽습니다
-detailed-exitcode를 지정한 plan은 성공하고 변경이 없으면 0, 오류이면 1, 성공하고 변경이 있으면 2를 반환합니다. 셸에서 비영 상태를 전부 같은 오류로 처리하면 필요한 변경과 실행 실패를 구분하지 못합니다. check.sh는 상태를 따로 저장하고 두 번째 계획이 0인지 확인합니다. 2가 나오면 어떤 변경이 남았는지 JSON과 화면을 보고 해결합니다. stdout에 No changes가 보인다는 문자열 하나만으로 성공을 판정하지 않습니다.
데이터 삭제는 별도 보존 판단입니다
volume prevent_destroy는 데이터 자원 삭제를 실수로 진행하는 것을 줄이지만 백업을 대신하지 않습니다. 설정에서 해당 자원 블록을 통째로 제거하면 보호 조건도 제거될 수 있으므로 plan의 삭제 검사도 함께 필요합니다. 리뷰 정책은 docker_volume.data의 delete를 차단합니다. 정리하려면 데이터를 보존할지 결정하고 백업의 복원 가능성을 확인한 뒤 승인된 정리 계획을 만듭니다. fixture를 통과시키려고 prevent_destroy와 delete 검사를 동시에 없애면 학습 목표를 충족하지 못합니다.
상태 보호는 ignore와 실제 추적을 함께 봅니다
gitignore에 terraform.tfstate를 적어도 이미 추적된 파일은 자동으로 빠지지 않습니다. state-check.py는 임시 Git 저장소에서 제외 패턴이 동작하는지 검사하고 실제 실행 위치에서도 추적된 상태 파일을 조사합니다. 상태와 plan을 다른 사람에게 보내기 전 민감한 값의 유무와 권한을 확인합니다. sensitive 표시는 화면 출력을 숨기는 기능이며 저장 파일에서 모든 비밀을 제거하는 기능으로 설명하지 않습니다. 운영 비밀을 넣지 않은 교육 환경에서도 보존 정책을 연습합니다.
검토할 계획과 적용할 계획을 연결합니다
initial.tfplan을 만들고 JSON으로 리뷰한 뒤 같은 파일을 apply에 전달합니다. 리뷰 후 입력이나 설정을 바꾸었다면 새 계획을 만들고 검토합니다. 저장 계획 파일도 신뢰한 출처에서 보관하고 덮어쓰기 여부를 확인합니다. 자동 정책의 ALLOW는 제한한 대상과 동작이 맞다는 뜻이지 서비스 성능과 사용자 요청 성공까지 증명하지 않습니다. 적용 뒤의 HTTP 확인과 수렴 검사는 별도 단계로 유지합니다. 계획 리뷰와 실행 결과 확인을 서로 대체하지 않습니다.
완성한 검사를 동료에게 설명합니다
수정한 review.py와 fixture 10개 결과를 제출하고 어떤 입력에서 starter의 결함이 드러났는지 적습니다. 실제 계획을 받을 때는 Python 검사와 사람 검토를 모두 수행합니다. update를 허용해야 하는 새 정책이 생기면 속성별 위험과 승인 기준을 정하고 새로운 실패 fixture를 먼저 추가합니다. 모든 update를 허용하는 한 줄 수정은 정책 확대 이유를 설명하지 못합니다. 면접에서는 주소·경로·접근 경계가 plan의 자원 변경과 어떻게 이어지는지 실제 안내판 사례로 답합니다.
계획과 종료 상태의 정의는 OpenTofu plan 공식 문서에서 확인합니다.
따라하기
교체 자료 읽기
레슨 zip의 port-change.json은 교육 fixture입니다. actions 두 동작과 before/after의 외부 포트 차이를 읽습니다.
cat port-change.jsonstarter 검사
bash check.sh에서 replace-delete-first 실패를 확인하고 review.py의 허용 목록에서 교체를 제거합니다. 검사 자체를 수정하지 않습니다.
bash check.sh수정 후 재검사
solution에서 직접 실행한 fixture 결과를 기록했습니다. 이 성공은 실제 OpenTofu 실행 결과를 뜻하지 않습니다.
bash check.sh실행 결과
PASS create PASS no-op PASS replace-delete-first PASS replace-create-first PASS delete-volume PASS update-port PASS unexpected-resource PASS missing PASS empty PASS errored RESULT: 0 failure(s); plan fixtures only
실제 계획과 상태 확인
미션 루트에서 실제 plan JSON을 내보내 리뷰합니다. state-check.py는 ignore 정책과 이미 추적된 상태 파일을 확인합니다. 실제 변경은 외부 담당자가 확인합니다.
tofu plan -out=reviewed.tfplan
tofu show -json reviewed.tfplan > plan-review.json
python3 -B review.py plan-review.json
python3 -B state-check.py확인 문제
실습
review.py에서 교체를 허용하는 결함을 고칩니다. create와 no-op만 예상 주소에서 허용하고 교체 두 순서·삭제·update·예상 밖 자원·누락 자료를 거부합니다. check.sh는 Python fixture만 실행합니다.
실행 명령
bash check.sh
기대 결과
RESULT: 0 failure(s); plan fixtures only
모범 답안
모범 답안 내려받기더 읽기
면접 질문
- VPC·서브넷·보안그룹의 역할을 설명합니다.