Ansible 기초 · 고치기 전에 보는 법 · 실습
고치기 전에 무엇이 바뀔지 본다
목표
점검 모드와 diff 를 '플래그 두 개' 가 아니라 '태스크마다 정해 주는 행동' 으로 다룹니다. 거짓 실패를 직접 만들어 고치고, 승인에 붙일 계획 산출물과 드리프트 게이트까지 만듭니다.
왜 중요한가
운영 서버에 플레이북을 처음 거는 날, 이 플레이북이 스무 대에 무엇을 할지 아무도 모릅니다. --check 는 그 자리에 놓인 도구인데 두 번 배신합니다 — 점검 모드가 깨끗했는데 진짜 실행이 실패하고, 점검 모드가 빨갛게 죽었는데 진짜 실행은 멀쩡합니다. 두 배신의 원인은 같습니다. 점검 모드는 실제로 실행하지 않은 채 결과를 추측하는 모드이고, 추측의 품질은 모듈마다 다릅니다. 그래서 점검 모드를 믿을 수 있게 만드는 일은 플래그를 붙이는 일이 아니라 태스크마다 '너는 점검 모드에서 어떻게 행동해라' 를 정해 주는 일입니다. 그 일을 마치고 나면 dry run 은 배포 전에 보는 그림을 넘어, 승인 근거이자 드리프트를 잡는 게이트가 됩니다.
단계
1. /root/anschk/hosts.ini 를 만드세요 — [web] 에 web1(ansible_host=127.0.0.1, ansible_port=2222), [all:vars] 로 ansible_user=root. 그다음 /root/anschk/site.yml 을 만드세요: 플레이 변수 app_env(기본 lab)·app_dir_mode(기본 "0755")·motd_owner(기본 unset) 를 두고, 태스크 넷으로 /root/anschk/app 디렉터리를 app_dir_mode 권한으로 만들고, /root/anschk/app/app.conf 에 env=<app_env> 와 listen=8080 두 줄을 권한 0644 로 쓰고, /root/anschk/app/motd 에 Welcome=labhub 와 Owner=unset 두 줄을 권한 0644 로 쓰고, 마지막으로 motd 의 ^Owner= 줄을 Owner=<motd_owner> 로 맞춥니다(그 파일이 없으면 만들도록 create 를 켜세요 — 점검 모드에서 앞 태스크가 파일을 실제로 만들지 않기 때문입니다). 아직 수렴시키지 말고 --check --diff 로만 돌려 출력을 /root/anschk/out/check1.txt 에 저장하세요.
2. site.yml 을 --diff 와 함께 기본값으로 한 번 실제 실행해 출력을 /root/anschk/out/converge.txt 에 저장하세요. 그다음 값 셋을 명령줄로 덮어써서 --check --diff 로 다시 돌리세요 — app_env=stage, app_dir_mode=0750, motd_owner=platform-team. 그 출력을 /root/anschk/out/diff.txt 에 저장하세요. 실제 파일은 그대로 env=lab·권한 0755·Owner=unset 이어야 합니다.
3. /root/anschk/probe.yml 을 만드세요. ansible.builtin.command 로 getent passwd root 를 실행해 pw 로 register 하고(changed_when: false), 그 값과 지금이 점검 모드인지를 ansible.builtin.debug 로 check_mode=<참거짓> pwline=<읽은 값> 형태로 한 줄에 냅니다. 이 플레이북을 --check 로 돌린 출력을 표준 오류까지 /root/anschk/out/probe-check.txt 에 저장하되, 점검 모드에서도 실제 값이 찍혀야 합니다. 건너뛰어지는 태스크가 하나도 없어야 합니다.
4. /root/anschk/patch.yml 을 만드세요 — 태스크 둘입니다. 하나는 /root/anschk/app/fresh.conf 에 env=lab 과 listen=9090 두 줄을 권한 0644 로 쓰고, 다른 하나는 그 파일의 ^listen= 줄을 listen=9443 으로 고칩니다. 먼저 이 상태 그대로 --check 로 돌려 실패 출력을 표준 오류까지 /root/anschk/out/false-failure.txt 에 저장하세요. 그다음 뒤 태스크에 점검 모드에서는 건너뛰는 가드를 달고 다시 --check 로 돌려 그 출력을 /root/anschk/out/false-fixed.txt 에 저장하세요. 두 번 모두 점검 모드이므로 /root/anschk/app/fresh.conf 는 끝까지 만들어지면 안 됩니다.
5. /root/anschk/dryrun.yml 을 만드세요. /root/anschk/app/never.conf 에 feature=on 한 줄을 권한 0644 로 쓰는 태스크 하나인데, --check 없이 평소대로 돌려도 절대 파일을 만들지 않고 바뀔 것이라는 보고만 해야 합니다. 같은 플레이북에 태스크를 하나 더 두세요 — /root/anschk/app/dryrun-ran.txt 에 real-run 한 줄을 권한 0644 로 쓰는 평범한 태스크입니다. 이 플레이북을 아무 플래그 없이 실행해 출력을 /root/anschk/out/dryrun.txt 에 저장하세요. 끝나면 /root/anschk/app/dryrun-ran.txt 는 있고 /root/anschk/app/never.conf 는 없어야 합니다.
6. /root/anschk/undef.yml 을 만드세요 — 정의되지 않은 변수(missing_var)를 내용에 쓰는 copy 태스크 하나입니다. /root/anschk/badmod.yml 도 만드세요 — 모듈 이름을 ansible.builtin.coppy 로 오타 낸 태스크 하나입니다. 그다음 /root/anschk/gates.sh 를 만들어 두 플레이북 각각에 --syntax-check·--list-tasks·--check 를 차례로 걸고 종료 코드만 /root/anschk/out/gates.txt 에 한 줄씩 적으세요: <파일이름> syntax-check=<코드> list-tasks=<코드> check=<코드>. 스크립트를 실행해 파일을 남기세요.
7. /root/anschk/plan.sh 를 만드세요. ansible.posix.json 을 stdout 콜백으로 지정해 site.yml 을 --check --diff -e app_env=stage 로 돌리고 그 JSON 전체를 /root/anschk/out/plan.raw.json 에 저장한 뒤, 거기서 바뀔 태스크의 이름만 뽑아 JSON 배열로 /root/anschk/out/plan.json 에 저장합니다. 스크립트를 실행해 두 파일을 남기세요. 배열에는 이름이 정확히 하나만 들어 있어야 합니다.
8. /root/anschk/drift-gate.sh 를 만드세요. site.yml 을 점검 모드로 돌려 요약의 changed 가 0 이면 첫 줄이 CLEAN 으로 시작하는 메시지를 내고 0 으로 끝나고, 1 이상이면 첫 줄이 DRIFT 로 시작하는 메시지를 내고 1 로 끝납니다. 점검 모드 실행 자체가 실패하면 DRIFT-UNKNOWN 으로 시작하는 메시지를 내고 1 로 끝냅니다. 스크립트에 준 인자는 그대로 ansible-playbook 에 넘어가야 합니다. 수렴된 상태에서 인자 없이 돌린 출력을 /root/anschk/out/gate-clean.txt 에, -e app_env=stage 를 주고 돌린 출력을 /root/anschk/out/gate-dirty.txt 에 저장하세요.
참고
- 먼저 1단계에서 인벤토리와 플레이북을 만드세요. 이 파드의 sshd 는 127.0.0.1:2222 에 떠 있고 키 인증이 이미 됩니다.
- 명령 힌트:
ansible-playbook -i hosts.ini site.yml --check --diff가 기본 도구이고,ansible-doc -t callback -l로 쓸 수 있는 콜백을 봅니다. 출력은> 파일 2>&1로 표준 오류까지 받습니다. - 명령 힌트: 매직 변수
ansible_check_mode는 지금이 점검 모드인지 알려 줍니다. 태스크에 붙이는check_mode키는 그 태스크만 점검 모드 밖으로 빼거나(false) 안에 가둡니다(true). - 흔한 실수: 경고와 오류가 표준 오류로 나오는 것을 모르고
> 파일만 걸어 빈 파일을 남기는 것. - 흔한 실수: 실패로 끝나는 명령의 출력을 저장하다가
set -e때문에 거기서 스크립트가 멈추는 것. - 흔한 실수:
check_mode: false를 대상을 바꾸는 태스크에 붙여 dry run 자체를 거짓말로 만드는 것. - 이 파드에는 감사 로그나 외부 승인 시스템이 없어, 승인 절차는 계획 산출물을 파일로 남기는 데까지만 다룹니다. capability 도 없어 서비스 재시작 같은 태스크는 다루지 않고 파일과 디렉터리만 씁니다.
- [점검 모드로 검증하기](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_checkmode.html) · [ansible-playbook 옵션](https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html) · [lineinfile 모듈](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html) · [copy 모듈](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html) · [조건문](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_conditionals.html)
단계 8개
- 만들자마자 점검 모드로 먼저 본다
- 한 번 수렴시키고 값 셋을 바꿔 세 종류의 diff 를 본다
- 점검 모드에서 건너뛰어진 조회 태스크를 되살린다
- 점검 모드의 거짓 실패를 만들어 보고 가드로 고친다
- 실제 실행에서도 절대 바꾸지 않는 태스크를 만든다
- 세 도구의 종료 코드가 어디서 갈리는지 표로 세운다
- 승인에 붙일 계획 산출물을 만든다
- 점검 모드를 게이트로 바꾼다