Ssoon

[ Part-2 ] 앤서블 기본 사용법 - 핸들러 및 작업 실패 처리 본문

Ansible 101 Study

[ Part-2 ] 앤서블 기본 사용법 - 핸들러 및 작업 실패 처리

구구달스 2024. 1. 20. 16:28
CloudNet@ 가시다님이 진행하는 Ansible 101 Study
"앤서블로 시작하는 인프라 자동화" (한빛미디어) 로 진행

 핸들러 및 작업 실패 처리

  • ansible playbook 은 여러 번 실행해도 결과는 항상 동일
  • 해당 호스트를 원하는 상태로 만드는 데 필요한 경우만 변경
  • 핸들러
    • 다른 작업에서 트리거한 알림에 응답하는 작업
    • 해당 호스트에서 작업이 변경될 때만 핸들러에 통지

💠 앤서블 핸들러

  • ansible 에서 핸들러 사용  ▶ notify 문을 사용  ▶ 명시적 호출된 경우
  • 각각의 고유한 이름을 사용하여 핸들러 정의 

  • rsyslog 서비스 재시작 하는 태스크가 실행 ▶ notify 키워드로 print msg 핸들러 호출
- hosts: tnode2-ubuntu.exp.com

  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"
  • ansible-playbook 실행

💠 작업 실패 무시

  • 플레이 시 각 작업의 반환 코드를 평가 작업의 성공 여부 판단
  • 작업 실패 이 후의 모든 작업 skip
  • ignore_errors
    1. 작업이 실패해도 계속 실행

  • 에러를 발생하기 위해 CentOS 에는 없는 apache2 패키지 설치 작업 추가
  • ignore_errors: yes 구문 입력
- hosts: tnode1-centos.exp.com

  tasks:
    - name: install apache2
      ansible.builtin.dnf:
        name: apache2
        state: latest
      ignore_errors: yes

    - name: print msg
      ansible.builtin.debug:
        msg: "before task is ignored"
  • ansible-playbook 실행
  • ignore 메시지와 함께 무시되고 다음 태스크 실행

💠 작업 실패 후 핸들러 실행

  • 작업이 실패 ▶ 해당 호스트에서 플레이 중단 ▶ 이전 작업에서 알림을 받은 모든 핸들러 실행 안됨
  • force_handler: yes 키워드
    • 이후 작업이 실패하여 플레이 중단되어도 알림을 받은 핸들러 호출
- hosts: tnode2-ubuntu.exp.com
  force_handlers: yes

  tasks:
    - name: restart rsyslog
      ansible.builtin.service:
        name: "rsyslog"
        state: restarted
      notify:
        - print msg
    - name: install apache2
      ansible.builtin.dnf:
        name: "apache2"
        state: latest

  handlers:
    - name: print msg
      ansible.builtin.debug:
        msg: "rsyslog is restarted"
  • ansible-playbook 실행
  • restart rsyslog 태스크 수행 install apache2 에러 print msg 핸들러 실행

💠 작업 실패 조건 지정

  • 쉘 스크립트 실행 결과가 실패 또는 에러 앤서블에서는 작업 성공으로 간주
  • failed_when
    • 작업이 실패 했음을 나타내는 조건 지정
  • 사용자 추가 쉘 스크립트 tnode1 의 root 폴더에 생성 adduser-script.sh
#!/bin/bash

# 사용자 계정 및 패스워드가 입력되었는지 확인
if [[ -n $1 ]] && [[ -n $2 ]]
then

  UserList=($1)
  Password=($2)

  # for문을 이용하여 사용자 계정 생성
  for (( i=0; i < ${#UserList[@]}; i++ ))
  do
    # if문을 사용하여 사용자 계정이 있는지 확인
    if [[ $(cat /etc/passwd | grep ${UserList[$i]} | wc -l) == 0 ]]
    then
      # 사용자 생성 및 패스워드 설정
      useradd ${UserList[$i]}
      echo ${Password[$i]} | passwd ${UserList[$i]} --stdin
    else
      # 사용자가 있다고 메시지를 보여줌.
      echo "this user ${UserList[$i]} is existing."
    fi
  done

else
  # 사용자 계정과 패스워드를 입력하라는 메시지를 보여줌.
  echo -e 'Please input user id and password.\nUsage: adduser-script.sh "user01 user02" "pw01 pw02"'
fi
  • ansible_builtin.shell 모듈 adduser-script.sh 실행
  • failed_when 구문
    • command_result.stdout 변수에 "please input user id and passsword" 문자열이 있으면 작업을 실패로 처리
- hosts: tnode1-centos.exp.com

  tasks:
    - name: run user add script
      ansible.builtin.shell: /root/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: "this is next task"
  • ansible-playbook 실행
  • 플레이북에서 failed_when 구문을 사용하지 않았다면 태스트가 실패했는지 모른 채 다음 태스크 실행

  • failed_when 구문 삭제 ignore_errors: yes 구문 추가
  • ansible.builtin.fail: 모듈과 when 구문 이용
    • Please input user id and password 문자열이 :있으면 메시지 출력하고 실패 처리 태스크 추가
- hosts: tnode1-centos.exp.com

  tasks:
    - name: run user add script
      ansible.builtin.shell: /root/adduser-script.sh
      register: command_result
      ignore_errors: yes

    - name: report script failure
      ansible.builtin.fail:
        msg: "{{ command_result.stdout }}"
      when: "'Please input user id and password' in command_result.stdout"
  • ansible-playbook 실행
  • run user add script 태스크는 정상 실행 report script failure 태스크는 실패 플레이 중단

💠 앤서블 블록 및  오류처리

  • block
    1. 오류를 제어하는 문법
    2. 작업을 논리적으로 그룹화하는 절
    3. 작업 실행 방법을 제어하는 데 사용
    4. rescue 문과 alwayys 문을 함께하여 오류 처리
block 실행할 기본 작업 정의
rescue block 절에 정의된 작업이 실패하는 경우 실행할 작업 정의
always block 및 rescue 절에 정의된 작업 성공/실패 관계없이 항상 실행되는 작업 정의

  • block
    • ansible.builtin.find: 모듈   /var/log/daily_log 디렉토리 검색   없으면 warning 발생   다음 태스크로
    • failed_when 구문 result.msg 변수에 Not all paths 메시지 발견되면 실패 처리
  • rescue
    • 디렉터리가 없으면 디렉터리를 생성
  • always
    • 로그 파일 생성
- hosts: tnode2-ubuntu.exp.com
  vars:
    logdir: /var/log/daily_log
    logfile: todays.log

  tasks:
    - name: configure log env
      block:
        - name: find directory
          ansible.builtin.find:
            path: "{{ logdir }}"
          register: result
          failed_when: "'Not all paths' in result.msg"

      rescue:
        - name: make directory when not found directory
          ansible.builtin.file:
            path: "{{ logdir }}"
            state: directory
            mode: '0755'

      always:
        - name: create file
          ansible.builtin.file:
            path: "{{ logdir }}/{{ logfile }}"
            state: touch
            mode: '0644'
  • ansible-playbook 실행
  • find directory 태스크
    • 디렉터리을 찾지 못해 오류 발생
  • make directory when not found directory 태스크
    • 디렉터리 생성
  • create file 태스크
    • 파일 생성 

  • tnode2-ubuntu 노드에서 확인

  • ansible-playbook 실행
  • rescue 구문에 make directory when not found directory 태스크 는 실행하지 않음

Comments