最初の宣言と状態ファイルの読み方
한국어 원문으로 표시합니다.
목표
선언 하나가 실제 파일과 상태 파일이라는 두 결과를 동시에 만든다는 것을 손으로 확인하고, 상태를 열어 리소스 주소·serial·의존성을 읽을 수 있게 됩니다.
왜 중요한가
선언형 도구를 처음 만나면 "명령어를 외우는 일"처럼 보이지만, 실제로 배워야 하는 것은 도구가 무엇을 근거로 판단하는가입니다. Terraform 은 코드(원하는 상태), 상태 파일(마지막으로 아는 상태), 실제 인프라(지금 있는 것) 세 가지를 비교해 계획을 만듭니다. 그래서 상태 파일을 잃으면 도구는 이미 존재하는 리소스를 "처음 보는 것"으로 여겨 다시 만들려 들고, 상태에 남은 유령 리소스는 "지우겠다"고 말합니다. 이 실습에서 상태를 jq 로 직접 열어 보는 이유가 여기 있습니다. 또 하나, 값을 하드코딩할 것인가 참조할 것인가는 취향이 아니라 그래프의 문제입니다. 참조해야만 도구가 순서를 알고, 나중에 앞 리소스가 바뀔 때 뒤 리소스도 함께 갱신됩니다.
단계
/opt/lab/fixtures/terraform/starter/main.tf를/root/tf/first/main.tf로 복사하고 그 디렉터리에서 초기화하세요.required_providers블록이 그대로 남아 있어야 하며, 초기화 뒤/root/tf/first/.terraform.lock.hcl과/root/tf/first/.terraform/providers가 생기고 잠금 파일에local프로바이더가 적혀 있어야 합니다.main.tf에 타입이local_file, 이름이hello인 리소스를 선언하세요.filename은/root/tf/first/out/hello.txt이고, 내용을 담는 인자 이름은content입니다.- 적용해서
/root/tf/first/out/hello.txt를 만드세요. 내용은hello opentofu로 둡니다. 적용 뒤/root/tf/first/terraform.tfstate에local_file.hello가 등록되고, 상태에 기록된content와 실제 파일 내용이 정확히 같아야 하며, 상태의version은4여야 합니다. - 타입이
random_pet, 이름이suffix인 리소스를 추가해 적용하세요.length는2로 두고prefix는 주지 마세요. 상태에random_pet.suffix가 생기고 만들어진 이름은단어-단어형태여야 합니다. hello의 내용을hello labhub로 바꿔 다시 적용하세요. 파일 내용과 상태에 기록된content가 모두 정확히hello labhub여야 하고, 상태의serial은2이상이어야 합니다.- 타입이
local_file, 이름이temp인 리소스를/root/tf/first/out/temp.txt로 한 번 만들었다가 다시 제거하세요. 제거할 때의 출력을/root/tf/first/out/destroy.txt에 저장합니다. 끝난 뒤temp.txt파일과 상태의local_file.temp는 사라지고local_file.hello는 남아 있어야 합니다. - 상태에 등록된 리소스 주소 목록을
/root/tf/first/out/state-list.txt에 저장하세요.local_file.hello와random_pet.suffix가 각각 한 줄씩 있어야 하고local_file.temp는 없어야 합니다 (6번을 끝낸 뒤에 뽑으세요). - 타입이
local_file, 이름이summary인 리소스를/root/tf/first/out/summary.txt로 만드세요. 내용에는random_pet.suffix가 만든 이름과hello labhub가 모두 들어가야 하며, 두 값 모두 다른 리소스의 속성을 참조해서 넣어야 합니다. 적용 뒤 상태의local_file.summary의dependencies에random_pet.suffix가 보여야 합니다.
참고
- 이 환경의 명령은
tofu이고terraform이라는 이름으로도 부를 수 있습니다. 하위 명령과 옵션 구조는 같습니다. - 인터넷은 없지만
local,random,null,tls프로바이더가 이미지 안 파일시스템 미러에 들어 있어 초기화가 됩니다. - 상태는 눈으로 읽는 것보다
jq로 뽑는 편이 빠릅니다..version,.serial,.lineage,[.resources[].type + "." + .resources[].name]정도면 충분합니다. - 흔한 실수 1: 내용 끝에 줄바꿈을 넣어 상태의
content가hello labhub\n이 되는 것. 5번은 정확한 일치를 봅니다. - 흔한 실수 2: 8번에서 만들어진 펫 이름을 눈으로 보고 문자열에 그대로 적는 것. 파일 내용은 통과해도 의존 관계가 생기지 않아 실패합니다.
작업 디렉터리 초기화하고 프로바이더 받기
/opt/lab/fixtures/terraform/starter/main.tf 를 /root/tf/first/main.tf 로 복사하고 그 디렉터리에서 초기화하세요. required_providers 블록이 그대로 남아 있어야 하며, 초기화 뒤 /root/tf/first/.terraform.lock.hcl 과 /root/tf/first/.terraform/providers 가 생기고 잠금 파일에 local 프로바이더가 적혀 있어야 합니다.
픽스처의 시작 파일에는 required_providers 가 이미 들어 있습니다. 그 파일을 작업 디렉터리로 복사한 뒤 초기화하면 잠금 파일과 .terraform/providers 가 생깁니다. 이 환경은 인터넷 대신 이미지 안 파일시스템 미러에서 받습니다.
local_file 리소스 선언하기
main.tf 에 타입이 local_file, 이름이 hello 인 리소스를 선언하세요. filename 은 /root/tf/first/out/hello.txt 이고, 내용을 담는 인자 이름은 content 입니다.
resource "타입" "이름" 에서 두 번째 라벨이 주소의 뒷부분이 됩니다. 파일 내용을 담는 인자 이름은 복수형이 아니라는 점에 주의하세요.
적용해서 파일과 상태를 함께 만들기
적용해서 /root/tf/first/out/hello.txt 를 만드세요. 내용은 hello opentofu 로 둡니다. 적용 뒤 /root/tf/first/terraform.tfstate 에 local_file.hello 가 등록되고, 상태에 기록된 content 와 실제 파일 내용이 정확히 같아야 하며, 상태의 version 은 4 여야 합니다.
적용이 끝나면 실제 파일과 terraform.tfstate 가 같이 생깁니다. 상태에 기록된 content 와 실제 파일 내용이 같은지 비교해 보세요 — 이 둘이 어긋난 상태가 곧 드리프트입니다. version 필드가 몇인지도 확인해 보세요.
random_pet 으로 무작위 이름 만들기
타입이 random_pet, 이름이 suffix 인 리소스를 추가해 적용하세요. length 는 2 로 두고 prefix 는 주지 마세요. 상태에 random_pet.suffix 가 생기고 만들어진 이름은 단어-단어 형태여야 합니다.
random_pet 은 단어를 하이픈으로 이어 붙인 이름을 만듭니다. 단어 개수를 정하는 인자가 무엇인지 찾고, 접두어는 주지 마세요.
선언을 바꾸고 다시 적용하기
hello 의 내용을 hello labhub 로 바꿔 다시 적용하세요. 파일 내용과 상태에 기록된 content 가 모두 정확히 hello labhub 여야 하고, 상태의 serial 은 2 이상이어야 합니다.
내용만 바꿔 다시 적용하면 상태의 serial 이 올라갑니다. 상태에 기록된 값과 실제 파일이 정확히 같아야 하므로 끝에 줄바꿈이 끼지 않게 하세요.
임시 리소스만 골라 지우기
타입이 local_file, 이름이 temp 인 리소스를 /root/tf/first/out/temp.txt 로 한 번 만들었다가 다시 제거하세요. 제거할 때의 출력을 /root/tf/first/out/destroy.txt 에 저장합니다. 끝난 뒤 temp.txt 파일과 상태의 local_file.temp 는 사라지고 local_file.hello 는 남아 있어야 합니다.
선언에서 블록을 지우고 다시 적용하면 그 리소스만 사라집니다. 지우기 전에 출력을 먼저 읽어 남겨야 할 리소스까지 대상이 되지는 않았는지 확인하세요.
상태에 등록된 주소 뽑기
상태에 등록된 리소스 주소 목록을 /root/tf/first/out/state-list.txt 에 저장하세요. local_file.hello 와 random_pet.suffix 가 각각 한 줄씩 있어야 하고 local_file.temp 는 없어야 합니다 (6번을 끝낸 뒤에 뽑으세요).
상태에 무엇이 들어 있는지 주소만 보여 주는 하위 명령이 있습니다. 이미 지운 리소스가 목록에 남아 있다면 순서를 잘못 밟은 것입니다.
참조로 요약 파일 만들기
타입이 local_file, 이름이 summary 인 리소스를 /root/tf/first/out/summary.txt 로 만드세요. 내용에는 random_pet.suffix 가 만든 이름과 hello labhub 가 모두 들어가야 하며, 두 값 모두 다른 리소스의 속성을 참조해서 넣어야 합니다. 적용 뒤 상태의 local_file.summary 의 dependencies 에 random_pet.suffix 가 보여야 합니다.
다른 리소스의 속성을 식으로 참조하면 의존 관계가 자동으로 생깁니다. 눈으로 본 값을 문자열에 그대로 적으면 파일 내용은 맞아도 dependencies 가 비어 실패합니다.