Terraform/OpenTofu 기초 · 리소스와 의존성 · 실습
의존성 그래프와 상태 파일 해부
목표
참조가 어떻게 의존성 그래프를 만드는지 상태 파일에서 직접 확인하고, 상태를 사람과 기계 두 가지 방식으로 읽어 메타데이터를 뽑아낼 수 있게 됩니다.
왜 중요한가
Terraform 을 며칠 쓰다 보면 "순서가 왜 이렇지"라는 질문이 반드시 옵니다. 답은 언제나 그래프입니다. 도구는 파일에 적힌 순서를 보지 않고, 어떤 리소스가 어떤 리소스의 값을 쓰는지만 봅니다. 그래서 값을 참조하면 순서가 생기고, 값을 베껴 적으면 순서가 사라집니다. depends_on 은 값으로 드러나지 않는 순서를 표현하는 탈출구지만, 습관이 되면 그래프가 굵어져 실행이 느려지고 재생성이 옆으로 번집니다. 한편 이 관계는 상태 파일에 dependencies 로 기록되는데, 이것이 코드에서 리소스를 지운 뒤에도 올바른 역순으로 삭제할 수 있는 근거입니다. 상태를 손으로 편집하는 일이 왜 위험한지도 여기서 이해할 수 있습니다.
단계
1. /root/tf/state 에 설정을 만들어 초기화하세요. 이름이 seed 인 random_pet 과 이름이 child 인 local_file 을 선언하되, child 의 내용이 random_pet.seed 의 값을 참조하게 하세요. child 에는 depends_on 을 쓰지 마세요. 적용 뒤 상태의 local_file.child 의 dependencies 에 random_pet.seed 가 들어 있어야 합니다.
2. 이름이 marker 인 local_file 을 추가하고, /root/tf/state/main.tf 에 depends_on = [local_file.child] 를 적어 순서를 못 박으세요. 적용 뒤 상태의 local_file.marker 의 dependencies 에 local_file.child 가 보여야 합니다.
3. 상태에 등록된 리소스 주소 목록을 /root/tf/state/out/state-list.txt 에 저장하세요. random_pet.seed, local_file.child, local_file.marker 세 줄이 각각 정확히 그 문자열 그대로 들어가야 합니다.
4. 상태의 JSON 표현을 /root/tf/state/out/state.json 에 저장하세요. .values.root_module.resources 아래에 리소스가 3개 이상 있고, 그중 address 가 local_file.child 인 항목이 있어야 합니다.
5. /root/tf/state/out/meta.json 을 만드세요. serial, lineage, version, resource_count 네 키를 가지며, 앞의 셋은 /root/tf/state/terraform.tfstate 의 값과 같아야 하고 resource_count 는 상태의 resources 배열 길이와 같아야 합니다.
6. child 가 만든 파일을 Terraform 을 거치지 않고 셸에서 직접 지운 뒤, 그 상태로 계획을 뽑아 /root/tf/state/out/drift-plan.txt 에 저장하세요. 출력에 local_file.child 를 다시 만들겠다는 내용이 있어야 하고 "변경 없음" 이면 안 됩니다.
7. /root/tf/state/.terraform.lock.hcl 을 읽고 거기에 고정된 프로바이더 이름과 버전을 한 줄로 정리해 /root/tf/state/out/lock-note.txt 에 저장하세요. local 이라는 이름과 2.5.3 같은 세 자리 버전 번호가 모두 들어가야 합니다.
8. 이름이 stage_a, stage_b, stage_c 인 local_file 세 개를 추가하되 stage_b 는 stage_a 의 값을, stage_c 는 stage_b 의 값을 참조하게 하세요. 적용한 뒤 /root/tf/state/out/chain.txt 에 만들어지는 순서대로 local_file.stage_a, local_file.stage_b, local_file.stage_c 를 한 줄에 하나씩, 총 3줄로 적으세요.
참고
terraform state list는 주소만,terraform show -json은 상태 전체를 기계가 읽는 형식으로 보여 줍니다. 후자는jq와 짝을 이룹니다.- 5번은
jq로.serial,.lineage,.version,(.resources|length)를 뽑아 새 JSON 을 조립하면 손으로 베끼는 실수를 피할 수 있습니다. - 6번의 계획 출력은 표준 출력으로 나옵니다. 다시 적용하기 전에 파일로 남기세요.
- 흔한 실수 1: 순서를 맞추려고 모든 리소스에
depends_on을 다는 것. 참조가 있으면 의존성은 이미 생겨 있고, 중복된depends_on은 그래프만 굵게 만듭니다. - 흔한 실수 2: 3번과 8번에서 주소 앞뒤에 공백이나 따옴표를 남기는 것. 채점은 줄 전체가 정확히 일치하는지를 봅니다.
단계 8개
- 참조만으로 의존성 만들기
- depends_on 으로 순서 못 박기
- 상태 주소 목록 뽑기
- 상태를 JSON 으로 뽑기
- 상태 메타데이터 기록하기
- 손으로 지운 파일이 계획에 잡히는지 보기
- 잠금 파일에서 프로바이더 버전 읽기
- 3단계 의존 사슬 만들고 순서 기록하기