Terraform/OpenTofu 기초 · 데이터 소스와 자원의 차이 · 실습
읽기만 하는 블록이 상태에 남았다
목표
data 블록이 resource 와 무엇이 다른지를 상태·계획·파괴 세 자리에서 직접 확인합니다. 읽기가 언제 일어나는지, 무엇을 소유하지 않는지, 원본이 없거나 바뀌면 어떻게 되는지를 OpenTofu 로 하나씩 일으켜 봅니다.
왜 중요한가
설정 파일에서 data 블록은 resource 만큼 자주 나오는데, 둘을 같은 것으로 읽으면 사고가 조용히 납니다. data 는 대상을 만들지도 지우지도 않습니다 — destroy 를 돌려도 원본은 그대로 남고, 그래서 남의 팀이 만든 것을 읽어 쓰는 설정이 안전해집니다. 대신 data 는 상태에 저장된 값을 믿지 않고 계획마다 다시 읽습니다. 원본이 바뀌면 그것은 드리프트가 아니라 입력이 바뀐 것이고, 하류가 통째로 교체될 수 있습니다. 읽을 대상의 이름이 아직 정해지지 않았거나 depends_on 이 걸려 있으면 읽기가 적용 시점으로 밀리는데, 이때 계획에는 값이 통째로 '알 수 없음' 으로 나와 리뷰가 어려워집니다. 이 네 가지를 손으로 겪어 두면 남의 설정을 읽을 때 data 블록에서 눈이 멈추게 됩니다.
단계
1. /root/tfb-data/base/seed.txt 에 alpha 한 줄을 직접 만들고, 같은 디렉터리의 main.tf 에 그 파일을 읽는 data "local_file" "seed" 와 그 내용을 copy.txt 에 쓰는 resource "local_file" "copy" 를 두세요. init·apply 하고 계획이 깨끗해야 합니다.
2. /root/tfb-data/base/terraform.tfstate 를 열어 mode 가 data 인 항목과 managed 인 항목의 주소를 각각 찾고, /root/tfb-data/shape.txt 에 data=<그 주소> 와 managed=<그 주소> 두 줄을 적으세요. 주소는 data.local_file.seed 처럼 mode 접두어까지 포함한 형태입니다.
3. /root/tfb-data/own/ 에 같은 모양의 설정을 두되 seed.txt 는 owned 한 줄로 만드세요. init·apply 로 copy.txt 를 만든 뒤 tofu destroy -auto-approve 를 돌리고 그 출력을 /root/tfb-data/own-destroy.txt 에 저장하세요. 다시 apply 하지 않습니다.
4. /root/tfb-data/deferred/main.tf 에 random_pet.name(length 2), 그 이름이 들어간 made-<이름>.txt 를 쓰는 local_file.made, 그 파일을 읽는 data.local_file.back, 읽은 값을 echo.txt 에 쓰는 local_file.echo 를 두세요. init 한 뒤 plan 출력을 /root/tfb-data/deferred-plan.txt 에 저장하고 apply 하세요.
5. /root/tfb-data/gate/ready.txt 를 ready 한 줄로 먼저 만들어 두세요. 같은 디렉터리 main.tf 에 null_resource.prepare(triggers v = "1"), depends_on = [null_resource.prepare] 를 붙인 data.local_file.ready, 읽은 값을 mirror.txt 에 쓰는 local_file.mirror 를 두고 init 하세요. plan 출력을 /root/tfb-data/gate-plan.txt 에 저장한 뒤 apply 하세요.
6. /root/tfb-data/missing/main.tf 에 없는 파일 absent.txt 를 읽는 data.local_file.absent 와 그 내용을 내보내는 출력 absent 를 두고 init 하세요. plan 을 돌려 오류 출력을 /root/tfb-data/missing-plan.txt 에 저장하세요. 명령이 실패해도 괜찮습니다. absent.txt 는 만들지 마세요.
7. /root/tfb-data/tfdata/main.tf 에 terraform_data.note(input "v1")와 그 output 을 내보내는 출력 note 를 두고 init·apply 하세요. 그다음 input 을 "v2" 로 바꾸고 plan 출력을 /root/tfb-data/tfdata-plan.txt 에 저장한 뒤 apply 하세요. 마지막으로 /root/tfb-data/mode-compare.txt 에 terraform_data=<tfdata 상태에서 읽은 mode> 와 local_file_seed=<base 상태에서 읽은 mode> 두 줄을 적으세요.
8. /root/tfb-data/base/seed.txt 를 beta 한 줄로 바꾸고 /root/tfb-data/base 에서 plan 을 돌려 출력을 /root/tfb-data/data-change.txt 에 저장한 뒤 apply 하세요. 계획이 왜 교체(replace)로 나오는지 확인하고, 마지막에 계획이 다시 깨끗해져야 합니다.
참고
- 파드에는 OpenTofu 1.9.0 과 local·random·null·tls 프로바이더 미러가 있어 인터넷 없이 돕니다. 인터넷이 필요한 데이터 소스는 이 파드에서 쓸 수 없어 전부 local 파일로 재현합니다.
- 계획 출력은
-no-color로 저장해야 채점기가 읽기 좋습니다. 색 코드가 섞이면 사람 눈에도 지저분합니다. - 흔한 실수: 6단계에서 오류를 없애려고 absent.txt 를 만들어 버리는 것. 이 단계는 실패하는 계획을 남기는 것이 과제입니다.
- 흔한 실수: 3단계에서 destroy 뒤에 다시 apply 하는 것. 지운 자리를 그대로 두고 원본이 남았는지 확인하는 단계입니다.
- [Data Sources](https://opentofu.org/docs/language/data-sources/) · [depends_on](https://opentofu.org/docs/language/meta-arguments/depends_on/) · [terraform_data](https://developer.hashicorp.com/terraform/language/resources/terraform-data) · [local_file 데이터 소스](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/file) · [tofu plan](https://opentofu.org/docs/cli/commands/plan/)
단계 8개
- 이미 있는 파일을 data 로 읽는다
- 상태에서 읽는 것과 만드는 것을 가른다
- destroy 해도 읽기만 한 원본은 남는다
- 읽을 대상이 아직 없으면 읽기가 apply 로 밀린다
- depends_on 을 붙이면 있는 파일도 plan 때 못 읽는다
- 원본이 없으면 계획 자체가 실패한다
- terraform_data 는 data 가 아니라 managed 다
- 원본이 바뀌면 드리프트가 아니라 입력이 바뀐 것이다