二度回しても静かなプレイブックを作る
한국어 원문으로 표시합니다.
목표
같은 플레이북을 몇 번을 돌려도 두 번째부터는 아무것도 바뀌지 않는 상태를 만들고, 그 사실을 로그와 보고서로 증명합니다.
왜 중요한가
멱등성은 "예쁜 코드"의 문제가 아니라 자동화를 실제로 쓸 수 있게 만드는 조건입니다. 두 번째 실행이 안전하다는 확신이 있어야 크론으로 주기 실행을 걸어 드리프트를 잡을 수 있고, 파이프라인 중간 실패 후에도 겁 없이 재실행할 수 있습니다. 반대로 매번 서비스를 재시작하는 플레이북은 사람들이 피하게 되고, 피하는 자동화는 곧 없는 자동화입니다. 핵심 장치는 상태를 아는 모듈, 셸 명령의 가드(creates/changed_when), 그리고 변경이 있을 때만 도는 핸들러입니다. 특히 핸들러가 플레이 끝에 몰려 실행된다는 점은 꼭 기억하세요 — 중간에 플레이가 실패하면 핸들러가 통째로 사라져 "설정은 바뀌었는데 서비스는 옛 설정을 보고 있는" 상태가 됩니다.
단계
/root/ans/idem/site.yml을 만들어 실행하고 출력을/root/ans/idem/out/run1.txt로 저장하세요. 첫 실행의changed는 2 이상이어야 합니다.- 같은 플레이북을 다시 실행해
/root/ans/idem/out/run2.txt로 저장하세요. 이번에는changed=0이어야 합니다. reload app이라는 핸들러를 정의하고, 설정을 다루는 태스크에서notify로 부르세요. 핸들러는 실행될 때/root/ans/idem/artifacts/reload.marker를 만들어야 합니다.- 두 번째 실행 로그(
run2.txt)에RUNNING HANDLER가 없어야 합니다. 첫 실행 로그에는 있어야 합니다. command/shell태스크를 하나 넣되creates가드를 붙이세요. 그 태스크는/root/ans/idem/artifacts/stamp.txt에 한 줄을 쓰고, 두 번 실행해도 파일에 한 줄만 있어야 합니다.- 조회만 하는 태스크에
changed_when을, 실패 판정이 필요한 태스크에failed_when을 각각 최소 한 번씩 쓰세요. - 플레이북을
--check로 실행한 출력을/root/ans/idem/out/check.txt로 저장하세요.changed=0,failed=0이어야 합니다. /root/ans/idem/out/idempotency.json을 만드세요.run1_changed(2 이상),run2_changed(0),handler_fired(1 또는 true),verdict("idempotent") 네 키를 담습니다.
참고
- 실습 파드는 실습마다 새로 뜹니다.
/root/ans/inventory/hosts.ini가 없으면 첫 실습에서 만든 것과 같은 인벤토리(web1·web2·db1,ansible_host=127.0.0.1,ansible_port=2222,ansible_user=root,[prod:children]에 web·db)를 먼저 다시 만드세요. 구조는/opt/lab/fixtures/ansible/inventory.sample.ini를 참고하면 됩니다. - PLAY RECAP 줄의
changed=N이 판정 기준입니다. - 핸들러 이름과
notify문자열은 정확히 같아야 합니다. 한 글자만 달라도 조용히 무시됩니다. - 흔한 실수 1: 템플릿에 시각이나 랜덤 값을 넣어 매번 렌더링 결과가 달라지는 것. 그러면 영원히
changed가 납니다. - 흔한 실수 2:
shell로 파일에 추가(>>)하면서 가드를 붙이지 않는 것. 실행할 때마다 줄이 쌓입니다.
첫 실행에서 변경 만들기
/root/ans/idem/site.yml 을 만들어 실행하고 출력을 /root/ans/idem/out/run1.txt 로 저장하세요. 첫 실행의 changed 는 2 이상이어야 합니다.
디렉터리·파일·설정을 만드는 태스크 몇 개면 충분합니다. 실행 결과 전체를 파일로 남기세요.
두 번째 실행에서 changed=0 만들기
같은 플레이북을 다시 실행해 /root/ans/idem/out/run2.txt 로 저장하세요. 이번에는 changed=0 이어야 합니다.
같은 플레이북을 다시 돌립니다. changed 가 0 이 아니면 어떤 태스크가 범인인지 로그에서 찾으세요.
핸들러 정의하고 notify 로 부르기
reload app 이라는 핸들러를 정의하고, 설정을 다루는 태스크에서 notify 로 부르세요. 핸들러는 실행될 때 /root/ans/idem/artifacts/reload.marker 를 만들어야 합니다.
핸들러 이름과 notify 의 문자열이 정확히 같아야 합니다. 핸들러가 돌면 마커 파일을 남기게 하세요.
두 번째 실행에서 핸들러가 안 돌게 하기
두 번째 실행 로그(run2.txt)에 RUNNING HANDLER 가 없어야 합니다. 첫 실행 로그에는 있어야 합니다.
notify 는 태스크가 changed 일 때만 발화합니다. 두 번째 실행 로그에 RUNNING HANDLER 가 없어야 합니다.
셸 명령에 creates 가드 붙이기
command/shell 태스크를 하나 넣되 creates 가드를 붙이세요. 그 태스크는 /root/ans/idem/artifacts/stamp.txt 에 한 줄을 쓰고, 두 번 실행해도 파일에 한 줄만 있어야 합니다.
명령이 만들어 내는 파일 경로를 creates 로 알려 주면 두 번째부터는 건너뜁니다. 로그가 한 줄만 쌓여야 합니다.
보고 기준 직접 정하기
조회만 하는 태스크에 changed_when 을, 실패 판정이 필요한 태스크에 failed_when 을 각각 최소 한 번씩 쓰세요.
조회만 하는 명령은 changed_when: false 로 두고, 실패 판정이 필요한 곳에는 failed_when 을 쓰세요.
점검 모드에서도 변경 없음 확인하기
플레이북을 --check 로 실행한 출력을 /root/ans/idem/out/check.txt 로 저장하세요. changed=0, failed=0 이어야 합니다.
이미 수렴한 상태라면 --check 실행도 changed=0 이어야 합니다. 점검 모드를 지원하지 않는 모듈이 있으면 실패가 납니다.
멱등성 판정 보고서 만들기
/root/ans/idem/out/idempotency.json 을 만드세요. run1_changed(2 이상), run2_changed(0), handler_fired(1 또는 true), verdict("idempotent") 네 키를 담습니다.
두 실행의 changed 수와 핸들러 발화 횟수를 JSON 으로 정리하고, 판정 문자열을 넣으세요.