LabHub
배우기 러닝패스 코스

Ansible基礎

一部だけ回したのに、なぜ最終状態ではないのか

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

태그로 플레이북의 일부만 돌리는 법을 익히고, 그 편의가 어떤 위험과 짝을 이루는지 직접 재 봅니다. 마지막에는 어떤 태그 선택이 완주할 수 있는지 판정하는 도구를 만듭니다.

왜 중요한가

플레이북은 자랍니다. 태스크가 여든 개인데 설정 한 줄만 고치고 싶은 날이 오고, 태그는 그 자리에 놓인 도구입니다. 문법이 쉬워서 사람들은 배운 다음 날부터 운영에서 씁니다. 사고는 거기서 납니다 — 태그는 실행을 자르는 칼인데, 플레이북은 잘려도 되게 설계되어 있지 않기 때문입니다. 앞 태스크가 만든 디렉터리를 뒤 태스크가 쓰고, 설정을 바꾼 태스크가 핸들러를 부릅니다. 일부만 고르면 그 연결이 끊어지고, 운이 나쁘면 실패조차 하지 않은 채 반쯤 맞는 상태가 남습니다. 그래서 이 실습은 태그 문법을 익히는 절반과, 자른 실행이 무엇을 보장하지 못하는지 눈으로 보는 절반으로 되어 있습니다.

단계

  1. /root/anstags/hosts.ini 를 만드세요 — [web]web1(ansible_host=127.0.0.1, ansible_port=2222), [all:vars]ansible_user=root. /root/anstags/site.yml 을 만드세요: 플레이 변수 app_env(기본 lab), 핸들러 reload app(/root/anstags/out/reload.markerreloaded 한 줄을 씁니다), 그리고 태스크 넷입니다 — /root/anstags/app 디렉터리를 0755 로 만드는 배포 자리를 만든다(태그 setup), /root/anstags/app/app.confenv=<app_env> 한 줄을 0644 로 쓰고 핸들러를 notify 하는 설정을 쓴다(태그 config), release_idr-2026 으로 정하는 배포 번호를 정한다(태그 prep, set_fact), /root/anstags/app/release.txtrelease_id 를 0644 로 쓰는 배포 번호를 기록한다(태그 deploy). 전체를 한 번 수렴시켜 출력을 /root/anstags/out/full.txt 에 저장하고, 이어서 --tags config 로 한 번 더 돌려 /root/anstags/out/config.txt 에 저장하세요.
  2. ansible-playbook -i hosts.ini site.yml --list-tags 의 출력을 /root/anstags/out/list-tags.txt 에 저장하세요. 그다음 --list-tasks --tags config 의 출력을 /root/anstags/out/list-config.txt 에 저장하세요. 두 번째 파일에는 설정을 쓴다 는 있고 배포 번호를 기록한다 는 없어야 합니다.
  3. --skip-tags prep,deploy 로 플레이북을 실제로 돌려 출력을 /root/anstags/out/skip.txt 에 저장하세요. 출력에는 배포 자리를 만든다설정을 쓴다TASK [...] 줄이 있고, 배포 번호를 정한다배포 번호를 기록한다 의 줄은 없어야 합니다. 그리고 --list-tasks --skip-tags prep,deploy 의 출력을 /root/anstags/out/list-skip.txt 에 저장하세요.
  4. 플레이 자체에 태그 platform 을 거세요. 그리고 설정을 검증한다 라는 이름의 블록을 태스크 끝에 더하고 그 블록에 태그 verify 를 다세요 — 블록 안에는 태그를 달지 않은 태스크 둘이 들어갑니다: /root/anstags/app/app.conf 의 상태를 읽어 conf_stat 으로 register 하는 설정 파일의 상태를 읽는다, 그 결과로 파일이 있는지 단언하는 설정 파일이 있는지 단언한다. --list-tasks 전체 출력을 /root/anstags/out/inherit.txt 에, --list-tasks --tags verify 출력을 /root/anstags/out/block.txt 에 저장하세요.
  5. 태스크 둘을 더하세요. 어떤 선택에서도 남기는 표식/root/anstags/out/always.markeralways 한 줄을 0644 로 쓰고 태그는 always 하나입니다. 함부로 돌면 안 되는 태스크/root/anstags/out/never.markerdanger 한 줄을 0644 로 쓰고 태그는 neverdanger 둘입니다. --tags config 로 실제로 돌려 출력을 /root/anstags/out/always.txt 에 저장하세요 — 어떤 선택에서도 남기는 표식 이 함께 돌아야 합니다. 그리고 --list-tasks --tags danger 출력을 /root/anstags/out/danger.txt 에 저장하세요. /root/anstags/out/never.marker 는 이 실습이 끝날 때까지 만들어지면 안 됩니다.
  6. /root/anstags/tasks/common.yml 을 만드세요 — 태스크 둘입니다. 공통 점검 하나common-one 을 출력하고 태그가 없습니다. 공통 점검 둘common-two 를 출력하고 태그 deep 을 갖습니다. 그다음 site.yml 끝에 태스크 둘을 더하세요 — import 로 공통 점검을 끌어온다(import_tasks 로 그 파일을 끌어오고 태그 imported)와 include 로 공통 점검을 끌어온다(include_tasks 로 같은 파일을 끌어오고 태그 included). --list-tasks --tags imported 출력을 /root/anstags/out/reuse-import.txt 에, --list-tasks --tags included 출력을 /root/anstags/out/reuse-include.txt 에 저장하세요.
  7. 먼저 /root/anstags/out/reload.marker 를 지우세요. 그다음 --start-at-task "배포 번호를 정한다" -e app_env=prod 로 플레이북을 실제로 돌리고 출력을 /root/anstags/out/startat.txt 에 저장하세요. 끝난 뒤 /root/anstags/app/app.conf 의 내용과 /root/anstags/out/reload.marker 의 존재 여부를 이어서 /root/anstags/out/aftermath.txt 에 남기세요 — 첫 줄은 conf=<app.conf 의 env 줄>, 둘째 줄은 marker=<yes 또는 no> 입니다.
  8. /root/anstags/tag-check.sh <태그목록> 을 만드세요. 그 선택으로 site.yml점검 모드로 돌려 보고, 정상으로 끝나면 첫 줄에 SAFE <태그목록> 을 내고 0 으로, 끝나지 않으면 첫 줄에 UNSAFE <태그목록> rc=<종료코드> 를 내고 1 로 끝냅니다. 그다음 ./tag-check.sh deploy./tag-check.sh prep,deploy 를 차례로 돌려 두 줄을 /root/anstags/out/tagcheck.txt 에 이어 저장하세요. 앞은 UNSAFE, 뒤는 SAFE 여야 합니다.

참고

태스크에 태그를 달고 전체를 한 번 수렴시킨다

/root/anstags/hosts.ini 를 만드세요 — [web]web1(ansible_host=127.0.0.1, ansible_port=2222), [all:vars]ansible_user=root. /root/anstags/site.yml 을 만드세요: 플레이 변수 app_env(기본 lab), 핸들러 reload app(/root/anstags/out/reload.markerreloaded 한 줄을 씁니다), 그리고 태스크 넷입니다 — /root/anstags/app 디렉터리를 0755 로 만드는 배포 자리를 만든다(태그 setup), /root/anstags/app/app.confenv=<app_env> 한 줄을 0644 로 쓰고 핸들러를 notify 하는 설정을 쓴다(태그 config), release_idr-2026 으로 정하는 배포 번호를 정한다(태그 prep, set_fact), /root/anstags/app/release.txtrelease_id 를 0644 로 쓰는 배포 번호를 기록한다(태그 deploy). 전체를 한 번 수렴시켜 출력을 /root/anstags/out/full.txt 에 저장하고, 이어서 --tags config 로 한 번 더 돌려 /root/anstags/out/config.txt 에 저장하세요.

태그는 이미 한 번 전체가 돌아간 시스템에 쓰는 도구입니다. 새 서버에 --tags config 만 걸면 디렉터리가 없어 실패하니, 첫 수렴은 반드시 전체로 합니다 — 그래서 이 단계는 전체 실행이 먼저입니다. 태그는 태스크에 tags: [이름] 으로 답니다. --tags config 로 돌린 출력에서 나머지 세 태스크의 TASK [...] 줄이 아예 없는 것을 확인하세요 — 걸러진 태스크는 건너뛴 것으로 표시되는 게 아니라 출력에서 통째로 빠집니다.

돌리기 전에 무엇이 돌지 목록으로 먼저 본다

ansible-playbook -i hosts.ini site.yml --list-tags 의 출력을 /root/anstags/out/list-tags.txt 에 저장하세요. 그다음 --list-tasks --tags config 의 출력을 /root/anstags/out/list-config.txt 에 저장하세요. 두 번째 파일에는 설정을 쓴다 는 있고 배포 번호를 기록한다 는 없어야 합니다.

이 두 도구는 대상에 붙지도 않고 아무것도 바꾸지도 않습니다 — 운영에서 태그를 처음 쓸 때 가장 먼저 걸어야 하는 것이 이것입니다. --list-tags 는 '이 플레이북에 어떤 태그가 있는가' 를 알려 주고, --list-tasks 는 '이번 선택으로 무엇이 돌 것인가' 를 순서대로 알려 줍니다. --list-tasks--tags 를 함께 주면 선택이 그대로 반영됩니다. 태스크마다 붙은 태그 목록도 같은 줄에 나오니 상속을 눈으로 확인할 때도 씁니다.

빼는 쪽으로 고른다

--skip-tags prep,deploy 로 플레이북을 실제로 돌려 출력을 /root/anstags/out/skip.txt 에 저장하세요. 출력에는 배포 자리를 만든다설정을 쓴다TASK [...] 줄이 있고, 배포 번호를 정한다배포 번호를 기록한다 의 줄은 없어야 합니다. 그리고 --list-tasks --skip-tags prep,deploy 의 출력을 /root/anstags/out/list-skip.txt 에 저장하세요.

고르는 방법은 두 가지입니다 — 넣을 것을 부르거나(--tags) 뺄 것을 부르거나(--skip-tags). 태그가 늘어나면 뒤쪽이 편할 때가 많습니다. 둘을 함께 줄 수도 있는데, 그때는 뺀 것이 이깁니다. 목록은 쉼표로 잇습니다. 돌리기 전에 목록으로 먼저 확인하는 습관은 --skip-tags 에서도 똑같이 값어치가 있습니다.

블록과 플레이에 건 태그가 아래로 흐른다

플레이 자체에 태그 platform 을 거세요. 그리고 설정을 검증한다 라는 이름의 블록을 태스크 끝에 더하고 그 블록에 태그 verify 를 다세요 — 블록 안에는 태그를 달지 않은 태스크 둘이 들어갑니다: /root/anstags/app/app.conf 의 상태를 읽어 conf_stat 으로 register 하는 설정 파일의 상태를 읽는다, 그 결과로 파일이 있는지 단언하는 설정 파일이 있는지 단언한다. --list-tasks 전체 출력을 /root/anstags/out/inherit.txt 에, --list-tasks --tags verify 출력을 /root/anstags/out/block.txt 에 저장하세요.

태그는 붙은 자리에서 아래로 흐릅니다. 블록에 달면 블록 안 모든 태스크가 갖고, 플레이에 달면 그 플레이의 모든 태스크가 갖습니다. 그 사실은 --list-tasks 의 각 줄 끝에 붙는 TAGS: [...] 에 그대로 드러납니다 — 블록 안 태스크에 아무것도 안 달았는데 태그가 둘 보이면 상속이 눈에 보인 것입니다. 상태를 읽는 모듈과 전제 조건을 단언하는 모듈은 이름이 떠오르지 않으면 ansible-doc -l ansible.builtin | grep -iE 'stat|assert' 로 찾으세요.

언제나 도는 태스크와 절대 안 도는 태스크

태스크 둘을 더하세요. 어떤 선택에서도 남기는 표식/root/anstags/out/always.markeralways 한 줄을 0644 로 쓰고 태그는 always 하나입니다. 함부로 돌면 안 되는 태스크/root/anstags/out/never.markerdanger 한 줄을 0644 로 쓰고 태그는 neverdanger 둘입니다. --tags config 로 실제로 돌려 출력을 /root/anstags/out/always.txt 에 저장하세요 — 어떤 선택에서도 남기는 표식 이 함께 돌아야 합니다. 그리고 --list-tasks --tags danger 출력을 /root/anstags/out/danger.txt 에 저장하세요. /root/anstags/out/never.marker 는 이 실습이 끝날 때까지 만들어지면 안 됩니다.

특수 태그는 다섯 개입니다 — always·never·tagged·untagged·all. 앞의 둘이 실무에서 쓰입니다. always 는 어떤 선택에서도 빠지면 안 되는 태스크(공통 변수 설정, 사실 수집)에 걸고, never 는 코드로는 남기되 손이 미끄러져 돌면 안 되는 태스크에 겁니다 — 주석 처리는 언젠가 풀리지만 never 는 풀리지 않습니다. never 가 붙은 태스크를 부르려면 함께 붙인 다른 이름표를 직접 불러야 합니다. 그 태스크는 --list-tasks 를 그냥 돌렸을 때 목록에 나오지도 않습니다 — 그것부터 확인해 보세요.

import 는 태그를 물려주고 include 는 물려주지 않는다

/root/anstags/tasks/common.yml 을 만드세요 — 태스크 둘입니다. 공통 점검 하나common-one 을 출력하고 태그가 없습니다. 공통 점검 둘common-two 를 출력하고 태그 deep 을 갖습니다. 그다음 site.yml 끝에 태스크 둘을 더하세요 — import 로 공통 점검을 끌어온다(import_tasks 로 그 파일을 끌어오고 태그 imported)와 include 로 공통 점검을 끌어온다(include_tasks 로 같은 파일을 끌어오고 태그 included). --list-tasks --tags imported 출력을 /root/anstags/out/reuse-import.txt 에, --list-tasks --tags included 출력을 /root/anstags/out/reuse-include.txt 에 저장하세요.

둘은 같은 파일을 끌어오지만 언제 끌어오는지가 다릅니다. 하나는 플레이북을 읽는 시점에 그 자리에 펼쳐지고(정적), 다른 하나는 실행 중에 비로소 끼어듭니다(동적). 그 차이가 태그 상속을 가릅니다 — 미리 펼쳐진 쪽은 태그가 태스크 하나하나에 붙고, 실행 중에 끼어드는 쪽은 문 자체에만 붙습니다. 두 목록 파일을 나란히 놓고 끌어온 파일 안의 태스크 이름이 보이는 쪽과 안 보이는 쪽을 확인하세요. 이것이 '오류 없이 아무 일도 안 일어나는' 고장의 정체입니다.

중간부터 돌리면 핸들러도 돌지 않는다

먼저 /root/anstags/out/reload.marker 를 지우세요. 그다음 --start-at-task "배포 번호를 정한다" -e app_env=prod 로 플레이북을 실제로 돌리고 출력을 /root/anstags/out/startat.txt 에 저장하세요. 끝난 뒤 /root/anstags/app/app.conf 의 내용과 /root/anstags/out/reload.marker 의 존재 여부를 이어서 /root/anstags/out/aftermath.txt 에 남기세요 — 첫 줄은 conf=<app.conf 의 env 줄>, 둘째 줄은 marker=<yes 또는 no> 입니다.

--start-at-task 는 그 이름의 태스크부터 시작합니다. 긴 플레이북이 중간에서 죽었을 때 1번부터 다시 돌리지 않으려고 쓰는 도구입니다. 그런데 앞 태스크가 만들었어야 할 것도, 앞 태스크가 보냈어야 할 notify 도 없는 채로 시작합니다 — 그래서 failed=0 으로 끝나도 시스템은 플레이북이 약속한 상태가 아닙니다. -e app_env=prod 를 함께 주었는데 설정 파일이 어떻게 되어 있는지, 핸들러 표식이 생겼는지를 직접 확인해 보세요. 이 단계의 답은 명령이 아니라 그 두 사실입니다.

어떤 태그 선택이 완주할 수 있는지 판정하는 도구

/root/anstags/tag-check.sh <태그목록> 을 만드세요. 그 선택으로 site.yml점검 모드로 돌려 보고, 정상으로 끝나면 첫 줄에 SAFE <태그목록> 을 내고 0 으로, 끝나지 않으면 첫 줄에 UNSAFE <태그목록> rc=<종료코드> 를 내고 1 로 끝냅니다. 그다음 ./tag-check.sh deploy./tag-check.sh prep,deploy 를 차례로 돌려 두 줄을 /root/anstags/out/tagcheck.txt 에 이어 저장하세요. 앞은 UNSAFE, 뒤는 SAFE 여야 합니다.

배포 번호를 기록한다배포 번호를 정한다 가 정한 값을 씁니다. 앞을 빼고 뒤만 고르면 그 변수는 정의되지 않은 채이고, 그것이 부분 실행이 위험한 첫 번째 방식입니다. 이 도구는 그 위험을 사람의 기억이 아니라 명령으로 바꿉니다. 판정에 점검 모드를 쓰는 이유는 운영에서 그대로 돌릴 수 있어야 하기 때문입니다 — 판정하려고 진짜로 바꾸면 도구가 아니라 사고입니다. 게이트가 1 로 끝나므로 결과를 파일에 모을 때 셸이 거기서 멈추지 않게 하세요.