Devin.KR

데이터 보존과 의존 순서 정리

90분 안팎

학습 목표

자원 삭제 전 범위·백업·의존성을 확인합니다.

개념

삭제의 완료 기준을 바꿉니다

자원이 목록에서 사라진 것만으로 정리 작업이 성공한 것은 아닙니다. 안내판 내용과 배포·복구 증거는 남아 있어야 하고 다른 프로젝트 자원은 유지되어야 합니다. 이번 레슨의 완료 기준은 대상 자원 0, 보존 데이터 복원 성공, 보존 파일 해시 일치, 비실습 자원 동일입니다. 계획 검사와 실제 삭제 검사를 나누어 준비합니다. 레슨 zip은 삭제 계획 정책을 연습하며 원본 state를 제공하지 않습니다. 실제 자원 정리는 앞 프로젝트를 이어받은 최종 미션에서 수행합니다.

상태와 실제 자원을 대조합니다

m05/m06에서 만든 terraform.tfstate는 코드 주소와 Docker 실제 자원을 연결합니다. 정확한 작업 공간에서 tofu state list와 state show로 주소·이름을 확인하고 Docker inspect의 bootcamp.project 라벨과 대조합니다. 원본 state가 없으면 새 state를 만들어 기존 자원을 지우려 하지 않습니다. 복구 가능한 원본 사본과 사용한 작업 경로를 먼저 찾습니다. state에는 민감정보가 들어갈 수 있으므로 공개 제출물에 넣지 않습니다. 서로 다른 개인 프로젝트 state를 한 폴더에 합치지 않습니다.

기록이 끊기기 전에 증거를 옮깁니다

m07 전환·원복 증거, m08 요청·span·비교 자료, m09 보고서와 회고, 이전 및 후보 CI archive를 삭제 범위 밖으로 복사합니다. 이미지 archive는 나중에 동일 버전을 재현하는 입력이고 digest만 적은 문서와 역할이 다릅니다. 보존 폴더를 데이터 volume 안이나 lab 하위로 두면 정리 작업과 함께 잃을 수 있습니다. 파일별 SHA-256 목록을 만들어 정리 후 다시 읽습니다. 실습 비밀 파일은 증거 묶음에 복사하지 않고 외부 주입 방법만 인계합니다.

일관된 데이터를 백업합니다

파일을 복사하는 동안 앱이 쓰면 서로 다른 시점의 내용이 섞일 수 있습니다. 이 프로젝트는 notice.txt 단일 text-v1 데이터이며 미션 cleanup.py가 전용 container들을 정지한 뒤 readonly volume에서 파일을 읽습니다. 실제 데이터베이스는 별도의 일관성 보장 절차가 필요하고 이 예제로 복사 백업 전체를 대표하지 않습니다. 알려진 요청 로그는 앞 관측 자료에 보존되어야 합니다. 알 수 없는 업무 파일이 발견되면 삭제를 중단하고 백업 목록과 복원 검사를 확장합니다.

백업과 복원을 각각 확인합니다

앞 m07의 backup.py는 notice.txt와 manifest.json을 tar에 넣고 archive SHA-256을 기록합니다. restore는 같은 해시를 확인하고 허용된 두 일반 파일만 읽으며 데이터의 길이·내용 해시·schema를 검사합니다. 새 디렉터리에 복원한 notice.txt를 원본 byte와 대조합니다. archive 파일이 존재한다는 사실만으로 복원 가능하다고 말하지 않습니다. 경로 탈출·링크·예상 밖 파일·손상 archive는 실패로 처리합니다. 복원 테스트가 실패하면 보호 설정을 해제하지 않습니다.

볼륨의 삭제 방지를 이해합니다

상속한 main.tf의 docker_volume.data에는 lifecycle prevent_destroy=true가 있습니다. 계획에 해당 volume 파괴가 포함되면 보호 오류가 날 수 있으며 이 오류는 지워야 할 잡음이 아닙니다. 복원 결과와 보존 정책을 확인한 뒤에만 전용 코드의 보호를 잠시 해제하고 destroy 계획을 만듭니다. 코드에서 자원 선언 자체를 없애 보호가 유지된다고 기대하지 않습니다. 미션은 보호값만 잠시 바꾸고 finally에서 원래 코드를 복원합니다. state rm으로 보호 오류를 숨기지 않습니다. OpenTofu lifecycle 공식 문서를 검토 기준으로 사용합니다.

삭제 계획을 구조로 읽습니다

tofu plan -destroy -out=cleanup.plan은 실행 전 계획 파일을 만들고 tofu show -json cleanup.plan은 검토 자료를 제공합니다. 계획을 만드는 명령 자체는 자원을 삭제하지 않습니다. OpenTofu plan 공식 문서를 검토 기준으로 사용합니다. resource_changes의 actions가 delete 하나인지, before의 이름과 labels가 예상한 프로젝트인지 읽습니다. delete와 create가 함께 있으면 교체 계획이며 이번 정리 정책에서 거부합니다. 저장한 계획에는 민감한 값이 들어갈 수 있으므로 공개 JSON 전체를 인계하지 않고 검토 주소·범위만 안전하게 기록합니다.

주소·이름·라벨을 함께 검사합니다

cleanup_policy.review는 docker_container.notice, docker_volume.data, docker_network.notice 세 주소와 실제 이름을 기대 목록에 대조합니다. 주소가 같아도 이름이나 라벨이 다른 자원은 삭제 대상이 아닙니다. 예상 주소가 빠지거나 중복되고 모르는 관리 자원이 추가되면 거부합니다. 단순히 프로젝트 라벨만 맞는 모든 자원을 삭제하면 같은 프로젝트의 후속 실험까지 지울 수 있습니다. 계획의 소유 범위와 완전성 검사는 서로 다른 실패를 막으므로 하나로 대체하지 않습니다.

의존 관계를 역방향으로 정리합니다

container가 volume과 network를 사용하므로 사용자를 먼저 정리하고 저장소와 네트워크를 나중에 정리합니다. 최종 미션은 m07/m08의 명확한 이름 목록과 라벨을 다시 확인한 후 추가 container·volume을 정리합니다. 원본 state의 service·data·network는 검토한 계획을 tofu apply로 적용하여 IaC 의존성을 따릅니다. 전역 prune이나 강제 삭제는 사용하지 않습니다. 라벨이 같은 미등록 자원도 발견하면 자동 정리를 중단하여 범위가 변한 이유를 조사합니다.

오류 이후에는 현재 상태를 읽습니다

foreign resource는 프로젝트 라벨이 없거나 일치하지 않는 계획이고 delete only는 교체나 생성 동작이 섞인 상태입니다. missing deletion은 예상 주소가 빠졌다는 뜻입니다. Docker의 사용 중 volume 오류는 남은 참조 container를 조사할 신호입니다. 삭제 도중 실패하면 일부 자원은 이미 없어질 수 있으므로 성공으로 기록하지 않습니다. 보존 자료·남은 자원·state를 읽고 복구할지 정리를 이어갈지 판단합니다. 명령을 그대로 다시 실행하여 오류를 없애려 하지 않습니다.

검증 범위와 사람의 검토를 남깁니다

bash check-offline.sh는 계획 fixture 아홉 건을 검사하며 실제 Docker 자원을 만들지 않습니다. bash check.sh는 이 검사 뒤 OpenTofu init·fmt·validate를 수행하므로 external입니다. 전체 정리 미션 역시 Docker/OpenTofu 실행 대기 상태입니다. 계획 정책의 테스트 통과는 코드의 거부 동작을 확인하고 실제 잔여 목록 검사는 삭제 결과를 확인합니다. 비실습 fixture와 다른 자원 ID 집합이 동일한지도 대조합니다. 쓰기 중지와 작업 공간 선택의 타당성은 담당자가 검토합니다.

보존의 종료 시점도 인계합니다

정리가 끝나면 남은 파일의 위치·보존 이유·담당·재검토 시점을 적습니다. 이미지 archive·회고·실습 데이터가 끝없이 쌓이면 자원을 없애도 저장소 낭비는 남습니다. 외부 비밀은 인계 후 별도 수명 관리와 폐기 절차를 정하고 이 정리 스크립트가 비밀을 지웠다고 주장하지 않습니다. 더 읽기의 rsync 장은 백업 경로와 동기화 옵션을 이해하는 배경입니다. 여기서는 복원 가능성과 삭제 경계라는 계약을 먼저 완성하고 다음 레슨의 재현 문서에 연결합니다.

따라하기

삭제-only와 교체 구분

actions 배열 전체를 비교합니다. 일부에 delete가 있다고 허용하지 않습니다.

for actions in [['delete'],['delete','create'],['no-op']]:
    print(','.join(actions),actions==['delete'])

실행 결과

delete True
delete,create False
no-op False

범위 누락 찾기

주소 집합의 차이가 무엇을 놓쳤는지 보여 줍니다.

expected={'docker_container.notice','docker_volume.data','docker_network.notice'}
found={'docker_container.notice','docker_network.notice'}
print('missing',','.join(sorted(expected-found)))

실행 결과

missing docker_volume.data

계획 검토 정책 수정

cleanup starter.zip의 cleanup_policy.py에서 프로젝트 라벨 검사를 완성합니다. 처음에는 foreign/no-label 두 검사가 실패하며 완성 후 9개가 통과합니다. 실제 state 삭제는 수행하지 않습니다.

bash check-offline.sh

HCL과 실제 destroy 검토

external 환경에서 레슨 zip은 init·fmt·validate를 검사합니다. 실제 정리는 미션 zip과 원본 state에서 README를 따라 복원 후 진행합니다. 아래 plan 명령은 보호 해제·복원 확인 이후이며 show의 주소·이름·라벨·delete-only를 검토합니다. 출력 성공은 아직 확인하지 않았습니다.

bash check.sh
# 아래 두 명령은 미션의 원본 state 작업 공간에서만 실행합니다.
tofu plan -destroy -out=cleanup.plan
tofu show -json cleanup.plan

확인 문제

실습

cleanup_policy.py의 foreign resource 검사를 구현합니다. 정확한 라벨·주소·이름, delete-only, 예상 주소 전체 포함과 중복 거부를 유지합니다. bash check-offline.sh의 9개 검사를 먼저 통과시키고 외부 환경에서 bash check.sh로 main.tf 문법을 검사합니다. volume의 prevent_destroy는 true로 둡니다. 본인 m05/m06 state를 사용하는 실제 정리는 최종 미션의 복원·계획·잔여 목록 검사 절차를 따릅니다.

시작 코드·테스트 내려받기

실행 명령

bash check.sh

기대 결과

오프라인 계획 정책 9건 통과, tofu init -backend=false 및 fmt -check·validate 성공. 실제 삭제는 최종 미션에서 별도로 확인합니다.

모범 답안모범 답안 내려받기

더 읽기

면접 질문

  • 실습 자원을 안전하게 정리하는 순서를 설명합니다.