롤과 콘텐츠 컬렉션을 활용한 플레이북 구현 - 롤 구조 소개 및 사용법

728x90
반응형

출처 : 앤서블로 시작하는 인프라 자동화

 

  • 앤서블은 내가 만든 플레이북을 다른 사람들과 공유하거나 다른 사람들이 만든 플레이북을 활용할 수 있다.
  • 앤서블의 롤은 플레이북 내용을 기능 단위로 나누어 공통 부품으로 관리 및 재사용하기 위한 구조이다.
  • 앤서블의 롤을 통해 구현하고, 앤서블 갤럭시를 통해 공유할 수 있으며, 다른 사람들이 만들어놓은 롤을 검색해서 가져올 수 있다.
  • 이번 장에서는 롤, 앤서블 갤럭시, 콘텐츠 컬렉션에 대해서 학습한다.

 

롤 구조 소개 및 사용법

  • 앤서블의 롤을 사용하면 일반적인 앤서블 코드를 더 쉽게 재사용할 수 있다.
  • 인프라를 프로비저닝하거나, 애플리케이션을 배포하는 데 필요한 모든 작업, 변수, 파일, 템플릿, 기타 리소스를 표준화된 디렉토리 구조로 패키이하는 데 도움이 된다.
  • 디렉토리를 복사하여 롤을 다른 프로젝트로 복사한 다음 플레이 내에서 호출할 수도 있다.
  • 앤서블 롤의 장점
    1. 콘텐츠를 그룹화하여 코드를 다른 사용자와 쉽게 공유할 수 있다.
    2. 웹 서버, 데이터베이스 서버, 깃 리포지터리와 같은 시스템 유형의 필수 요소를 정의할 수 있다.
    3. 대규모 프로젝트를 쉽게 관리할 수 있다.
    4. 다른 사용자와 동시에 개발할 수 있다.
    5. 잘 작성한 롤은 앤서블 갤럭시를 통해 공유하거나 다른 사람이 공유한 롤을 가져올 수 있다.

 

 

앤서블 롤 구조

  • 앤서블 롤은 하위 디렉토리 및 파일의 표준화된 구조에 의해 정의된다.
  • 최상위 디렉토리는 롤 자체의 이름을 의미하고, 그 안은 tasks 및 handlers 등 롤에서 목적에 따라 정의된 하위 디렉토리로 구성된다.
    • defaults : 이 디렉토리의 main.yml 파일에는 롤이 사용될 때 덮어쓸 수 있는 롤 변수의 기본값이 포함되어 있다. 이러한 변수는 우선순위가 낮으며 플레이에서 변경 가능하다.
    • files : 이 디렉토리에는 롤 작업에서 참조한 정적 파일이 있다.
    • handlers : 이 디렉토리의 main.yml 파일에는 롤의 핸들러 정의가 포함되어 있다. 핸들러란 다른 작업에서 트리거된 알림에 응답하는 작업이다.
    • meta : meta 디렉토리의 main.yml 파일에는 작성자, 라이센스, 플랫폼 및 옵션, 롤 종속성을 포함한 롤에 대한 정보가 들어있다.
    • tasks : 롤의 작업 정의가 포함되어 있다.
    • templates : 롤 작업에서 참조할 Jinja2 템플릿이 있다. jinja2 템플릿이란 파이썬 깁만의 템플릿 엔진이다. 템플릿 엔진은 웹 애플리케이션에서 동적으로 생성되는 HTML, XML, JSON 등의 문서를 만들기 위해 사용된다.
    • tests : 롤을 테스트하는 데 사용할 수 있는 인벤토리와 test.yml 플레이북이 포함될 수 있다.
    • vars : 롤의 변수 값을 정의한다.

 

ansible-galaxy role init my-role

 

ansible-galaxy role init 명령어를 사용하여 my-role 이라는 롤을 생성한다.

 

tree my-role

 

tree 명령어로 my-role 롤의 구조를 살펴본다. my-role 디렉토리에는 앞에서 살펴본 롤의 하위 디렉토리들이 있음을 확인할 수 있다.

 

 

롤을 이용한 플레이북 개발

  • 심플한 롤 플레이북을 개발해본다.

 

  • 프로세스
    • 롤이 호출되면 현재 호스트의 운영체제 버전이 지원 운영체제 목록에 포함되는지 확인한다.
    • 운영체제가 CentOS이거나 레드햇이면 httpd 관련 패키지를 dnf 모듈을 이용해 설치한다.
    • 설치가 끝나면 제어 노드의 files 디렉토리 안에 있는 index.html 파일을 관리 노드의 /var/www/html 디렉토리에 복사한다.
    • 파일 복사가 끝나면 httpd 서비스를 재시작한다.
  • 롤 구조
    • 롤 이름 : my-role
    • tasks(메인 태스크)
      • install service : httpd 관련 패키지 설치
      • copy html file : index.html 파일 복사
    • files (정적 파일)
      • index.html
    • handlers
      • restart service : httpd 서비스 재시작
    • defaults (가변 변수) : 메인 태스크에서 사용된 변수 선언
      • service-title
    • vars (불변 변수) : 메인 태스크와 핸들러에서 사용된 변수 선언
      • service_name : 서비스명
      • src_file_path : 복사할 파일 경로
      • dest_file_path : 파일이 복사될 디렉토리 경로
      • httpd_packages : httpd 관련 패키지 목록
      • supported_distros : 지원 OS 목록
    • 해당 프로세스와 롤의 구조에 맞게 플레이북을 작성해보자.

 

vi 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

 

my-role 디렉토리로 이동한 다음 tasks.main.yml 파일에 위 코드를 입력한다. 첫 번째 태스크인 install service에는 플레이북에서 변수로 정의한 서비스명을 함께 출력한다.그리고 ansible.builtin.dnf 모듈을 사용해 httpd 관련 패키지를 설치한다. 이때 관련 패키지는 여러 개이며 loop 문을 사용한다. 서비스 설치가 완료되면 ansible.builtin.copy 모듈을 사용해 파일을 복사하고, 복사가 끝나면 restart service라는 핸들러를 호출한다.

 

vi files/index.html
Hello! Ansible

 

files/index.html 파일을 생성하고 Hello! Ansible 이라는 내용을 입력한다.

 

vi handlers/main.yml

---
# handlers file for my-role

- name: restart service
  ansible.builtin.service:
    name: "{{ service_name }}"
    state: restarted

 

핸들러를 작성한다. ansible.builtin.service 모듈을 이용해 서비스를 재시작한다.

 

vi defaults/main.yml

---
# defaults file for my-role

service_title: "Apache Web Server"

 

외부로부터 재정의될 수 있는 가변 변수를 정한다. service_title을 외부에서 받아 수정이 가능하도록 설정했고, 기본 값은 "Apache Web Server"이다.

 

vi 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
  - Ubuntu

 

service_name, src_file_path, dest_file_path, httpd_packages, supported_distros 라는 불변 변수를 정의한다.

 

 

플레이북에 롤 추가하기

  • 롤을 실행하기 위해서는 롤을 호출해주는 플레이북이 필요하다.
  • 플레이북에서 롤을 추가하려면 2가지 방법이 있다.
    • ansible.builtin.import_role 모듈 : 롤을 정적으로 추가. 고정된 롤을 추가
    • ansible.builtin.include_role 모듈 : 롤을 동적으로 추가. 반복문이나 조건문에 의해 롤 변경 가능
  •  ansible.builtin.import_role을 이용해서 롤을 추가해본다.

 

vi role-example.yml

---

- hosts: tnode1-centos

  tasks:
    - name: Print start play
      ansible.builtin.debug:
        msg: "Let's start role play"

    - name: Install Service by role
      ansible.builtin.import_role:
        name: my-role

 

my-ansible 디렉토리로 이동한 다음 role-example.yml 파일을 생성하고 위 코드를 입력한다. 플레이북에는 ansible.builtin.import_role 모듈을 이용해 앞에서 작성한 my-role 롤을 추가한다.

 

ansible-playbook -syntax-check role-example.yml
ansible-playbook role-example.yml

 

문법 에러 체크를 진행하고 플레이북을 실행한다.(문법 체크는 생략해도 괜찮다.)

플레이북을 실행하면 Print start play 태스크를 시작으로 my-role 내의 각 태스크와 핸들러가 차례대로 수행된다.

 

vi role-example.yml

---

- hosts: tnode1-centos

  tasks:
    - name: Print start play
      ansible.builtin.debug:
        msg: "Let's start role play"

    - name: Install Service by role
      ansible.builtin.import_role:
        name: my-role
      vars:
        service_title: Httpd

ansible-playbook role-example.yml

 

defaults/main.yml 파일에 정의되었던 가변 변수인 service_title을 롤을 호출하는 곳에서 재정의하는 플레이북으로 수정해본다.

수정한 다음 플레이북을 실행하면 태스크명이 install service Httpd로 변경된 것을 확인할 수 있다. httpd 패키지는 방금 설치되었기 때문에 이번에는 패키지를 재설치하거나 파일을 복사하지 않는다.

 

 

플레이북에서 Roles 섹션 사용하기

  • 플레이북에서 롤을 추가하는 다른 방법은 roles 섹션에 롤을 나열하는 것이다.
  • roles 섹션은 tasks 섹션과 매우 유사하나 작업 목록이 아닌 롤 목록으로 구성되어있다.

 

ansible-galaxy role init my-role2
vi my-role2/tasks/main.yml

---
# tasks file for my-role2

- name: Config firewalld
  ansible.posix.firewalld:
    service: "{{ item }}"
    permanent: true
    state: enabled
  loop: "{{ service_port }}"

- name: Reload firewalld
  ansible.builtin.service:
    name: firewalld
    state: reloaded

 

my-role2라는 새로운 롤을 생성하고 my-role2/tasks/main.yml 파일에 firewalld 방화벽 서비스에 http 서비스를 추가하는 태스크와 firewalld 서비스를 reload 하는 태스크를 추가한다.

 

vi my-role2/vars/main.yml

---
# vars file for my-role2

service_port:
  - http
  - https

 

my-role2/vars/main.yml 파일에 service_port 변수에 http와 https 를 정의한다.

 

vi roles-example2.yml

---

- hosts: tnode1-centos

  roles:
    - my-role
    - my-role2

  tasks:
    - name: Print finish role play
      ansible.builtin.debug:
        msg: "Finish role play"

 

롤을 호출하는 플레이북을 작성한다. roles 섹션을 따로 작성해서 my-role과 my-role2를 각각 추가한다.

 

ansible-playbook --check role-example2.yml

 

--check 옵션을 사용해 플레이북을 실행해서 실제 플레이가 수행되기 전에 시뮬레이션 해본다. 시뮬레이션을 통해 my-role과 my-role2 롤들이 차례대로 실행되는 것을 확인할 수 있다.

 

vi role-example3.yml

---

- hosts: tnode1-centos

  roles:
    - role: my-role
      service_title: "Httpd Web"
    - role: my-role2

  tasks:
    - name: Print finish role play
      ansible.builtin.debug:
        msg: "Finish role play"

 

roles 섹션을 사용할 때도 defaults/main.yml 파일에 선언한 가변 변수의 값을 함께 넘겨줄 수 있다.

my-role의 defaults/main.yml 파일에 정의되어 있는 service_title로, "Httpd Web"이라는 값을 넘겨준다.

 

ansible-playbook --check role-example3.yml

 

실행해보면 my-role의 태스크명이 install service Httpd Web으로 출력되는 것을 확인할 수 있다.

 

 

특수 작업 섹션

  • roles 섹션과 함께 자주 사용되는 2개의 특수 작업 섹션이 있다.
    • pre_tasks : tasks와 유사한 작업 목록이지만, roles 섹션의 롤보다 먼저 실행
    • post_tasks : tasks 및 핸들러 다음에 실행

 

---
vi special_role.yml

---

- hosts: tnode1-centos

  pre_tasks:
    - name: Print Start role
      ansible.builtin.debug:
        msg: "Let's start role play"

  roles:
    - role: my-role
    - role: my-role2

  tasks:
    - name: Curl test
      ansible.builtin.uri:
        url: http://tnode1-centos
        return_content: true
      register: curl_result
      notify: Print result
      changed_when: true

  post_tasks:
    - name: Print Finish rold
      ansible.builtin.debug:
        msg: "Finish role play"

  handlers:
    - name: Print result
      ansible.builtin.debug:
        msg: "{{ curl_result.content }}"

 

특수 작업 섹션인 pre_tasks와 post_tasks를 작성한다.

 

ansible-playbook special_role.yml

 

플레이북을 실행해 어떤 순서대로 태스크와 롤이 실행되는지 확인한다.

가장 먼저 pre_tasks 섹션에 있던 Print start role이 실행된다.

그 다음 my-role과 my-role2의 태스크가 실행된다.

그리고 tasks의 Curl test 태스크가 실행되고 handlers인 Print result 가 실행된다.

마지막으로 post_tasks인 Print Finish rold가 실행된다.

 

 

728x90
반응형