유지보수 명령 실행 및 실패 처리

AnsibleBeginner
지금 연습하기

소개

기존 유지보수 프로그램을 선언형 자동화에 통합할 때는 주의가 필요합니다. command, shell, script를 구분하고 공백이 있는 경로를 안전하게 전달하며 읽기 전용 결과를 분류하고 실제 스크립트 출력에 실행 가드를 적용합니다. 파이프라인과 위임된 컨트롤러 수신 기록으로 실행 위치와 실패 전파를 관찰합니다. 실제 입력 누락 실패도 유발하고 복구합니다.

안전한 인수로 직접 명령 실행하기

이 단계에서는 command로 관리 입력을 점검하고 공백이 있는 경로를 보존하며 읽기 전용 작업을 올바르게 분류합니다.

상태 관리에는 copy와 file 같은 선언형 모듈을 우선 사용하세요. command, shell, script는 기존 실행 파일이나 유지보수 프로그램을 통합할 때 유용합니다. command는 셸 없이 관리 실행 파일을 실행하므로 파이프와 리다이렉션을 해석하지 않습니다. argv 형식은 공백이 있는 경로도 포함하여 각 인수를 분리해 유지합니다.

준비된 각 대상에는 승인된 데이터 한 줄이 있는 /home/automation/maintenance input.txt와 maintenance-ready 사전 입력이 있습니다. 컨트롤러는 이후에 사용할 기존 스크립트를 scripts/ 아래에 제공합니다. 이 입력들을 보존하세요.

컨트롤러 프로젝트로 이동합니다.

cd /home/labex/project

argv를 사용하는 플레이북을 만듭니다. 공백이 있는 경로는 YAML 목록 항목 하나입니다. register는 stdout과 숫자 반환 코드 rc를 포함한 실행 결과를 저장합니다. 보통 0은 성공을 뜻하고 0이 아닌 명령 반환 코드는 태스크를 실패시킵니다.

cat > maintenance.yml <<'YAML'
- name: Inspect maintenance inputs safely
  hosts: all
  gather_facts: false
  tasks:
    - name: Read the managed input with a space-safe argument list
      ansible.builtin.command:
        argv:
          - /usr/bin/cat
          - /home/automation/maintenance input.txt
      register: input_result
      changed_when: false

    - name: Retain the inspected input in a managed record
      ansible.builtin.copy:
        dest: /home/automation/command-result.txt
        content: "{{ input_result.stdout }}\n"
        mode: "0640"
YAML

cat 명령은 읽기 전용이므로 changed_when false는 결과를 변경 없음으로 분류합니다. 이 설정은 명령의 실제 동작이 아니라 보고를 바꿉니다. 변경하는 프로그램의 변경을 숨기는 데 사용하면 안 됩니다. copy 태스크는 반환된 stdout을 사용하여 명시적인 마지막 줄바꿈이 있는 실제 관리 기록을 씁니다.

플레이북을 확인하고 실행합니다.

ansible-playbook maintenance.yml --syntax-check
ansible-playbook maintenance.yml

두 읽기 태스크는 ok를 보고하고 최초 기록 복사는 각 대상을 변경해야 합니다. 실제 기록을 점검합니다.

ansible all -m ansible.builtin.command -a 'cat /home/automation/command-result.txt'

각 기록에는 Approved maintenance data가 있어야 합니다. 이 core 버전에서는 command가 셸을 호출하지 않아도 Python을 통해 환경 변수 인수를 확장할 수 있습니다. 달러 접두사 인수가 문자 그대로 필요하면 expand_argument_vars false를 사용하세요. 이 고정 경로에는 필요하지 않습니다.

컨트롤러 스크립트 전송 및 실제 출력에 가드 적용하기

이 단계에서는 제공된 컨트롤러 측 유지보수 스크립트를 두 대상에서 호출하고 불필요한 반복 실행을 피합니다.

실행 전에 제공된 프로그램을 살펴봅니다.

cat scripts/host-maintenance.sh

프로그램은 출력을 만들기 전에 대상의 maintenance-ready 입력을 확인합니다. 준비 입력이 없으면 오류를 출력하고 42로 종료합니다. 있으면 실제 대상 호스트 이름과 레이블 인수가 포함된 보호된 보고서를 씁니다. 작은 셸 구현은 기존 통합 입력이며 일반 파일 구성에는 선언형 모듈을 사용하세요.

script 모듈은 컨트롤러 소스를 대상으로 전송하고 그곳에서 실행합니다. 이는 실행 파일이 관리 노드에 이미 있어야 하는 command와 다릅니다. 아래 따옴표로 감싼 레이블은 공백이 있는 인수 하나로 유지됩니다. creates 경로는 관리 대상에서 확인하며 보고서가 이미 있으면 스크립트를 건너뜁니다.

스크립트 태스크를 덧붙입니다.

cat >> maintenance.yml <<'YAML'

    - name: Run the supplied controller script once per target report
      ansible.builtin.script:
        cmd: /home/labex/project/scripts/host-maintenance.sh 'Maintenance checked'
        creates: /home/automation/maintenance-run/report.txt
      register: maintenance_result
      failed_when: maintenance_result.rc is defined and maintenance_result.rc != 0
YAML

등록 결과의 rc가 failed_when을 제어합니다. is defined 가드는 실행 반환 코드가 없는 결과를 처리합니다. ignore_errors나 failed_when false로 실제 스크립트 실패를 겉보기 성공으로 바꾸지 마세요.

확장된 플레이북을 실행합니다.

ansible-playbook maintenance.yml

두 대상 모두 보고서를 만들어야 합니다. 실제 출력을 읽습니다.

ansible all -m ansible.builtin.command -a 'cat /home/automation/maintenance-run/report.txt'

각 출력에는 자신의 호스트 이름과 label=Maintenance checked가 있어야 합니다. 같은 플레이북을 반복합니다.

ansible-playbook maintenance.yml

대상 보고서가 있으므로 스크립트를 건너뛰고 두 요약은 실패/연결 불가 대상 없이 changed=0을 보고해야 합니다. creates는 존재 가드이지 콘텐츠 조정 도구가 아닙니다. 손상된 기존 보고서를 수정하거나 스크립트 입력이 바뀔 때 자동으로 다시 만들지는 않습니다.

실패 전파 및 컨트롤러 수신 기록 위임하기

이 단계에서는 실제 파이프라인에만 shell을 사용하고 별도 컨트롤러 수신 기록을 저장하며 스크립트 실패를 숨기지 않고 드러내는 연습을 합니다.

파이프는 한 명령의 출력을 다른 명령의 입력에 연결하므로 shell이 필요합니다. Bash pipefail은 파이프라인 안의 실패한 명령이 실패 결과를 만들게 하여 마지막 wc의 성공이 이를 숨기지 못하게 합니다. 아래 파이프라인은 입력 줄 수만 세므로 대상 상태를 바꾸지 않는 changed_when false가 적절합니다. failed_when은 예상치 못한 줄 수도 거부합니다.

컨트롤러 수신 기록 디렉터리를 만듭니다. 위임된 각 copy는 원래 인벤토리 이름을 별도 파일 이름에 사용하므로 호스트가 하나의 공용 기록을 덮어쓰지 않습니다.

mkdir -p receipts

파이프라인과 수신 기록 태스크를 덧붙입니다. delegate_to localhost는 수신 기록 태스크만 컨트롤러에서 실행하며 inventory_hostname은 여전히 원래 대상을 식별합니다. become false는 일반 labex 계정으로 컨트롤러 파일을 생성하게 합니다.

cat >> maintenance.yml <<'YAML'

    - name: Count managed input lines with explicit pipeline failure propagation
      ansible.builtin.shell: |
        set -o pipefail
        cat '/home/automation/maintenance input.txt' | wc -l
      args:
        executable: /bin/bash
      register: line_result
      changed_when: false
      failed_when: line_result.rc != 0 or (line_result.stdout | trim) != '1'

    - name: Store a per-target receipt on the controller
      ansible.builtin.copy:
        dest: "/home/labex/project/receipts/{{ inventory_hostname }}.txt"
        content: |
          host={{ inventory_hostname }}
          input_lines={{ line_result.stdout | trim }}
        mode: "0640"
      delegate_to: localhost
      become: false
YAML

전체 유지보수 흐름을 실행합니다.

ansible-playbook maintenance.yml

두 컨트롤러 수신 기록을 확인합니다. 각각 자신의 원래 호스트와 input_lines=1을 식별해야 합니다.

cat receipts/web1.txt receipts/web2.txt

이제 web1에서 스크립트의 실제 실패 분기를 연습합니다. file 모듈로 가드 대상 보고서와 준비 입력을 제거합니다. 이는 교육 노드 안의 의도적인 임시 변경입니다.

ansible web1 -m ansible.builtin.file -a 'path=/home/automation/maintenance-run/report.txt state=absent'
ansible web1 -m ansible.builtin.file -a 'path=/home/automation/maintenance-ready state=absent'

다음 실행은 web1 스크립트 태스크에서 rc 42와 입력 누락 메시지로 실패해야 합니다. ||는 예상한 0이 아닌 플레이북 종료 후 Terminal 흐름을 계속하게 하며 Ansible 실패 분류를 바꾸지 않습니다.

ansible-playbook maintenance.yml || printf 'Expected missing-readiness failure\n'

보고서 경로를 확인합니다. 스크립트 실패 후 web1에 꾸며 낸 성공 보고서가 있어서는 안 됩니다.

ansible web1 -m ansible.builtin.stat -a 'path=/home/automation/maintenance-run/report.txt'

정확한 컨트롤러 소스로 준비 입력을 복원하고 전체 흐름을 다시 실행합니다.

printf 'Ready\n' > ready.txt
ansible web1 -m ansible.builtin.copy -a 'src=/home/labex/project/ready.txt dest=/home/automation/maintenance-ready mode=0644'
ansible-playbook maintenance.yml

web1은 보고서를 성공적으로 다시 생성해야 합니다. 마지막 반복에는 변경, 연결 불가 대상, 실패가 없어야 합니다.

ansible-playbook maintenance.yml

읽기 전용 점검은 여전히 실행되고 가드가 있는 스크립트는 기존 보고서를 건너뛰며 각 위임된 기록은 컨트롤러에 남습니다. 이렇게 하면 성공한 반복 실행을 안정적으로 유지하면서 실제 오류 신호를 보존할 수 있습니다.

요약

직접 관리 실행에는 argv, 컨트롤러에서 대상으로 프로그램 전송에는 script를 사용하고 명시적 실패 전파가 필요한 실제 파이프라인에만 shell을 사용했습니다. 읽기 전용 변경 보고, 실제 creates 가드, 숨기지 않은 종료 코드가 결과의 의미를 유지했습니다. 위임된 호스트별 수신 기록은 컨트롤러 실행을 보여 주었고 입력 누락 연습은 복원되고 안정된 흐름으로 끝났습니다.