LabHub

Terraform 실전 · count 와 for_each · 실습

count 에서 for_each 로, 파괴 없이 이주하기

LabHub 에서 이어서 보기

목표

countfor_each 의 차이를 상태 주소로 확인하고, 이미 적용된 자원을 파괴 없이 for_each 로 이주시키는 절차를 익힙니다.

왜 중요한가

countfor_each 는 문법 선택처럼 보이지만 실제로는 각 인스턴스의 식별자를 무엇으로 삼을 것인가를 정하는 결정입니다. count 는 순서를, for_each 는 이름을 식별자로 씁니다. 목록 가운데 항목을 하나 지워 보면 차이가 드러납니다 — count 는 뒤쪽이 한 칸씩 당겨지면서 남아 있어야 할 자원까지 재생성되고, for_each 는 해당 키만 사라집니다. 실제 클라우드였다면 이 차이가 "설정 한 줄 지웠는데 서버 두 대가 재생성됐다"로 나타납니다. 이미 적용된 자원의 주소를 바꿔야 할 때는 moved 블록을 쓰세요. moved 는 상태만 옮기고 실물은 건드리지 않으며, 코드에 리팩터링 이력이 남아 다른 사람이 plan 만 돌려도 자동으로 따라옵니다. 이주가 제대로 됐는지 판정하는 기준은 하나입니다 — 계획에 파괴가 한 건도 없어야 합니다.

단계

1. /root/tf/foreach/main.tflocal_file 리소스 nodecount = 3 으로 선언하고 tofu init 후 적용하세요. 그다음 주소를 옮기기 전에 tofu state list 결과를 /root/tf/foreach/out/count-state.txt 로 저장하세요. 이 파일에는 local_file.node[0], local_file.node[1], local_file.node[2] 세 줄이 들어 있어야 하며(문자열 키 형태가 들어 있으면 안 됩니다), 7번의 이주 전 스냅숏 역할을 합니다.
2. node 의 파일 이름을 /root/tf/foreach/out/node-${count.index}.txt, 내용을 node-${count.index} 로 하세요. 이름을 세 번 손으로 적지 말고 반드시 반복 색인으로 만들어야 합니다. out 아래 node-*.txt 는 정확히 3개여야 하고, 각 파일의 첫 줄은 node-0, node-1, node-2 여야 합니다.
3. local_file 리소스 zonefor_each = toset(["kr", "us", "eu"]) 로 만들고 파일은 /root/tf/foreach/out/zone-<키>.txt 세 개가 생기게 하세요. 상태의 키는 eu, kr, us 여야 합니다.
4. local_file 리소스 service 를 맵으로 도세요. 키는 api, web, worker 이고 각 값에는 포트가 들어갑니다(web 의 포트는 반드시 8080). /root/tf/foreach/out/service-web.txt 안에는 name=webport=8080 이 각각 한 줄로 들어가야 합니다.
5. for 표현식으로 서비스 이름을 키, 포트를 값으로 갖는 출력 service_ports 를 정의하고 tofu output -json 결과를 /root/tf/foreach/out/outputs.json 로 저장하세요. 항목은 3개, web8080 이어야 합니다.
6. variable "enable_debug"(bool, 기본값 false)를 만들고 local_file 리소스 debugcount = var.enable_debug ? 1 : 0 을 쓰세요. 파일 경로는 /root/tf/foreach/out/debug.txt 이고 내용은 자유입니다(스위치는 인스턴스가 최대 하나라 색인이 밀릴 일이 없다는 점이 count 를 계속 써도 되는 이유입니다). 스위치를 켠 계획(tofu plan -var enable_debug=true)의 출력을 /root/tf/foreach/out/toggle.txt 로 저장하되(1 to add 가 보여야 합니다) 적용하지는 마세요. 최종 상태에는 debug 인스턴스가 0개이고 /root/tf/foreach/out/debug.txt 도 없어야 합니다.
7. nodefor_each = { n0 = 0, n1 = 1, n2 = 2 } 로 바꾸세요. 맵의 키는 새 주소용이고 값은 옛 색인이므로, 파일 이름과 내용은 each.key 가 아니라 each.value 로 만들어 node-0.txt·node-1.txt·node-2.txt 와 그 내용이 1~2번과 완전히 같게 유지해야 합니다(이름을 바꾸면 이주가 아니라 재생성이 되어 계획에 파괴가 뜹니다). 그리고 moved 블록 3개로 local_file.node[0]local_file.node["n0"] 으로 옮기는 식으로 옛 주소와 새 주소를 이어 주세요. 적용한 뒤 tofu plan 출력을 /root/tf/foreach/out/after-plan.txt 로 저장하면 No changes 여야 하고 파괴가 한 건도 없어야 합니다.
8. /root/tf/foreach/out/addresses.json 을 만드세요. addresses 키에 tofu state list 의 주소를 배열로 담고(node 3 + zone 3 + service 3 = 9개 이상), 숫자 색인이 붙은 주소는 하나도 없어야 합니다. numeric_index_count 키에는 숫자 색인 주소의 개수를 적으며 이주가 끝났다면 0 입니다.

참고

단계 8개

  1. count 로 세 개 만들고 옮기기 전 주소 남기기
  2. count.index 로 인스턴스 구분하기
  3. 집합을 도는 for_each 쓰기
  4. 맵을 도는 for_each 와 each.value
  5. for 표현식으로 출력 맵 만들기
  6. 조건부 count 로 기능 스위치 만들기
  7. moved 블록으로 count 를 for_each 로 이주하기
  8. 전체 주소 목록과 이주 완료 보고서 만들기