플레이북을 작성하다 보면 이전에 사용한 코드를 재활용할 여지가 많다. 하지만 플레이북 자체의 내용이 길고 복잡하다면 일일히 수정하기 어려워진다. 앤서블에서는 표준화된 디렉토리 구조로 컨텐츠들을 모듈화하여 코드 재사용 및 협업을 편리하게 할 수 있도록 Ansible role 이라는 기능을 제공한다. 또 Ansible galaxy를 통하여 작성한 롤을 공유할 수 있다.
앤서블 롤의 구조
앤서블 롤은 아래와 같은 표준화된 디렉토리 구조를 가진다. 최상위 디렉토리인 'role'은 롤 자체의 이름을 의미하며, 하위 디렉토리들은 롤에서 목적에 따라 정의된 역할을 수행한다. 각 files와 templates을 제외한 각 하위토리 안에는 main.yml 파일이 존재한다. 최종적으로 롤이 실행될 때, main.yml 파일의 내용을 참조하여 실행된다.
── role
├── defaults
├── files
├── handlers
├── meta
├── tasks
├── templates
├── tests
└── vars
Directory | Function |
defaults | 롤이 사용될 때 덮어쓸 수 있는 변수 기본 값이 포함된다. |
files | 롤 작업에서 참조할 정적 파일이 위치한다. |
handlers | 롤의 핸들러 작업이 정의된다. |
meta | 롤에 대한 메타데이터가 들어있다. |
tasks | 롤의 작업이 정의된다. |
templates | 롤 작업에서 참조할 동적 파일인 Jinja2 템플릿이 위치한다. |
tests | 롤을 플레이할 때 테스트 할 인벤토리와 플레이북이 포함된다. |
vars | 롤에서 사용할 변수 값을 정의한다. |
ansible-galaxy role init {{ role-name }} 명령어를 통하여 기본 롤 디렉토리 구조를 생성할 수 있다. 생성 후, 필요없는 하위 디렉토리는 삭제해도 무방하다.
롤을 이용한 플레이북 개발
책의 예제에 나와있는 심플한 롤 플레이북을 작성해보도록 한다.
Procedure
- 'my-role'이라는 role을 생성
- 롤 호출 시 현재 호스트의 OS버전이 지원 목록에 포함되는지 유효성 체크
- httpd 관련 패키지 설치
- 설치가 끝나면 files 디렉토리 안에 준비해둔 'index.html' 파일을, 제어 노드의 특정 경로에 복사
- httpd restart
[01] tasks/main.yml
[root@Ansible-Controller my-role]# cat tasks/main.yml
---
# tasks file for my-role
- name: install service {{ service_title }}
ansible.builtin.dnf:
name: "{{ item }}"
state: latest
loop: "{{ httpd_packages }}"
when: ansible_facts.distribution in supported_distros
- name: copy html file
ansible.builtin.copy:
src: "{{ src_file_path }}"
dest: "{{ dest_file_path }}"
notify:
- restart service
dnf 모듈을 이용하여 httpd 관련 패키지를 설치한다. 관련 변수들은 후에 vars 파일에서 선언해주기로하고, 변수에 포함되는 모든 패키지들이 설치되도록 loop문을 돌려준다. 이 때 팩트 변수에서 수집한 os 버전이 'supported_distros'라는 변수에 포함될 때만 수행하도록 when문을 사용하여 조건문을 달아준다. 설치가 끝나면 files 디렉토리에 위치한 파일을 제어 노드로 복사한다. 복사가 완료되면 notify문을 통해 restart service라는 핸들러를 호출한다.
[02] handlers/main.yml
[root@Ansible-Controller my-role]# cat handlers/main.yml
---
# handlers file for my-role
- name: restart service
ansible.builtin.service:
name: "{{ service_name }}"
state: restarted
restart service라는 핸들러가 호출되면 service 모듈을 이용하여 제어노드의 service 유닛을 재시작한다.
[03] files/index.html
[root@Ansible-Controller my-role]# cat files/index.html
Hello Ansible World!
제어노드로 복사될 index.html 파일
[04] defaults/main.yml
[root@Ansible-Controller my-role]# cat defaults/main.yml
---
# defaults file for my-role
service_title: "Apache Web Server"
외부로부터 변경될 수 있는 가변변수이다.
[05] vars/main.yml
[root@Ansible-Controller my-role]# cat vars/main.yml
---
# vars file for my-role
service_name: httpd
src_file_path: ../files/index.html
dest_file_path: /var/www/html
httpd_packages:
- httpd-tools
- httpd-filesystem
- httpd
supported_distros:
- CentOS
- Redhat
- Rocky
tasks와 handlers의 main.yml에서 사용할 변수들을 선언한다.
[06] 플레이북에 롤 추가하기
롤을 실행하기 위해서는 ansible-playbook my-role과 같이 기존에 플레이북을 실행한 방식으로 실행할 수 없다. 따라서 롤을 실행하기 위한 플레이북을 따로 작성해주어야 한다.
[root@Ansible-Controller roles]# cat role-playing.yml
---
- hosts: localhost
tasks:
- name: Print playbook execution
ansible.builtin.debug:
msg: "role-play"
- name: Install Service by role
ansible.builtin.import_role:
name: my-role
import_role 모듈을 이용하여 실행할 role의 이름을 선언해준다.
[07] Execution
웹 브라우저를 통해 해당 호스트에 접근하여 Ansible role을 이용한 http와 index.html의 설정이 잘 적용된 것을 확인할 수 있다.
'Engineering > Ansible' 카테고리의 다른 글
[Ansible] 9. 핸들러 및 작업 실패 처리 (2) | 2024.10.02 |
---|---|
[Ansible] 8. 반복문과 조건문을 이용한 제어문 구현 (0) | 2024.09.04 |
[Ansible] 7. Ansible Facts 활용 (0) | 2024.09.02 |
[Ansible] 6. Ansible Vault (0) | 2024.08.29 |
[Ansible] 5. 변수 (1) | 2024.08.28 |