LabHub

Terraform 실전 · 상태 조작과 import · 실습

상태 옮기고 지우고 가져오기

LabHub 에서 이어서 보기

목표

이미 적용된 자원의 주소를 안전하게 옮기고, 관리 밖에 있던 자원을 상태에 편입시키고, 그 결과 코드와 상태가 어긋나지 않음을 종료 코드로 증명합니다.

왜 중요한가

상태 파일은 도구의 기억입니다. 코드는 "무엇이 있어야 하는가"를, 실물은 "무엇이 있는가"를 말하고, 상태는 "내가 마지막으로 알던 것"을 말합니다. 리팩터링은 이 셋 중 코드만 바꾸는 일이라, 상태를 함께 옮기지 않으면 도구는 옛 자원이 사라지고 새 자원이 생겼다고 판단해 파괴와 생성을 계획합니다. 그래서 이름 변경 같은 사소한 작업이 운영에서는 위험한 작업이 됩니다. 반대로 state rm 은 이름과 달리 실물을 지우지 않습니다 — 장부에서만 지우는 관리 포기 선언이고, 코드에 선언이 남아 있으면 다음 계획이 그 자원을 다시 만들려 듭니다. 이 비대칭을 정확히 알고 있어야 상태 수술이 무섭지 않습니다. 그리고 모든 수술 전에는 사본을 뜨세요. 되돌릴 수 있는 작업과 되돌릴 수 없는 작업의 차이는 그 파일 하나입니다.

단계

1. /root/tf/surgery/main.tf 에 세 리소스를 선언하고 tofu init 후 적용하세요 — local_file.legacy(파일 /root/tf/surgery/files/legacy.txt), local_file.notes(파일 /root/tf/surgery/files/notes.txt), random_pet.orphan. 그다음 상태 파일을 /root/tf/surgery/backup/terraform.tfstate.bak 로 복사하세요. 사본은 올바른 JSON 이어야 하고 lineage 가 현재 상태와 같아야 하며 리소스가 3개 이상이어야 합니다.
2. tofu state list 결과를 /root/tf/surgery/out/state-list.txt 로(3줄 이상), tofu state show local_file.legacy 결과를 /root/tf/surgery/out/show-legacy.txt 로 저장하세요. 두 번째 파일에는 id 속성 줄이 보여야 합니다.
3. tofu state mv local_file.legacy local_file.renamed 로 상태의 주소를 바꾸고, 같은 작업 안에서 코드의 리소스 이름도 renamed 로 고치세요. 옛 local_file.legacy 블록은 주석 처리가 아니라 완전히 지워야 하며, 작업 디렉터리의 어떤 .tf 파일에도 남아 있으면 안 됩니다. 상태만 옮기고 코드를 그대로 두면 다음 계획이 옛 이름의 자원을 다시 만들려 듭니다. tofu plan 출력을 /root/tf/surgery/out/plan-after-rename.txt 로 저장하면 No changes 여야 합니다.
4. /root/tf/surgery/modules/archive/ 디렉터리에 모듈을 만들어 같은 local_file 리소스를 renamed 라는 이름으로 선언하세요(파일 경로·내용 등 인자 값이 옮기기 전과 완전히 동일해야 합니다). 루트에 module "archive" 블록을 추가하고 tofu init 을 돌린 뒤 tofu state mv local_file.renamed module.archive.local_file.renamed 를 실행하고, 루트 main.tf 에서는 그 리소스 블록을 지우세요(여기서도 주석 처리가 아니라 삭제입니다 — 리소스 선언은 이제 모듈 파일에만 있어야 합니다). tofu plan 출력을 /root/tf/surgery/out/plan-after-module.txt 로 저장하면 No changes 여야 합니다.
5. tofu state rm random_pet.orphan 을 실행한 뒤 tofu plan 출력을 /root/tf/surgery/out/plan-after-rm.txt 로 저장하세요. 계획에는 random_pet.orphan 을 다시 만들겠다는 내용(1 to add)이 있어야 합니다. 확인했으면 main.tf 에서도 그 리소스 블록을 지우고, /root/tf/surgery/out/rm-note.txtstate rmdestroy 의 차이를 한 줄로 적으세요.
6. main.tfresource "terraform_data" "adopted" 를 빈 껍데기로 선언하고, 그 위에 import 블록을 두어 to = terraform_data.adopted, id = "labhub-adopted" 를 지정한 뒤 적용하세요. 상태의 terraform_data.adoptedid 속성이 labhub-adopted 여야 합니다.
7. main.tfresource "terraform_data" "legacy_job" 을 선언하고, 이번에는 명령줄로 tofu import terraform_data.legacy_job labhub-legacy 를 실행하세요. 출력을 /root/tf/surgery/out/import.txt 로 저장하면 Import successful 문구가 보여야 하고, 상태의 terraform_data.legacy_jobidlabhub-legacy 여야 합니다.
8. tofu plan -detailed-exitcode 를 실행하고 종료 코드만 /root/tf/surgery/out/final-exit.txt 에 적으세요(0 이어야 합니다). 그리고 /root/tf/surgery/out/inventory.json 을 만들어 addresses 에 현재 상태의 모든 주소를 배열로 담고 backup_takentrue 를 넣으세요. 주소 개수는 상태의 인스턴스 수와 정확히 같아야 하며, 목록에는 module.archive. 로 시작하는 주소와 가져온 adopted 주소가 포함돼야 합니다.

참고

단계 8개

  1. 수술 전 상태 사본 확보하기
  2. 상태 목록과 개별 리소스 들여다보기
  3. state mv 로 이름만 바꾸기
  4. 리소스를 모듈 안으로 옮기기
  5. state rm 이 실물을 지우지 않음을 증명하기
  6. import 블록으로 자원 편입하기
  7. 명령줄 import 로 편입하기
  8. 수술 후 일치 여부를 종료 코드로 증명하기