Ansible: Playbook 기본 구조

Playbook의 기본 구조에 대해 함께 알아보는 시간을 가져보도록 하겠습니다.

Ansible Playbook 개요

Ansible은 IT 인프라의 설정, 애플리케이션 배포, 일련의 작업 조정 등을 자동화하는 데 사용되는 도구입니다. Ansible의 핵심 요소 중 하나는 Playbook으로, 이는 Ansible을 사용하여 수행할 작업의 시나리오를 정의하는 파일입니다. Playbook은 특정 서버에서 수행해야 할 작업의 목록을 제공하며, YAML(YAML Ain’t Markup Language) 형식으로 작성됩니다.

YAML에 대한 내용은 YAML 소개 및 기본 문법 게시글을 참고해주세요.

Playbook 기본 구조

Playbook의 기본 구조는 상당히 간결합니다. Playbook은 일련의 ‘Play’로 구성되며, 각 Play는 ‘hosts’와 ‘tasks’라는 두 가지 주요 섹션으로 구성됩니다. ‘hosts’ 섹션에서는 플레이가 적용될 호스트를 지정하고, ‘tasks’ 섹션에서는 수행할 작업을 정의합니다.

--- # Play 섹션
- name: Example Playbook
  hosts: server
  vars:
    http_port: 80
    max_clients: 200
  remote_user: root

  tasks: # Task 섹션
  - name: Ensure Apache is installed
    yum:
      name: httpd
      state: present

  - name: Ensure Apache is running
    service:
      name: httpd
      state: started

  handlers:
  - name: Restart Apache
    service:
      name: httpd
      state: restarted
    listen: "restart apache"

  - name: Change Apache configuration
    template:
      src: /srv/httpd.j2
      dest: /etc/httpd.conf
    notify: "restart apache"
...
 

Task와 Module

각 Task는 Ansible의 기능을 수행하는 기본 단위입니다. 각 Task는 Ansible 모듈을 사용하여 원하는 작업을 수행하도록 정의됩니다. 예를 들어, ‘file’ 모듈을 사용하여 파일을 생성하거나 삭제하거나, ‘service’ 모듈을 사용하여 서비스를 시작하거나 중지할 수 있습니다.

---
- name: Example Playbook
  hosts: servers
  tasks:
  - name: Ensure Apache is installed
    yum:
      name: httpd
      state: present

  - name: Ensure Apache is running
    service:
      name: httpd
      state: started
...

이 Playbook은 ‘servers’ 그룹에 속한 호스트에 대해 작업을 수행합니다. ‘tasks’ 섹션에서는 두 개의 task를 정의합니다.

첫 번째 task는 ‘yum’ module을 사용하여 Apache가 설치되어 있는지 확인합니다. ‘name’에는 패키지 이름인 ‘httpd’를, ‘state’에는 원하는 상태인 ‘present’를 지정하여, 이 패키지가 설치되어 있어야 함을 나타냅니다.

두 번째 task는 ‘service’ module을 사용하여 Apache 서비스가 실행 중인지 확인합니다. ‘name’에는 서비스 이름인 ‘httpd’를, ‘state’에는 원하는 상태인 ‘started’를 지정하여, 이 서비스가 실행 중이어야 함을 나타냅니다.

이렇게 각 task는 특정 module을 사용하여 원하는 작업을 정의하며, Playbook은 이 task들을 순서대로 실행합니다.

Playbook 핸들러(Handlers)

Playbook에서는 ‘handler’라는 특별한 종류의 task를 정의할 수 있습니다. Handler는 특정 task가 변경될 때만 실행되는 task로, 서비스를 재시작하거나 설정을 새로 고침하는 등의 작업에 주로 사용됩니다.

---
- name: Example Playbook
  hosts: servers
  tasks:
  - name: Change Apache configuration
    template:
      src: /srv/httpd.j2
      dest: /etc/httpd.conf
    notify: "restart apache"

  handlers:
  - name: Restart Apache
    service:
      name: httpd
      state: restarted
...

이 Playbook은 ‘servers’ 그룹에 속한 호스트에 대해 작업을 수행합니다. ‘tasks’ 섹션에서는 Apache의 설정 파일을 변경하는 task를 정의합니다. 이 task는 ‘template’ module을 사용하여, ‘/srv/httpd.j2’라는 Jinja2 템플릿을 ‘/etc/httpd.conf’로 복사합니다.

이 작업 후에는 ‘notify’ 키워드를 사용하여 “restart apache”라는 이름의 핸들러를 호출합니다.

핸들러는 ‘handlers’ 섹션에서 정의합니다. 이 예에서는, “Restart Apache”라는 이름의 핸들러가 ‘service’ module을 사용하여 Apache 서비스를 재시작합니다. ‘name’에는 서비스 이름인 ‘httpd’를, ‘state’에는 원하는 상태인 ‘restarted’를 지정합니다.

이렇게 핸들러는 특정 task에서 변경 사항이 발생했을 때만 실행되며, 이를 통해 서비스의 재시작 등의 추가 작업을 효율적으로 관리할 수 있습니다.

Playbook 변수(Variables)

Playbook에서는 변수를 사용하여 작업을 동적으로 구성할 수 있습니다. 변수는 Playbook의 여러 부분에서 재사용할 수 있는 값을 정의하는 데 사용되며, 이를 통해 Playbook의 유연성과 재사용성을 높일 수 있습니다.

  1. ---- name: Example Playbook  hosts: servers  vars:  http_port: 80  max_clients: 200   tasks:  - name: Change Apache configuration  template:  src: /srv/httpd.j2  dest: /etc/httpd.conf  vars:  http_port: "{{ http_port }}"  max_clients: "{{ max_clients }}"...

이 Playbook은 ‘servers’ 그룹에 속한 호스트에 대해 작업을 수행합니다. ‘vars’ 섹션에서는 ‘http_port’와 ‘max_clients’라는 두 개의 변수를 정의합니다.

그 다음에는 ‘tasks’ 섹션에서 Apache의 설정 파일을 변경하는 task를 정의합니다. 이 task는 ‘template’ module을 사용하여, ‘/srv/httpd.j2’라는 Jinja2 템플릿을 ‘/etc/httpd.conf’로 복사합니다.

이때, ‘vars’ 키워드를 사용하여 task에서 사용할 변수를 지정합니다. ‘{{ http_port }}’와 ‘{{ max_clients }}’는 각각 ‘http_port’와 ‘max_clients’ 변수의 값을 참조합니다.

이렇게 Playbook의 변수는 Playbook의 여러 부분에서 재사용할 수 있으며, 이를 통해 Playbook의 유연성을 높일 수 있습니다.

Playbook 팩트(Facts)

Ansible은 ‘Facts’라는 시스템 정보를 수집하여 제공합니다. Facts는 원격 시스템에 대한 상세 정보를 제공하며, 이를 Playbook에서 변수로 사용할 수 있습니다. 예를 들어, 원격 시스템의 운영 체제나 IP 주소 등을 알아낼 수 있습니다.

  1. ---
  2. - name: Example Playbook
  3.   hosts: servers
  4.  
  5.   tasks:
  6.   - name: Gather facts
  7.   setup:
  8.   - name: Display facts
  9.   debug:
  10.   msg: "Hostname is {{ ansible_hostname }} and OS is {{ ansible_distribution }}"
  11. ...

이 Playbook은 ‘servers’ 그룹에 속한 호스트에 대해 작업을 수행합니다. ‘tasks’ 섹션에서는 두 개의 task를 정의합니다.

첫 번째 task는 ‘setup’ module을 사용하여 호스트에 대한 facts를 수집합니다. 이 module은 호스트에 대한 다양한 정보를 수집하고, 이 정보를 facts로 반환합니다.

두 번째 task는 ‘debug’ module을 사용하여 수집된 facts를 출력합니다. ‘msg’에는 출력할 메시지를 지정하며, 이 메시지에는 ‘{{ ansible_hostname }}’와 ‘{{ ansible_distribution }}’라는 두 개의 facts를 포함합니다. 이들은 각각 호스트의 이름과 운영체제를 나타냅니다.

이렇게 facts는 호스트에 대한 실시간 정보를 제공하며, 이를 통해 Playbook의 동작을 동적으로 제어할 수 있습니다.

Playbook 조건문과 반복문

Ansible Playbook에서는 조건문과 반복문을 사용하여 작업의 실행을 제어할 수 있습니다. ‘when’ 키워드를 사용하여 특정 조건에서만 작업을 실행하도록 할 수 있으며, ‘loop’ 키워드를 사용하여 작업을 반복할 수 있습니다.

  1. ---
  2. - name: Example Playbook
  3.   hosts: servers
  4.   vars:
  5.   packages:
  6. - httpd
  7. - mysql
  8.  
  9.   tasks:
  10.   - name: Install packages
  11.   yum:
  12.   name: "{{ item }}"
  13.   state: present
  14.   with_items: "{{ packages }}"
  15.  
  16.   - name: Start service if package is httpd
  17.   service:
  18.   name: "{{ item }}"
  19.   state: started
  20.   when: item == 'httpd'
  21.   with_items: "{{ packages }}"
  22. ...

이 Playbook은 ‘servers’ 그룹에 속한 호스트에 대해 작업을 수행합니다. ‘vars’ 섹션에서는 ‘packages’라는 변수를 정의하고, 이 변수에는 설치하려는 패키지의 목록을 지정합니다.

‘tasks’ 섹션에서는 먼저 ‘yum’ module을 사용하여 패키지를 설치하는 task를 정의합니다. ‘name’에는 설치하려는 패키지의 이름을, ‘state’에는 원하는 상태인 ‘present’를 지정합니다. 이때, ‘with_items’ 키워드를 사용하여 ‘packages’ 변수에 있는 각 패키지에 대해 task를 반복합니다.

그 다음에는 ‘service’ module을 사용하여 서비스를 시작하는 task를 정의합니다. ‘name’에는 시작하려는 서비스의 이름을, ‘state’에는 원하는 상태인 ‘started’를 지정합니다. 이때, ‘when’ 키워드를 사용하여 조건문을 추가합니다. 이 조건문은 ‘item’이 ‘httpd’일 때만 task를 실행하도록 합니다. 마찬가지로, ‘with_items’ 키워드를 사용하여 ‘packages’ 변수에 있는 각 패키지에 대해 task를 반복합니다.

이렇게 조건문과 반복문을 사용하면, Playbook의 동작을 유연하게 제어할 수 있습니다.

Playbook 실행

Playbook은 Ansible 명령행 도구를 사용하여 실행할 수 있습니다. ‘ansible-playbook’ 명령을 사용하여 Playbook 파일을 지정하고 실행하면, Ansible은 Playbook에 정의된 Play와 Task를 순서대로 실행합니다.

먼저, 작성한 Playbook 파일이 있는 디렉토리로 이동합니다. 이 예에서는 ‘example.yml’이라는 이름의 Playbook 파일을 사용한다고 가정하겠습니다.

1
cd /path/to/your/directory
cs

그 다음에는 ‘ansible-playbook’ 명령을 사용하여 Playbook을 실행합니다. 이때, ‘-i’ 옵션을 사용하여 인벤토리 파일을 지정할 수 있습니다. 인벤토리 파일에는 Playbook을 실행할 호스트의 목록이 포함되어 있습니다.

1
$ ansibleplaybook i hosts.ini example.yml
cs

이 명령을 실행하면, Ansible는 ‘example.yml’ Playbook을 ‘hosts.ini’ 인벤토리 파일에 지정된 호스트에 대해 실행합니다. Playbook의 실행 과정은 터미널에 출력되며, 각 task의 실행 결과와 함께 전체 실행 결과도 표시됩니다.

마무리

Ansible의 Playbook은 IT 작업을 자동화하는 강력한 도구입니다. Playbook의 간단하고 명확한 구조는 IT 전문가가 쉽게 작업을 정의하고 실행할 수 있게 해줍니다. 이제 Ansible Playbook의 기본 구조와 작동 방식에 대해 깊이 있게 이해하셨을 것입니다.

참고 문헌

https://www.redhat.com/ko/topics/automation/what-is-an-ansible-playbook

https://github.com/na3150/Cloud_boot_camp/blob/main/Ansible/%5BAnsible%5D%20%EB%B0%98%EB%B3%B5%EB%AC%B8(loop)%EA%B3%BC%20%EC%A1%B0%EA%B1%B4%EB%AC%B8(when).md

https://watch-n-learn.tistory.com/80