-
[Ansible 101] 핸들러 및 작업 실패 처리IT/Ansible 2024. 1. 21. 08:08728x90
앤서블 모듈은 멱등(idempotent)이 가능하도록 설계되어 있습니다.
즉, 플레이북을 여러 번 실행해도 결과는 항상 동일합니다.
또한 플레이 및 해당 작업은 여러 번 실행할 수 있지만,
해당 호스트는 원하는 상태로 만드는 데 필요한 경우에만 변경됩니다.
하지만 한 작업에서 시스템을 변경해야 하는 경우 추가 작업을 실행해야 할 수도 있습니다.
예를 들어 서비스의 구성 파일을 변경하려면 변경 내용이 적용되도록 서비스를 다시 로드해야 합니다.
이때 핸들러는 다른 작업에서 트리거한 알림에 응답하는 작업이며, 해당 호스트에서 작업이 변경될 때만 핸들러에 통지합니다.
1. 핸들러
#1. Handlers
참조 링크 : https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html
앤서블에서 핸들러를 사용하려면 notify 문을 사용하여 명시적으로 호출된 경우에만 사용할 수 있습니다.
또한 핸들러를 정의할 때는 같은 이름으로 여러 개의 핸드러를 정의하기보다는 각각의 고유한 이름을 사용하여 정의하는 것이 좋습니다.
1) 플레이북 생성
rsyslog 재시작 태스크가 실행되면 notify 키워드를 통해 print msg라는 핸들러를 호출합니다.
* 핸들러는 handlers 키워드로 시작합니다.
~/my-ansible/handler-sample.yml
--- - hosts: tnode2 tasks: - name: restart rsyslog ansible.builtin.service: name: "rsyslog" state: restarted notify: - print msg handlers: - name: print msg ansible.builtin.debug: msg: "rsyslog is restarted"
2) 실행
마찬가지로, 한번 더 실행하더라도 동일한 결과를 얻습니다.
앞서 설명드린 듯이, 앤서블은 멱등성을 띄고 있기 때문입니다.
#2. 작업 실패 무시
- 앤서블은 플레이 시 각 작업의 반환 코드를 평가하여 작업의 성공 여부를 판단합니다.
일반적으로는 작업이 실패하면 앤서블은 이후의 모든 작업을 건너뜁니다. - 하지만 작업이 실패해도 플레이를 계속 실행할 수 있습니다. 이는 ignore_errors라는 키워드로 구현할 수 있습니다.
1) 플레이북 생성
다음의 내용은 강제로 apache3 패키지를 설치하는 내용입니다.
어떻게 되는지 한번 보겠습니다.
우선 두개의 플레이북을 생성해 주겠습니다.
~/my-ansible/ignore-example-1.yml
--- - hosts : tnode1 tasks: - name: Install apache3 ansible.builtin.apt: name: apache3 state: latest - name: Print msg ansible.builtin.debug: msg: "Before task is ignored"
~/my-ansible/ignore-example-2.yml
--- - hosts : tnode1 tasks: - name: Install apache3 ansible.builtin.apt: name: apache3 state: latest ignore_errors: yes - name: Print msg ansible.builtin.debug: msg: "Before task is ignored"
위 두 개의 플레이북은 ignore_errors: yes 구문의 유무가 다릅니다.
플레이북 1 실행 후,
플레이북 2 실행 후,
ignore-example-2.yml을 실행했을 때는 ignore_errors를 거쳐서 플레이북이 실행되는 것을 확인하실 수 있습니다.
#3. 작업 실패 후 핸들러
- 앤서블은 일반적으로 작업이 실패하고 해당 호스트에서 플레이가 중단되면 이전 작업에서 알림을 받은 모든 핸들러가 실행되지 않습니다.
- 하지만 플레이북에 force_handlers: yes 키워드를 설정하면 이후 작업이 실패하여 플레이가 중단되어도 알림을 받은 핸들러가 호출됩니다.
이번 세션에 사용할 모듈은 다음의 세 가지입니다.
ansible.builtin.apt 모듈
- 참조 링크 : https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.htmlansible.builtin.dnf 모듈
- 참조 링크 : https://docs.ansible.com/ansible/latest/collections/ansible/builtin/dnf_module.htmlError handling in playbooks
- 참조 링크 : https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_error_handling.html
1) 플레이북 생성
hosts 아래 force_handlers: yes 를 추가하고, install apache2 태스크를 추가합니다.
~/my-ansible/force-handler-1.yml
--- - hosts: tnode2 tasks: - name: restart rsyslog ansible.builtin.service: name: "rsyslog" state: restarted notify: - print msg - name: install apache3 ansible.builtin.apt: name: "apache3" state: latest handlers: - name: print msg ansible.builtin.debug: msg: "rsyslog is restarted"
~/my-ansible/force-handler-2.yml
--- - hosts: tnode2 force_handlers: yes tasks: - name: restart rsyslog ansible.builtin.service: name: "rsyslog" state: restarted notify: - print msg - name: install apache3 ansible.builtin.apt: name: "apache3" state: latest handlers: - name: print msg ansible.builtin.debug: msg: "rsyslog is restarted"
2) 실행
플레이북을 실행하면, 두 번째 플레이북에서 install apache3 태스크가 실패했음에도 불구하고 print msg 핸들러가 실행된 것은 앞서 말씀드린 force_handlers: yes 옵션 때문입니다.
이 옵션은 실패한 태스크가 있더라도 등록된 핸들러를 강제로 실행하게 만듭니다.
이러한 동작은 특히 어떤 태스크가 실패했을 때도 중요한 정리 작업이나 알림을 보내야 할 경우 유용합니다.예를 들어, 특정 서비스를 재시작해야 하거나 실패 알림을 보내야 하는 경우 등에 사용됩니다.
#4. 작업 실패 조건 지정 (shell script 보다는 module을 사용하자)
- 앤서블에서 셸 스크립트를 실행한 뒤 결과로 실패 또는 에러 메시지를 출력해도, 앤서블에서는 작업이 성공했다고 간주합니다.
- 어떤 명령이라도 실행된 경우에는 태스크 실행 상태를 항상 changed 로 합니다.
- 이런 경우 failed_when 키워드를 사용하여 작업이 실패했음을 나타내는 조건을 지정할 수 있습니다.
1) 스크립트 생성
~/my-ansible/adduser-script.sh
# 사용자 추가하는 스크립트 파일 내용 확인 cat ~/my-ansible/Easy-Ansible/chapter_07.3/adduser-script.sh cp ~/my-ansible/Easy-Ansible/chapter_07.3/adduser-script.sh adduser-script.sh chmod +x adduser-script.sh ls -l adduser-script.sh # 해당 스크립트로 user1 생성해보기 ## "passwd: unrecognized option '--stdin'" 에러는 암호 적용 부분에서 발생 sudo ./adduser-script.sh sudo ./adduser-script.sh "user1" "qwe123" tail -n 3 /etc/passwd sudo userdel -rf user1
2) tnode1에 스크립트를 복사 후 확인
# 사용자 추가하는 스크립트 파일을 tnode1에 복사 ansible -m copy -a 'src=/home/ubuntu/my-ansible/adduser-script.sh dest=/home/ubuntu/adduser-script.sh' tnode1 # 복사 확인 ssh tnode1 ls -l /home/ubuntu/ -rw-r--r-- 1 root root 846 Jan 13 22:09 adduser-script.sh # 스크립트 실행 확인 ssh tnode1 --------------- sudo chmod +x adduser-script.sh sudo ./adduser-script.sh exit ---------------
3) 플레이북 생성
~/my-ansible/failed-when-1.yml
--- - hosts: tnode1 tasks: - name: Run user add script ansible.builtin.shell: /home/ubuntu/adduser-script.sh register: command_result - name: Print msg ansible.builtin.debug: msg: "{{ command_result.stdout }}"
~/my-ansible/failed-when-2.yml
failed_when 조건식 :
command_result.stdout 변수에 “Please…”라는 문자열이 있으면 작업을 실패(fail)로 처리하겠다는 의미입니다.
--- - hosts: tnode1 tasks: - name: Run user add script ansible.builtin.shell: /home/ubuntu/adduser-script.sh register: command_result failed_when: "'Please input user id and password' in command_result.stdout" - name: Print msg ansible.builtin.debug: msg: "{{ command_result.stdout }}"
4) 실행
실행하면 첫 번째 플레이북은 정상 동작하는 것으로 보입니다.
스크립트가 0이 아닌 종료 코드를 반환하지 않았기 때문에, Ansible은 이 태스크를 성공적으로 완료한 것으로 간주합니다.
그 결과, 두 번째 태스크인 Print msg가 실행되어 스크립트의 출력 내용을 표시합니다.ansible -m shell -a "tail -n 3 /etc/passwd" tnode1
위의 커맨드를 통해서 유저가 추가 됐는지 확인합니다.
두 번째 플레이북을 실행하면, 다음과 같이 나옵니다.
조건 "'Please input user id and password' in command_result.stdout"는 스크립트의 출력 "Please input user id and password"라는 문자열이 포함되어 있으면 태스크가 실패한 것으로 간주하도록 설정합니다.
스크립트의 실행 결과에서 해당 문자열이 발견되었기 때문에, Ansible은 이 태스크를 실패한 것으로 간주합니다.
따라서 Print msg 태스크는 실행되지 않고, 플레이북의 실행이 중단됩니다.감사합니다.
728x90반응형'IT > Ansible' 카테고리의 다른 글
[Ansible 101] 2주차 도전과제 (0) 2024.01.21 [Ansible 101] 앤서블 블록 및 오류처리 (0) 2024.01.21 [Ansible 101] 조건문 (0) 2024.01.21 [Ansible 101] 반복문 (2) 2024.01.21 [Ansible 101 스터디] 앤서블 1주차 기본 실습 (변수) (6) 2024.01.14 - 앤서블은 플레이 시 각 작업의 반환 코드를 평가하여 작업의 성공 여부를 판단합니다.