소개
플레이북을 실행하는 것은 Ansible 작업의 일부일 뿐입니다. 작업 (task) 출력을 검사하고, 요약 (recap) 내용을 이해하며, 최종 관리 노드의 상태를 검증하는 과정이 필요합니다.
이 실습에서는 ansible-navigator를 사용하여 플레이북을 실행하고, 관리 대상 파일을 생성한 뒤, 플레이북을 다시 실행하여 원하는 상태가 유지되는지 확인하는 과정을 진행합니다.
프로젝트 구성 준비
이 단계에서는 추가적인 명령줄 옵션 없이 navigator 가 실행할 수 있는 프로젝트를 생성합니다. 구성은 이전 실습과 유사하지만, 이번에는 플레이북이 여러 파일을 관리하게 됩니다.
프로젝트 디렉터리를 생성하고 이동합니다.
cd /home/labex/project
mkdir -p rhce-ansible/{inventory/group_vars,playbooks,files}
cd rhce-ansible
인벤토리 및 구성 파일을 생성합니다.
cat > inventory/hosts <<'EOF'
[managed]
node1 ansible_connection=local
EOF
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
retry_files_enabled = False
interpreter_python = auto_silent
EOF
인벤토리는 로컬 호스트 별칭 하나를 포함하는 managed 그룹을 생성합니다. ansible.cfg 파일은 해당 인벤토리를 기본값으로 설정하므로, navigator 는 추가 인벤토리 플래그 없이도 프로젝트 디렉터리에서 플레이북을 실행할 수 있습니다.
cat > ansible-navigator.yml <<'EOF'
---
ansible-navigator:
mode: stdout
execution-environment:
enabled: false
playbook-artifact:
enable: false
EOF
navigator 설정은 이 실습을 터미널 중심으로 유지합니다. mode: stdout은 작업 출력을 직접 출력하며, 로컬 실행은 컨테이너 설정을 피하고, 아티팩트 (artifact) 를 비활성화하여 눈에 보이는 프로젝트 파일을 생성한 파일들로만 제한합니다.
플레이북을 위한 소스 콘텐츠 생성
이 단계에서는 플레이북이 배포할 소스 콘텐츠를 생성합니다. 프로젝트 내에 소스 파일을 유지하면 Ansible 이 관리하는 대상이 무엇인지 명확해집니다.
이 단계의 명령을 실행하기 전에 프로젝트 디렉터리로 돌아가 상대 경로가 Ansible 프로젝트를 참조하도록 합니다.
cd /home/labex/project/rhce-ansible
소스 파일을 생성합니다.
cat > files/motd.txt <<'EOF'
RHCE Ansible navigator practice host
EOF
이것은 소스 콘텐츠입니다. 즉, Ansible 이 배포하기를 원하는 파일이며 최종 관리 복사본이 아닙니다. 소스 파일을 생성된 출력물과 분리하여 보관하면 플레이북이 관리하는 대상을 더 쉽게 파악할 수 있습니다.
인벤토리 그룹 변수 파일에 대상 디렉터리 경로 변수를 생성합니다. 이 파일을 inventory/group_vars 아래에 유지하면 플레이북이 하위 디렉터리에 저장되어 있을 때도 일관되게 로드됩니다.
mkdir -p inventory/group_vars
cat > inventory/group_vars/all.yml <<'EOF'
managed_dir: /home/labex/project/rhce-ansible/managed-state
EOF
managed_dir은 프로젝트별 변수입니다. 이를 inventory/group_vars/all.yml에 정의하면 플레이북의 모든 작업에서 동일한 절대 경로를 반복하는 대신 변수 이름을 참조할 수 있습니다.
관리 상태 플레이북 작성
이 단계에서는 디렉터리를 생성하고 파일을 복사하는 플레이북을 작성합니다. file 모듈은 디렉터리와 권한을 관리하고, copy 모듈은 파일 콘텐츠를 배포합니다. 이 플레이북은 playbooks 디렉터리에 위치하므로, 소스 경로 ../files/motd.txt는 프로젝트 수준의 files 디렉터리를 가리킵니다.
이 단계의 명령을 실행하기 전에 프로젝트 디렉터리로 돌아가 상대 경로가 Ansible 프로젝트를 참조하도록 합니다.
cd /home/labex/project/rhce-ansible
playbooks/manage-state.yml을 생성합니다.
cat > playbooks/manage-state.yml <<'EOF'
---
- name: Manage local state with navigator
hosts: managed
gather_facts: false
tasks:
- name: Create managed state directory
ansible.builtin.file:
path: "{{ managed_dir }}"
state: directory
mode: '0755'
- name: Deploy managed message
ansible.builtin.copy:
src: ../files/motd.txt
dest: "{{ managed_dir }}/motd.txt"
mode: '0644'
EOF
플레이북을 순서대로 읽어보세요. 첫 번째 작업은 대상 디렉터리가 존재하는지 확인하고, 두 번째 작업은 소스 파일을 해당 디렉터리로 복사합니다. {{ managed_dir }} 표현식은 inventory/group_vars/all.yml에서 로드된 값으로 대체됩니다.
시스템을 변경하기 전에 구문 검사를 수행합니다.
ansible-playbook playbooks/manage-state.yml --syntax-check
이 검사는 navigator 로 플레이북을 실행할 예정이더라도 여전히 유용합니다. navigator 는 플레이북을 Ansible 에 전달하므로, 일반적인 구문 분석에 실패하는 플레이북은 navigator 를 통해서도 실패하게 됩니다.
Navigator 로 플레이북 실행
이 단계에서는 플레이북을 실행합니다. 요약 (recap) 라인이 중요합니다. ok는 원하는 상태에 도달한 작업 수를, changed는 무언가를 수정한 작업 수를 나타내며, failed=0은 실행이 성공적으로 완료되었음을 의미합니다.
이 단계의 명령을 실행하기 전에 프로젝트 디렉터리로 돌아가 상대 경로가 Ansible 프로젝트를 참조하도록 합니다.
cd /home/labex/project/rhce-ansible
플레이북을 실행합니다.
ansible-navigator run playbooks/manage-state.yml
관리되는 출력 파일을 직접 검사합니다.
요약 내용은 실행이 완료되었는지 알려주지만, 관리되는 파일은 요청된 상태가 실제로 존재하는지 증명합니다. files/motd.txt에 넣었던 것과 동일한 텍스트가 보여야 합니다.
cat managed-state/motd.txt
다시 실행하여 멱등성 검사
이 단계에서는 동일한 플레이북을 다시 실행합니다. 잘 작성된 플레이북은 반복해도 안전해야 합니다. 파일이 이미 요청된 콘텐츠와 권한을 가지고 있다면, Ansible 은 다시 변경할 필요가 없어야 합니다.
이 단계의 명령을 실행하기 전에 프로젝트 디렉터리로 돌아가 상대 경로가 Ansible 프로젝트를 참조하도록 합니다.
cd /home/labex/project/rhce-ansible
플레이북을 두 번째로 실행하고 출력을 저장합니다.
ansible-navigator run playbooks/manage-state.yml | tee navigator-second-run.txt
요약 내용을 검색합니다. 정확한 간격은 다를 수 있지만, 요약에는 여전히 실패가 없어야 합니다.
두 번째 실행은 반복 가능성에 관한 것입니다. failed=0으로 깔끔하게 실행되는 것은 플레이북이 관리 상태를 깨뜨리지 않고 다시 적용될 수 있음을 증명합니다. 만약 changed=0이 함께 나타난다면, 작업이 이미 충족된 상태임을 의미합니다.
grep -E 'failed=0' navigator-second-run.txt
요약
ansible-navigator를 사용하여 플레이북을 실행하고, 생성된 관리 파일을 검사했으며, 플레이북을 반복 실행하여 깔끔하게 작동하는지 확인했습니다. 이것이 Ansible 자동화 작업 전반에 걸쳐 사용되는 기본적인 '실행 - 검사 - 검증' 루프입니다.



