LabHub
배우기 러닝패스 코스

Terraform 실전 · 동적 블록과 복잡한 형 · 실습

서비스 셋 × 환경 셋을 손으로 펼쳤더니 스무 블록이 됐다

LabHub 에서 이어서 보기

목표

중첩 객체 변수를 받아 맵으로 바꾸고, 이중 반복을 flatten 과 setproduct 두 방식으로 펼쳐 같은 결과를 내고, dynamic 블록으로 선택적 블록을 만들고 그 한계를 오류로 확인한 뒤, 펼친 행렬을 파일과 보고서로 렌더합니다.

왜 중요한가

인프라 코드가 길어지는 진짜 이유는 리소스가 많아서가 아니라 같은 모양이 반복되어서입니다. 그 반복을 손으로 펼치면 고칠 곳이 스무 군데가 되고, 리뷰하는 사람은 스무 블록이 정말 같은지 눈으로 대조해야 합니다. HCL 은 이것을 두 갈래로 풉니다 — 값을 만드는 쪽과 블록을 만드는 쪽입니다. 값 쪽(for 표현식·flatten·setproduct·객체 형)은 얼마든지 접고 펼 수 있고, 블록 쪽(dynamic)은 프로바이더 스키마가 허락하는 범위 안에서만 만들 수 있습니다. 이 차이를 모르면 dynamic 으로 모든 것을 짜려다 읽을 수 없는 설정을 만들게 됩니다. 실무에서 dynamic 이 가장 값어치 있게 쓰이는 자리는 사실 반복이 아니라 '이 블록을 넣을까 말까' 라는 선택이고, 반복은 대개 for_each 와 값 표현식이 맡습니다.

단계

1. /root/tfa-dyn/variables.tflist(object({ name = string, port = number, envs = list(string) })) 형의 services 변수를 선언하고, 이름이 겹치지 않는지 보는 validation 을 붙이세요. /root/tfa-dyn/terraform.tfvars 에는 api(8080, dev·prod), web(8081, dev), batch(9090, dev·stage·prod) 세 개를 적습니다. /root/tfa-dyn/main.tf 에는 프로바이더 선언과 jsonencode(var.services)out/services.json 에 쓰는 local_file.services 를 두고 init·apply 하세요.
2. /root/tfa-dyn/svc.tflocal.by_name(이름을 키로 잡은 맵)을 만들고, 그것으로 for_each 를 돌려 서비스마다 /root/tfa-dyn/out/svc/<이름>.conf 를 쓰는 local_file.svc 를 선언하세요. 파일 내용은 name=<이름>port=<번호> 두 줄입니다. apply 한 뒤 상태의 인스턴스 키가 무엇인지 보세요.
3. /root/tfa-dyn/flat.tf 에 서비스 × 그 서비스의 환경을 모두 펼친 local.pairs(각 항목은 env·name·port 를 가진 객체)를 flatten 으로 만들고, "<env>/<name>" 을 키로 잡은 local.by_key 맵을 jsonencode/root/tfa-dyn/out/flat.json 에 쓰세요. 항목은 여섯 개가 나와야 합니다.
4. /root/tfa-dyn/product.tflocal.all_envs(모든 환경의 중복 없는 목록)를 만들고, setproduct(local.all_envs, var.services) 의 모든 조합 중 그 서비스가 실제로 쓰는 환경만 남겨 local.combo_by_key 를 만든 뒤 /root/tfa-dyn/out/product.json 에 쓰세요. 3단계 결과와 완전히 같아야 합니다.
5. /root/tfa-dyn/cert.tfvar.with_subject(bool, 기본 true)와 ED25519 개인키, 그리고 dynamic "subject" 로 주체 블록을 켜고 끄는 tls_self_signed_cert.c 를 두세요. 주체는 common_name = "api.internal", organization = "LabHub" 입니다. 인증서는 /root/tfa-dyn/out/cert.pem 에 씁니다. 먼저 -var with_subject=false 로 적용해 openssl x509 -noout -subject 결과를 /root/tfa-dyn/out/no-subject.txt 에 저장하고, 그다음 기본값으로 다시 적용해 같은 명령의 결과를 /root/tfa-dyn/out/subject.txt 에 저장하세요.
6. /root/tfa-dyn/cert.tfdynamic "subject" 가 두 개의 블록을 만들도록 잠깐 고쳐 apply 하고, 실패 출력을 /root/tfa-dyn/out/limit-error.txt 에 저장하세요. 그다음 원래대로 되돌려 다시 적용하고 계획이 깨끗한 상태로 마칩니다.
7. /root/tfa-dyn/rendered.tf 에 3단계의 local.by_keyfor_each 를 돌려 /root/tfa-dyn/rendered/<env>-<name>.conf 여섯 개를 만드세요. 내용은 env=, name=, port= 세 줄입니다.
8. /root/tfa-dyn/summary.tf 에 환경별 항목 수(by_env), 이름을 정렬한 목록(services), 서비스 포트의 합(total_ports) 세 가지를 담은 /root/tfa-dyn/out/summary.json 을 만드세요. 세 값은 모두 HCL 표현식으로 계산합니다.

참고

단계 8개

  1. 중첩 객체를 변수 형으로 받는다
  2. 리스트를 맵으로 바꿔 for_each 에 넘긴다
  3. 이중 반복을 flatten 으로 한 겹으로 편다
  4. 같은 행렬을 setproduct 로 다시 만든다
  5. dynamic 으로 블록을 있다·없다로 만든다
  6. dynamic 은 스키마가 허락하는 만큼만 만든다
  7. 펼친 행렬을 파일로 렌더한다
  8. 펼친 값을 다시 접어 보고서로 만든다