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

any_errors_fatal

플레이북은 실행 중 특정 작업에서 실패가 발생하면 기본적으로 실패한 노드만 정지합니다. 나머지 노드는 실패하지 않는 한 작업을 끝까지 이어갑니다. Playbook Error Handling 방법의 하나로 any_errors_fatal 지시어를 사용하여 플레이북 실행 시 하나의 노드가 실패할 경우 전체 노드가 정지하게 하는 방법을 알아보도록 하겠습니다.

 

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

웹 서버를 설치하는 간단한 플레이북을 실행시켜 작업이 실패했을 때 어떤 동작을 하는지 살펴보도록 하겠습니다.

# 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

위에서 작성한 웹서버 설치 플레이북을 실행합니다. 인벤토리 목록은 node1과 node2가 있으며, “node2”에는 yum repo를 구성하지 않아 일부로 실패하도록 만들었습니다.

# 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

작업 결과를 보면 node2는 첫 번째 “install http package” 작업에서 실패 후 더 이상 작업이 진행되지 않습니다. 반면에 node1은 “start http service” 작업까지 모두 진행되는 걸 보실 수 있습니다. 이는 예상된 결과입니다. 플레이북이 실행될 때는 실패한 노드만 제외되고 성공한 노드는 계속해서 작업을 이어가도록 설계되어 있습니다.

 

하나의 노드가 실패하면 모든 노드에서 플레이 중단

어느 노드든 작업이 실패하는 경우 바로 모든 플레이를 중지하도록 설정할 수 있습니다. 예를 들어 여러 호스트에서 동일한 작업을 처리할 때 어느 하나의 노드에서 에러가 발생하면 전체 플레이를 중지해야 하는 경우 사용할 수 있습니다. 해당 기능을 지원하는 “any_errors_fatal” 옵션을 사용합니다.

 

any_errors_fatal 설정

위에서 사용했던 webserver.yaml 플레이북에 “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

아래 플레이북 실행 결과를 보면 “install http package” 작업에서 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

max_fail_percentage 설정

좀 더 세밀한 제어를 위해 “max_fail_percentage” 옵션을 사용할 수도 있습니다. 이 설정은 실패 비율을 %로 정의할 수 있습니다. 예를 들어 롤링 업데이트 같은 작업에서 일부 노드의 실패를 용인하고 작업을 진행할 때 사용할 수 있습니다.

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

다음과 같이 10으로 정의된 경우 앤서블은 10% 이하의 노드가 실패해도 다른 노드의 작업 진행을 보장합니다.

퍼센트 설정은 지정된 백분율을 초과해야 플레이가 정지됩니다. 예를 들어, 4개의 노드가 있는 경우 2개의 노드 작업 실패 시 플레이북을 중지하기 위해서는 50%가 아닌 49%로 설정해야 합니다.

 

참고

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

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Scroll to Top