목차
Roles
`Roles`을 사용하면 알려진 파일 구조를 기반으로 관련 변수, 파일, tasks, handlers 및 기타 Ansible artifacts를 자동으로 로드할 수 있습니다. content를 role로 그룹화하면, 쉽게 재사용할 수 있습니다.
Role directory structure
Ansible role은 8개의 주요 표준 디렉터리가 있는 정의된 데릭터리 구조가 있습니다. 적어도 각 역할에 표준 디렉터리 중 하나 이상은 포함해야 합니다. Role에서 사용하지 않는 디렉터리는 생략이 가능합니다.
# playbooks
site.yml
webservers.yml
fooservers.yml
roles/
common/ # this hierarchy represents a "role"
tasks/ #
main.yml # <-- 필요한 경우 더 작은 파일을 포함할 수 있습니다.
handlers/ #
main.yml # <-- handlers file
templates/ # <-- files for use with the template resource
ntp.conf.j2 # <------- templates end in .j2
files/ #
bar.txt # <-- files for use with the copy resource
foo.sh # <-- script files for use with the script resource
vars/ #
main.yml # <-- variables associated with this role
defaults/ #
main.yml # <-- default lower priority variables for this role
meta/ #
main.yml # <-- role dependencies
library/ # roles can also include custom modules
module_utils/ # roles can also include custom module_utils
lookup_plugins/ # or other types of plugins, like lookup in this case
webtier/ # same kind of structure as "common" was above, done for the webtier role
monitoring/ # ""
fooapp/ # ""
기본적으로 Ansible은 role 내의 각 디렉토리에서 main.yml 파일을 찾습니다.(main.yaml or main도 포함)
- tasks/main.yml : role이 실행되는 태스크들의 메인 리스트
- handlers/main.yml : 핸들러는 해당 역할의 내부 또는 외부에서 사용할 수 있음
- library/my_module.py : role 내에서 사용되는 모듈
- defaults/main.yml : role에서 사용되는 default variables. 여기서의 variables는 가장 낮은 우선순위를 가지며 인벤토리 변수를 비롯한 다른 변수에 의해 쉽게 재정의가 가능
- vars/main.yml : other variables for the role
- files/main.yml : role이 배포하는 파일
- templates/main.yml : role이 배포하는 템플릿
- meta/main.yml : role의 메타데이터로 role의 종속성(dependency) 등을 포함합니다.
예를 들어, 플랫폼별 작업을 별도의 파일에 저장하고 `tasks/mail.yml` 파일에서 참조할 수 있습니다.
# roles/example/tasks/main.yml
- name: Install the correct web server for RHEL
import_tasks: redhat.yml <<== redhat.yml 파일 참조
when: ansible_facts['os_family']|lower == 'redhat'
- name: Install the correct web server for Debian
import_tasks: debian.yml <<== debian.yml 파일 참조
when: ansible_facts['os_family']|lower == 'debian'
# roles/example/tasks/redhat.yml
- name: Install web server
ansible.builtin.yum:
name: "httpd"
state: present
# roles/example/tasks/debian.yml
- name: Install web server
ansible.builtin.apt:
name: "apache2"
state: present
Storing and finding roles
기본적으로, Ansible은 아래 경로들에서 Role을 찾습니다.
- 컬렉션을 사용하는 경우
- roles/ 디렉터리에 있는 플레이북 관련 파일들
- `roles_path` config의 경로 (default: ~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles)
- 플레이북 파일이 위치한 디렉토리
만약, 다른 장소에 role을 저장하고 싶다면, `roles_path` 설정으로 변경할 수 있습니다.
또는 아래와 같이 경로를 사용하여 role을 호출할 수도 있습니다.
---
- hosts: webservers
roles:
- role: '/path/to/my/roles/common'
참고로, 저희 프로젝트는 제일 마지막에 나온 경로 설정으로 role을 호출합니다.
예를 들어서 playbook 파일 내에서 아래처럼 사용합니다.
- name: Restart broker
hosts: kafka:&broker
serial: 1
vars:
target_service_type: broker
target_service_port: 9092
roles:
- role: roles/kafka/restart
tags: [kafak, broker]
Using roles
3가지 방식으로 role을 사용할 수 있습니다.
- play level에서 `role` 옵션 : play에서 role을 사용하는 가장 일반적인 방법입니다.
- task level에서 `include_role` : play의 task section에서 역할을 동적으로 재사용 할 수 있습니다.
- task level에서 `import_role` : play의 task section에서 역할을 정적으로 재사용 할 수 있습니다.
Using roles at the play level
Role을 사용하는 일반적인 방법은 play에 roles 옵션을 사용하는 것입니다. (우리 프로젝트는 이 방법 사용)
---
- hosts: webservers
roles:
- common
- webservers
`roles` 옵션에 여러 키워드를 넘길 수 있습니다.
---
- hosts: webservers
roles:
- common
- role: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
tags: typeA
- role: foo_app_instance
vars:
dir: '/opt/b'
app_port: 5001
tags: typeB
`role` option에 tag를 추가하면, Ansible은 role에 속한 모든 task에 tag를 적용합니다.
플레이북의 `roles:`섹션에서 `vars:` 를 사용하면, 변수가 play 변수에 추가되어 role 전후에 play 내의 모든 task에서 사용할 수 있습니다.
Including roles: dynamic reuse
`include_role`을 사용하여 play의 task 섹션 어디에서나 역할을 동적으로 재사용할 수 있습니다. `roles` 섹션에 추가된 roles는 play의 다른 task보다 먼저 실행되지만, 포함된 role은 정의된 순서대로 실행됩니다. `include_role` task 앞에 다른 task가 있는 경우, 다른 task가 먼저 실행됩니다.
---
- hosts: webservers
tasks:
- name: Print a message
ansible.builtin.debug:
msg: "this task runs before the example role"
- name: Include the example role
include_role:
name: example
- name: Print a message
ansible.builtin.debug:
msg: "this task runs after the example role"
roles 내에 variables와 tag를 포함할 수 있습니다.
조건부로 role을 포함할 수도 있습니다.
---
- hosts: webservers
tasks:
- name: Include the some_role role
include_role:
name: some_role
when: "ansible_facts['os_family'] == 'RedHat'"
Importing roles: static reuse
`import_role`을 사용하여 play의 task 섹션 어디에서나 role을 정적으로 재사용할 수 있습니다. roles 키워드를 사용하는 것과 동일하게 동작됩니다.
---
- hosts: webservers
tasks:
- name: Print a message
ansible.builtin.debug:
msg: "before we run our role"
- name: Import the example role
import_role:
name: example
- name: Print a message
ansible.builtin.debug:
msg: "after we ran our role"
import_role문에 task를 추가하면 Ansible은 role 내의 모든 task에 태그를 적용합니다.
Role argument validation
2.11 버전부터 매개변수(argument) 특성 유효성 검사를 사용할 수 있습니다.
이 특성 명세(specification)는 meta/argument_spaces.yml (or .yaml) 파일에 정의되어 있습니다. 매개변수의 특성이 정의되면, role이 실행될 때 새로운 task가 추가되어 role에 제공된 매개변수의 유효성을 검사합니다.
매개 변수의 유효성 검사가 실패하면, role 실행이 실패합니다.
Specification format
link 에서 자세한 내용을 확인할 수 있습니다.
Sample specification
# roles/myapp/meta/argument_specs.yml
---
argument_specs:
# roles/myapp/tasks/main.yml entry point
main:
short_description: The main entry point for the myapp role.
options:
myapp_int:
type: "int"
required: false
default: 42
description: "The integer value, defaulting to 42."
myapp_str:
type: "str"
required: true
description: "The string value"
# roles/myapp/tasks/alternate.yml entry point
alternate:
short_description: The alternate entry point for the myapp role.
options:
myapp_int:
type: "int"
required: false
default: 1024
description: "The integer value, defaulting to 1024."
Running a role multiple times in one play
role에 정의된 parameter가 각 정의마다 다르지 않는 한, role을 여러 번 정의하더라도 Ansible은 play에서 role을 한번만 실행합니다.
role의 parameter는 서로 다르게 정의되어 있습니다. 아래와 같이 적는다면, Ansible은 role `foo`를 play에서 한 번만 실행합니다.
---
- hosts: webservers
roles:
- foo
- bar
- foo
두 가지 옵션으로 Ansible이 role을 두 번 이상 실행하도록 강제할 수 있습니다.
Passing different parameters
각 role 정의에 parameter가 다르게 정의되어 있다면, Ansible은 role을 한 번 이상 실행합니다. 다른 변수 값을 제공하는 것은 다른 role 매개변수를 전달하는 것과 다릅니다. import_role과 include_role은 role 매개 변수를 허용하지 않으므로 roles 키워드에서만 동작합니다.
아래 play는 `foo`가 두 번 실행됩니다.
---
- hosts: webservers
roles:
- role: foo
message: "first"
- role: foo
message: "second"
Using `allow_duplicates: true`
role에 대한 `meta/main.yml` 파일에 `allow_duplicates: true`를 추가합니다.
# playbook.yml
---
- hosts: webservers
roles:
- foo
- foo
# roles/foo/meta/main.yml
---
allow_duplicates: true
Using role dependencies
Role 종속성(dependency)을 사용하면, 한 role을 사용할 때 다른 role을 자동으로 추가할 수 있습니다.
Role 종속성은 선행작업으로 엄밀히 말하자면 종속성이 아닙니다. Role은 parent/child 관계를 가지지 않습니다.
Ansible은 모든 roles 리스트를 로드하고, `dependencies`하위 role 리스트를 먼저 실행한 이후에 다른 role을 실행합니다.
Play object는 종속성 리스트에서 호출되는 role을 포함한 모든 role의 부모입니다.
Role 종속성은 role 디렉토리 내에 `meta/main.yml`에 저장됩니다. 이 파일에는 특정 role 앞에 넣을 role 리스트와 파라미터가 포함되어야 합니다.
# roles/myapp/meta/main.yml
---
dependencies:
- role: common
vars:
some_parameter: 3
- role: apache
vars:
apache_port: 80
- role: postgres
vars:
dbname: blarg
other_parameter: 12
Ansible은 종속성에 있는 role을 다른 role보다 먼저 실행합니다. Ansible은 `roles` 키워드를 사용할 때 이 패턴을 재귀적으로 실행합니다. 예를 들어, foo, bar, baz라는 roles가 있을 때, foo의 종속성에 bar이 들어가고 bar의 종속성에 baz가 들어간다면 실행 순서는 baz - bar - foo 가 됩니다.
Running role dependencies multiple times in one play
Ansible은 위에서 언급한 중복된 role 처럼 role 종속성에서도 중복된 role은 한 개로 간주합니다. (role에 정의된 매개변수, tag 또는 when 절이 각 정의마다 다른 경우 제외)
Play의 두 역할이 모두 세 번째 role을 종속성으로 나열하거나, 다른 매개변수나 tag를 사용하거나, when절을 전달하거나 `allow_duplicates:true`를 사용하지 않는 한 Ansible은 해당 Role 종속성을 한 번만 실행합니다.
아래 예시로 쭉 보겠습니다.
- 아래는 `car`이라는 role의 종속성입니다.
---
dependencies:
- role: wheel
n: 1
- role: wheel
n: 2
- role: wheel
n: 3
- role: wheel
n: 4
wheel에 두 개의 종속성 `tire`와 `brake`가 있습니다. `wheel`에 대한 `meta/main.yml` 파일에 아래와 같이 포함됩니다.
---
dependencies:
- role: tire
- role: brake
그리고 `tire`와 `brake`의 `meta/main.yml` 파일에 다음과 같이 추가합니다.
---
allow_duplicates: true
실행 결과는 순서대로 다음과 같이 나옵니다.
tire(n=1)
brake(n=1)
wheel(n=1)
tire(n=2)
brake(n=2)
wheel(n=2)
...
car
Role 종속성과 함께 `allow_duplicates:true`를 사용하려면 종속성을 가진 role이 아닌 종속성 아래에 나열된 role에 지정해야 합니다. 위 예제에서는 `tire`와 `brake` role의 `meta/main.yml`에 `allow_duplicates:true`를 설정합니다.
Enbedding mudules and plugins in roles
사용자 지정 모듈 또는 플러그인을 작성하는 경우 이를 role의 일부로 배포할 수 있습니다.
예를 들어, 회사의 내부 소프트웨어를 구성하는 데 필요한 모듈을 조직의 다른 사람들이 사용할 수 있게 하고 싶지만, 모든 사람에게 Ansible 라이브러리 경로를 구성하는 방법을 알려주고 싶지 않은 경우, 내부 _config role에 모듈을 포함할 수 있습니다.
Role에 모듈이나 플러그인을 추가하려면 role의 `tasks` 및 `handlers` 구조에 `library`라는 디렉토리를 추가한 다음 이 디렉토리에 포함시킵니다.
roles/
my_custom_modules/
library/
module1
module2
References
'데이터 엔지니어링' 카테고리의 다른 글
Druid flatten spec 공식 문서 (0) | 2023.03.26 |
---|---|
Druid segment retention rules | 세그먼트 보존 규칙 (0) | 2023.03.26 |
Ansible Inventory와 variables 설정 방법 (0) | 2023.03.16 |
Apache Druid 정의, 구성요소, 아키텍처 (0) | 2022.12.27 |
Elasticsearch search_after vs scroll API(cursor) (3) | 2022.10.08 |
댓글