Infrastructure as Code · 드리프트와 임포트 · 실습
금요일 밤 손으로 고친 규칙을 월요일 apply 가 지우려 했다
목표
코드 밖에서 생긴 변경을 plan -refresh-only 로 따로 읽고, 그대로 적용하면 사라질 것을 계획 JSON 에서 찾은 뒤, 흡수·되돌림·제외 세 가지 해소를 직접 하고 매일 돌릴 감지 스크립트를 만듭니다.
왜 중요한가
선언형 도구는 코드를 진실로 삼으므로 콘솔에서 고친 옳은 수정도 다음 적용에서 되돌립니다. 그래서 드리프트를 발견하면 먼저 무엇이 사라질지 읽고, 흡수할지 되돌릴지를 사람이 정해야 합니다. ignore_changes 는 모든 드리프트를 숨겨 주는 스위치가 아니고, 프로바이더가 읽지 않는 속성의 변경은 계획에 아예 나타나지 않습니다. 이 한계를 알아야 감지 결과가 비었을 때 '일치한다' 와 '안 보인다' 를 구분할 수 있습니다.
단계
1. /root/iac-drift/main.tf 에 rules 변수(기본값 ["allow 443"]), 규칙마다 한 줄씩 out/firewall.rules 에 쓰는 local_file.fw, out/motd.txt 에 maintenance window: sun 02:00 한 줄을 쓰는 local_file.motd 를 두고 init·apply 하세요.
2. 장애 대응 중 누군가 /root/iac-drift/out/firewall.rules 끝에 allow 8443 한 줄을 손으로 더했습니다(직접 더하세요). 코드는 건드리지 않고 tofu plan -refresh-only 로 밖에서 생긴 변경만 본 출력을 /root/iac-drift/drift.txt 에 저장하세요.
3. 코드를 바꾸지 말고 tofu plan -out=/root/iac-drift/monday.tfplan 으로 계획을 저장하세요(적용하지 않음). 그 계획이 firewall.rules 에 쓸 내용과 지금 파일을 비교해, 적용하면 사라질 줄만 /root/iac-drift/lost.txt 에 적으세요.
4. 긴급 수정이 옳았다고 판단했습니다. rules 기본값을 ["allow 443", "allow 8443"] 로 바꾸고 apply 하세요. 그 뒤 firewall.rules 는 두 줄이고 계획은 깨끗해야 합니다.
5. 이번에는 누군가 out/motd.txt 를 maintenance window: none 으로 바꿨습니다(직접 바꾸세요). 이건 잘못된 변경입니다. 되돌리기 전에 tofu plan -refresh-only 출력을 /root/iac-drift/revert-drift.txt 에 저장하고, 코드는 그대로 둔 채 apply 해 공지를 코드의 내용으로 되돌리세요.
6. main.tf 에 out/cache.conf 에 cache v1 을 쓰고 lifecycle { ignore_changes = [content] } 가 걸린 local_file.cache 를 더해 apply 하세요. (가) 파일을 손으로 cache tampered 로 바꾼 뒤 tofu plan 출력을 /root/iac-drift/ignore.txt 에 저장하고 apply 로 되돌립니다. (나) 코드의 내용을 cache v2 로 바꾸고 계획이 깨끗한지 봅니다(적용하지 않음). (다) chmod 600 out/firewall.rules 뒤 tofu plan -detailed-exitcode 의 종료 코드를 /root/iac-drift/perm.txt 에 perm=<코드> 로 적으세요.
7. /root/iac-drift/detect.sh <작업디렉터리> 를 만드세요. plan -refresh-only 를 계획 파일로 저장해 밖에서 바뀐 리소스의 주소를 모아, 드리프트가 없으면 OK 와 0, 있으면 DRIFT <주소들(공백 구분, 정렬)> 한 줄과 2, 실패하면 ERROR 와 1 로 끝냅니다. 작업 디렉터리에 파일을 남기지 않습니다. 채점기는 /root/iac-drift 의 사본에서 파일을 바꿔 가며 확인합니다.
참고
- 파드에는 OpenTofu 1.9.0 과 local 프로바이더 미러가 있어 인터넷 없이 돕니다.
- local_file 은 내용이 기록과 다르면 파일을 '삭제됨' 으로 보고하고 다시 만드는 계획을 세웁니다(이 파드에서 실측). 클라우드 리소스의 프로바이더는 보통 속성 단위 차이(~ 수정)로 보고하므로 화면 모양은 다르지만, 흡수·되돌림·제외의 판단은 같습니다.
- 밖에서 생긴 변경만 보기:
tofu plan -refresh-only, 그것을 상태에만 받아들이기:tofu apply -refresh-only. - 흔한 실수: 드리프트를 보자마자 apply 해 옳은 긴급 수정을 지우는 것. 흔한 실수: ignore_changes 를 걸었으니 감지에서 빠진다고 믿는 것.
- [tofu plan (-refresh-only)](https://opentofu.org/docs/cli/commands/plan/) · [tofu refresh](https://opentofu.org/docs/cli/commands/refresh/) · [lifecycle (ignore_changes)](https://opentofu.org/docs/language/meta-arguments/lifecycle/) · [JSON Output Format (resource_drift)](https://opentofu.org/docs/internals/json-format/)
단계 7개
- 기준선: 방화벽 규칙과 공지를 코드로 적용한다
- 금요일 밤의 긴급 수정을 계획에서 본다
- 월요일에 그냥 apply 하면 무엇이 사라지나
- 옳은 수정이었다 — 코드로 흡수한다
- 잘못된 수정이었다 — 코드대로 되돌린다
- ignore_changes 가 막는 것과 못 막는 것, 아예 안 보이는 것
- 매일 아침 도는 드리프트 감지