[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
댓글
댓글 쓰기