[Ansible] Error Handling #1 - any_errors_fatal 하나의 노드 작업 실패 시 모든 노드 플레이 정지

 


Ansible 플레이북 실행 중 하나의 노드에서 오류가 발생했을 때 전체 실행 흐름을 제어하는 방법을 소개합니다.

 

플레이북이 실패한 노드를 처리하는 기본 방법

Ansible 플레이북은 실행 중 특정 작업에서 실패가 발생하면 기본적으로 실패한 노드만 작업을 중단하고, 나머지 노드는 정상적으로 작업을 끝까지 수행합니다. 이는 병렬 처리 환경에서 효율성을 높이기 위한 기본 동작입니다.

예를 들어, 웹 서버 설치를 위한 간단한 플레이북을 아래와 같이 작성합니다. 이때 node2는 Yum 리포지토리를 설정하지 않아 설치 작업이 실패하도록 구성되어 있습니다.

# cat webserver.yaml 
---
- name: install web service
  hosts: all
  tasks:
    - name: install http package
      ansible.builtin.dnf: 
        name: httpd
        state: present 

    - name: start http service
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: yes

플레이북을 실행해 보면, node2는 패키지 설치 실패 후 이후 작업이 진행되지 않고 중단됩니다. 반면 node1은 모든 작업을 정상적으로 완료합니다.

# ansible-playbook webserver.yaml 

PLAY [install web service] *****************************************************

TASK [Gathering Facts] *********************************************************
ok: [node2]
ok: [node1]

TASK [install http package] ****************************************************
fatal: [node2]: FAILED! => {"changed": false, "msg": "Failed to download metadata for repo 'local-OS': Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried", "rc": 1, "results": []}
changed: [node1]

TASK [start http service] ******************************************************
changed: [node1]

PLAY RECAP *********************************************************************
node1                      : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

이처럼 Ansible은 기본적으로 작업 실패가 발생한 노드만 제외하고, 나머지 노드는 계속 작업을 이어서 수행합니다.

 

모든 노드에서 작업 중단하기 - any_errors_fatal

어떤 경우에는 하나의 노드에서라도 실패가 발생하면 모든 노드에서 즉시 작업을 중단해야 할 필요가 있습니다. 예를 들어, 전체 일관성이 중요한 배포 작업에서는 이런 방식이 필요합니다.

이를 위해 Ansible에서는 any_errors_fatal: true 지시어를 사용할 수 있습니다. 이 설정을 통해 하나의 노드에서 오류가 발생하면 모든 호스트에서 현재 작업까지만 완료하고 플레이북 실행을 중지합니다.

# cat webserver.yaml 
---
- name: install web service
  hosts: all
  any_errors_fatal: true
  tasks:
    - name: install http package
      ansible.builtin.dnf: 
        name: httpd
        state: present 

    - name: start http service
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: yes

위 설정을 적용한 상태에서 플레이북을 실행하면, node2에서 패키지 설치 실패가 발생한 뒤 node1도 다음 작업을 진행하지 않고 즉시 플레이북이 중단됩니다.

# ansible-playbook webserver.yaml 

PLAY [install web service] **********************************************************

TASK [Gathering Facts] **************************************************************
ok: [node2]
ok: [node1]

TASK [install http package] *********************************************************
fatal: [node2]: FAILED! => {"changed": false, "msg": "Failed to download metadata for repo 'local-OS': Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried", "rc": 1, "results": []}
ok: [node1]

NO MORE HOSTS LEFT ******************************************************************

PLAY RECAP **************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
이처럼 any_errors_fatal 옵션은 전체 실행 흐름을 즉시 멈추고 복구 또는 점검이 필요한 상태로 전환하는 데 유용합니다.


실패 허용 비율 설정 - max_fail_percentage

보다 유연한 오류 제어가 필요한 경우에는 max_fail_percentage 옵션을 사용할 수 있습니다. 이 설정은 전체 호스트 중 몇 퍼센트까지 실패를 허용할지를 정의합니다.

예를 들어, 롤링 배포와 같이 일부 실패를 허용하고 나머지 노드에 계속 작업을 진행해야 하는 상황에 적합합니다.

---
- name: install web service
  hosts: all
  max_fail_percentage: 10

위 예시는 노드 중 10%까지는 실패해도 플레이가 계속 진행되도록 설정한 것입니다. 단, 백분율을 초과해야 중단되므로, 예를 들어 4개의 노드가 있다면 2개 실패 시 중단하려면 49%로 설정해야 합니다.

 

참고

https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_error_handling.html

댓글

이 블로그의 인기 게시물

[Linux] RHEL Local YUM Repository 구성

[Linux Command] sudo command 설명

[Ansible Modules] Fetch module 설명 및 활용