본문 바로가기

리눅스

Ansible playbook에서 block, rescue, loop, always를 사용하는 방법(ansible-playbook)

728x90

Ansible playbook에서 block, rescue, loop, always를 사용하는 방법(ansible-playbook)

블록(Block)은 작업의 논리적 그룹을 만듭니다. 블록은 또한 많은 프로그래밍 언어의 예외 처리와 유사하게 작업 오류를 처리하는 방법을 제공합니다.

Ansible에서 block, rescue, loop, always를 사용하는 방법은 주로 예외 처리와 루프에서 유용합니다

Ansible 플레이북 작성

  • block, rescue, loop, always 사용 예시
vim example.yml
---
- name: 플레이북 예시
  hosts: all
  gather_facts: false
  become: true

  tasks:
    - name: Outer Block
      block:
        - name: Loop Block - Task 1
          debug:
            msg: "Loop Item: {{ item }}"
          loop:
            - 1
            - 2
            - 3
        - name: Loop Block - Task 2
          debug:
            msg: "Another Task inside Loop"
      rescue:
        - name: Rescue Block
          debug:
            msg: "This runs on rescue"
      always:
        - name: Always Block
          debug:
            msg: "This always runs"

이 Ansible 플레이북은 block, rescue, loop, 그리고 always를 사용하여 작업의 성공 또는 실패에 따라 흐름을 제어하는 방법을 보여주는 예시입니다.

 

각 부분을 자세히 살펴보겠습니다.

 

Outer Block (외부 블록)

  • 플레이북은 모든 호스트를 대상으로 하며 (hosts: all), 자동으로 팩트 수집을 비활성화하는 옵션 (gather_facts: false)과 슈퍼유저로 권한 상승을 하는 옵션 (become: true)을 가지고 있습니다.

Block (블록)

  • block 키워드는 여러 작업을 하나로 묶는 역할을 합니다. 이는 그 안의 작업들을 담는 컨테이너 역할을 합니다.
  • 블록 내부에는 두 개의 작업(Loop Block - Task 1Loop Block - Task 2)이 있습니다.
  • Loop Block - Task 1loop 키워드를 사용하여 리스트(- 1, 2, 3)를 반복하며 각 항목에 대한 디버그 메시지를 출력합니다.
  • Loop Block - Task 2는 같은 블록 내의 또 다른 작업입니다.

Rescue (레스큐)

  • rescue 키워드는 블록 내에서 어떤 작업이라도 실패하면 실행되어야 하는 작업들을 정의합니다. 여기서는 Rescue Block 작업입니다.

Always (얼웨이즈)

  • always 키워드는 블록 내의 작업들이 성공하든 실패하든 상관없이 항상 실행되어야 하는 작업들을 정의합니다. 여기서는 Always Block 작업입니다.

Ansible 플레이북 실행

ansible-playbook -i inventory/hosts.ini ansible_learn/example.yml --limit localhost
$ ansible-playbook -i inventory/hosts.ini ansible_learn/example.yml --limit localhost

PLAY [플레이북 예시] **************************************************************************************************

TASK [Loop Block - Task 1] ********************************************************************************************
ok: [localhost] => (item=1) => {
    "msg": "Loop Item: 1"
}
ok: [localhost] => (item=2) => {
    "msg": "Loop Item: 2"
}
ok: [localhost] => (item=3) => {
    "msg": "Loop Item: 3"
}

TASK [Loop Block - Task 2] ********************************************************************************************
ok: [localhost] => {
    "msg": "Another Task inside Loop"
}

TASK [Always Block] ***************************************************************************************************
ok: [localhost] => {
    "msg": "This always runs"
}

PLAY RECAP ************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

요약하면

 

  • 블록 내의 모든 작업이 성공하면 rescue 블록은 건너뛰어지고, always 블록이 실행됩니다.
  • 블록 내의 어떤 작업이라도 실패하면 rescue 블록이 실행되고, 그 후에 always 블록이 실행됩니다.

이러한 구조를 사용하면 작업을 논리적으로 구성하여 성공, 실패 및 어떤 경우에도 실행되어야 하는 작업에 대한 구체적인 동작을 제공할 수 있습니다.

728x90

실제 서버에 적용 가능한 예시

Nginx를 설치하고 구성하는 작업을 수행하는 플레이북을 만들어 보겠습니다. 플레이북은 패키지 설치, 설정 파일 배포, 서비스 시작을 다룹니다.

vim install_nginx.yml
---
- name: Nginx 설치 및 구성
  hosts: all
  become: true

  tasks:
    - name: Nginx 설치
      block:
        - name: Update apt cache (for Ubuntu)
          apt:
            update_cache: yes
          when: ansible_os_family == 'Debian'

        - name: Nginx 설치
          package:
            name: nginx
            state: present
      rescue:
        - name: Nginx 설치 중 실패 처리(Handle failure)
          debug:
            msg: "Nginx를 설치하지 못했습니다. 로그를 확인해 보세요."

    - name: Nginx 구성 배포
      block:
        - name: Nginx 구성 파일 복사
          template:
            src: nginx.conf.j2
            dest: /etc/nginx/nginx.conf
          notify:
            - Restart Nginx
      rescue:
        - name: 구성 배포 중 실패 처리(Handle failure)
          debug:
            msg: "Nginx 구성을 배포하지 못했습니다. 변경 사항을 롤백합니다."

    - name: Nginx 서비스 시작
      block:
        - name: Start Nginx
          service:
            name: nginx
            state: started
      rescue:
        - name: Nginx 서비스 시작 중 장애 처리
          debug:
            msg: "Nginx 서비스를 시작하지 못했습니다. 수동 개입이 필요합니다."

  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

 

이 예시에서 사용한 주요 구성 요소는 다음과 같습니다.

 

  • block : 패키지 설치, 설정 파일 배포, 서비스 시작과 같이 여러 작업을 묶어주는 역할을 합니다.
  • rescue : block 내에서 어떤 작업이라도 실패하면 실행되어야 하는 작업을 정의합니다. 실패 시 어떤 부분이 문제인지 확인할 수 있도록 디버깅 메시지를 출력하도록 했습니다.
  • loop : 여러 서버에 동일한 작업을 반복 적용할 때 사용됩니다. 이 예시에서는 사용되지 않았지만, 여러 서버를 대상으로 하는 작업에서 유용하게 사용될 수 있습니다.
  • always : block 내의 작업이 성공하든 실패하든 관계없이 항상 실행되어야 하는 작업을 정의합니다. 여기서는 Nginx 서비스를 재시작하는 핸들러를 사용했습니다.

이러한 방식으로 플레이북을 작성하면 복잡한 배포 시나리오에서도 성공과 실패에 따라 적절한 조치를 취할 수 있습니다.

 

참고URL

- Ansible Documentation : playbook block

 

728x90