Terraform 실전 · workspace 와 디렉터리 분리 · 실습
prod 를 선택한 줄 모르고 destroy 를 쳤다
목표
workspace 로 환경을 나눌 때 상태가 실제로 어디에 생기는지 열어 보고, 선택 실수 사고를 직접 낸 뒤 문지기로 막고, 같은 것을 디렉터리 분리로 만들어 두 방식을 숫자로 견줍니다.
왜 중요한가
환경을 나누는 첫 도구로 workspace 를 집는 이유는 분명합니다 — 코드가 한 벌이고, 프로바이더 캐시도 한 벌이고, 명령 한 줄로 갈아탑니다. 그런데 그 장점이 그대로 위험입니다. 백엔드가 하나라는 말은 dev 를 쓰는 사람과 prod 를 쓰는 사람이 같은 자격증명으로 같은 저장소를 연다는 뜻이고, '지금 어느 환경인가' 는 화면이 아니라 작업 디렉터리 안 파일 하나에만 적혀 있습니다. 공식 문서가 workspace 를 시스템 분해나 자격증명이 갈라지는 배포에 쓰지 말라고 적은 이유가 이것입니다. 그래서 실무의 선택은 '둘 중 무엇이 옳은가' 가 아니라 '무엇을 무엇으로 나누는가' 입니다 — 같은 팀이 쓰는 임시 사본은 workspace 로, 권한이 갈라지는 경계는 디렉터리로 나눕니다.
단계
1. /root/tfa-ws/main.tf 에 local 프로바이더와 local_file.env 를 두세요. 파일 이름은 out/<workspace 이름>.conf, 내용은 첫 줄 workspace=<workspace 이름>, 둘째 줄 replicas=<local.replicas> 입니다. /root/tfa-ws/sizes.tf 에는 locals 로 replicas = 1 만 둡니다. init 하고 apply 하세요.
2. dev 와 prod workspace 를 만들고 각각에서 apply 하세요. 끝나면 /root/tfa-ws/out/ 에 세 파일이, /root/tfa-ws/terraform.tfstate.d/ 아래에 두 개의 상태 파일이 있어야 합니다.
3. /root/tfa-ws/where.tsv 에 workspace 세 개를 이름순(default·dev·prod)으로 한 줄씩 적으세요. 탭으로 나눈 세 칸은 <workspace 이름>, /root/tfa-ws 기준 상태 파일 상대경로, 그 상태의 lineage 입니다.
4. /root/tfa-ws/sizes.tf 를 고쳐 local.sizes 맵(default = 1, dev = 2, prod = 6)에서 지금 workspace 의 값을 lookup 으로 꺼내 local.replicas 로 쓰세요. 세 workspace 모두에서 다시 apply 하면 out/ 의 세 파일이 서로 다른 replicas 값을 갖습니다.
5. prod 를 선택한 상태에서 tofu destroy -auto-approve 를 돌려 사고를 직접 내세요. 출력은 /root/tfa-ws/incident/prod-destroy.log 에, 그때 선택돼 있던 workspace 이름은 /root/tfa-ws/incident/selected.txt 에(.terraform/environment 를 그대로 복사) 남깁니다. 그다음 /root/tfa-ws/incident.md 에 selected:, command:, lost:, recovery: 네 줄을 적고, prod 를 다시 apply 해 복구하세요.
6. /root/tfa-ws/guard.sh 를 만드세요. 인자로 받은 이름과 지금 선택된 workspace 가 같으면 확인 메시지를 내고 0 으로, 다르면 지금 선택된 이름을 보여 주며 1 로, 인자가 없으면 2 로 끝나야 합니다. workspace 를 바꾸지는 않습니다.
7. /root/tfa-ws/modules/app/main.tf 에 var.env·var.replicas 를 받아 /root/tfa-ws/out-dir/<env>.conf 를 쓰는 모듈을 두고, /root/tfa-ws/envs/dev 와 /root/tfa-ws/envs/prod 두 디렉터리에서 그 모듈을 각각 env="dev" replicas=2, env="prod" replicas=6 으로 부르세요. 두 디렉터리를 따로 init·apply 합니다. workspace 는 쓰지 않습니다.
8. /root/tfa-ws/compare.tsv 에 아래 다섯 줄을 탭 두 칸으로 적으세요. 값은 지어내지 말고 지금 디스크에서 세어 적습니다.workspace_states = workspace 방식이 갖는 상태 파일 수, directory_states = envs/ 아래 상태 파일 수, workspace_plugin_dirs = workspace 방식의 .terraform 디렉터리 수, directory_plugin_dirs = envs/ 아래 .terraform 디렉터리 수, selected_marker = 지금 선택된 workspace 를 기억하는 파일의 상대경로.
참고
- 파드에는 OpenTofu 1.9.0 과 local 프로바이더 미러가 있어 인터넷 없이 돕니다. 이 실습의 백엔드는 모두 local 입니다.
- local 백엔드에서 기본 workspace 의 상태는 작업 디렉터리의 terraform.tfstate 이고, 그 밖의 workspace 는 terraform.tfstate.d 아래로 갑니다. 백엔드마다 경로 규칙이 다릅니다.
- 흔한 실수: 2단계에서 이미 있는 이름에 workspace new 를 다시 부르는 것. select 로 갈아타야 합니다.
- 흔한 실수: 4단계에서 sizes.tf 만 고치고 apply 를 한 workspace 에서만 도는 것. 상태가 workspace 마다 따로라 각각 적용해야 합니다.
- [Workspaces](https://opentofu.org/docs/language/state/workspaces/) · [Managing Workspaces (CLI)](https://opentofu.org/docs/cli/workspaces/) · [Command: workspace](https://opentofu.org/docs/cli/commands/workspace/) · [Backend: local](https://opentofu.org/docs/language/settings/backends/local/)
단계 8개
- 기본 workspace 의 상태는 어디에 있나
- workspace 를 둘 더 만들면 상태가 어디로 가나
- 어느 workspace 의 상태가 어느 파일인지 적는다
- 같은 코드가 환경마다 다른 값을 갖게 한다
- 선택을 잘못한 채 명령을 내린다
- 쓰기 명령 앞에 문지기를 세운다
- 같은 것을 디렉터리 분리로 만든다
- 두 방식을 숫자로 견준다