Cloud Engineering/Ansible

[Ansible] handler (핸들러) / block (블록) / delegate (위임)

minjiwoo 2023. 3. 6. 18:02
728x90

Handler (핸들러)

작업을 실행 후 작업에 대한 변경이 있으며, notify 를 설정한 경우에만 핸들러가 실행된다. 

핸들러는 notify: 로 설정한다. Ansible 공식 문서의 예제는 다음과 같다. 

---
- name: Verify apache installation
  hosts: webservers
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root
  tasks:
    - name: Ensure apache is at the latest version
      ansible.builtin.yum:
        name: httpd
        state: latest

    - name: Write the apache config file
      ansible.builtin.template:
        src: /srv/httpd.j2
        dest: /etc/httpd.conf
      notify:
      - Restart apache

    - name: Ensure apache is running
      ansible.builtin.service:
        name: httpd
        state: started

  handlers:
    - name: Restart apache
      ansible.builtin.service:
        name: httpd
        state: restarted

위와 같이 핸들러는 일반적인 작업을 수행하는데 사용되는 것이 아니라, 부가적으로 실행되어야 하는 경우에만 실행시킨다. 대표적인 예로, 웹서버의 설정파일을 바꾼 후에 apache 서비스를 재실행 시켜야하는데, 이런 경우 handler 를 사용하기에 적절하다.

핸들러는 모든 tasks들이 실행되고 나서 notify 에 의해 실행되며, notify 받은 순서에 의해 실행되는 것이 아니라 핸들러가 정의된 위에서 아래로 순차적으로 실행된다. 

또한 알림을 받은 핸들러만 실행되며, 동일한 이름의 핸들러가 있는 경우 이후에 정의한 핸들러만 실행된다.  

참고문서:

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

 

Handlers: running operations on change — Ansible Documentation

Sometimes you want a task to run only when a change is made on a machine. For example, you may want to restart a service if a task updates the configuration of that service, but not if the configuration is unchanged. Ansible uses handlers to address this u

docs.ansible.com

Block 

Block 으로 여러개의 작업들을 하나의 논리적인 그룹으로 묶을 수 있다. 

- hosts: ansi-node1
  vars:
    var1: "/etc/hosts"
    var2: "/etc"
    var3: "/"
    var4: "/notdir"
  tasks:
  - name: block checking path
    block:
    - debug: 
        msg: "This is file"
      when: var1 is file
    - debug: 
        msg: "This is dir"
      when: var2 is directory
    - debug: 
        msg: "This is mounted"
      when: var3 is mount
  - name: block checking existence
    block:
    - debug:
        msg: "exists"
      when: var4 is exists
    - debug: 
        msg: "not exists"
      when: var4 is not exists

하나의 Block 으로 묶이게 되면  Block 내의 작업들 전체에 동일한 조건문이나 ignore_errors 같은 설정을 걸어줄 수 있다. 

- hosts: ansi-node1
  vars:            
    path1: "/notdir"
  tasks:           
  - name: block 1  
    block:         
    - command: ls "{{ path1 }}"
    rescue:        
    - name: rescue block   
      debug:       
        msg: "block failed!"
    always:        
    - name: always 
      debug:       
        msg: "block ir failed or success!"

Block 내의 작업이 하나라도 실패하게 되면 rescue 를 실행할 수 있다. 반면, always는 실패 유무와 관련없이 항상 수행하는 작업이다. 

결과적으로, /notdir 는 존재하지 않는 디렉토리여서 ls 명령은 실패한다. 따라서 rescue 에 의해 block failed! 메세지가 출력되는 것이다. 

delegate (위임)

플레이북 파일에서 작업들의 일부를 다른 호스트에게 위임할 수 있다. delegate_to: 위임할 대상 이라고 표기한다. 

- hosts: ansi-node1        
  vars:                    
    dict1:                 
      apple: 5000          
      banana: 2000         
      grape: 1000          
  tasks:                   
  - debug:                 
      msg: "{{ item.key }} {{ item.value }}"     
    loop: "{{ query('dict', dict1) | default({}) }}"
    when: item.value > 1000 and item.value < 5000
    delegate_to: ansi-node2

ansi-node1 의 작업이었던 것을 ansi-node2에게 위임(delegate) 하는 예시이다. 

 

 

728x90