ansible에서 log 파일 기록하기

ansible을 사용하면서 문제가 발생할 때 가장 먼저 확인할 수 있는 것은 ansible log이다. 이러한 log는 아래 방법으로 로그 파일을 기록할 수 있다. 이러한 log를 통해 ansible, ansible-playbook 명령의 출력을 저장하고 문제 발생시 이것을 확인하여 troubleshooting을 할 수 있다.

 

vi ansible.cfg

[defaults]
log_path = /home/student/troubleshoot-playbook/ansible.log 

 

# 참고 : log 저장 위치

log 파일이 저장될 위치를 /var/log로 하려면, playbook을 root로 실행하거나, /var/log에 대한 권한 설정을 변경해야 한다. 또한 로그파일 관리를 위해 logrotate도 구성하도록 권고된다.

 

 

debug 모듈의 msg로 변수 확인하기

debug 모듈은 playbook이 실행되면서 특정 변수들에 대한 값을 직접 확인할 수 있다. 변수를 사용하는 playbook에서 디버깅을 할 때 사용할 수 있다. 예를 들어 작업 출력을 다음 작업의 입력으로 쓰는데, 그 값이 제대로 들어갔는지 확인할 때 사용한다.

 

debug 모듈은 2가지 방법으로 사용한다.

1. 메시지+변수를 출력 (msg 사용)

2. 변수를 출력 (var 사용)

---
- name: debug test
  hosts: workstation.lab.example.com
  tasks:

    - name: debug test task
      debug:
        msg: "the free memory for this system is {{ ansible_facts['memfree_mb'] }}"

    - name: display the "output" variable
      debug:
        var: ansible_facts['memfree_mb']

 

task 전체를 실행하지 않고, 일부만 실행하기

--start-at-task 옵션을 사용하면, 해당 플레이북의 task중 특정 task부터 끝까지 실행하게 할 수 있다. 즉 시작하는 task를 처음부터가 아닌 명시한 task부터 하게 하는 것이다. 예를들어 아래 예시를 보자.

---
- name: debug test
  hosts: workstation.lab.example.com
  tasks:

    - name: debug test task
      debug:
        msg: "the free memory for this system is {{ ansible_facts['memfree_mb'] }}"

    - name: display the output variable
      debug:
        var: ansible_facts['memfree_mb']

    - name: third output
      debug:
        msg: "third task"

이 예시 파일에서 다음과 같이 실행하면, display the output variable 태스크부터 시작한다. (이 --start-at-task 옵션은 인수로 name을 받는다.)

ansible-playbook debugtest.yml --start-at-task="display the output variable"

원래 task가 3개여야 하는데, 중간에 display the output variable 태스크부터 시작해서 끝까지 수행하는 것을 알 수 있다.

 

 

디버깅 옵션

playbook을 실행할 때, -v 옵션을 사용하여 디버그 정보를 확인할 수 있다. 아래 예시처럼 사용할 수 있다.

ansible-playbook debugtest.yml -vv

-v

출력 데이터가 표시된다.

-vv

출력 및 입력 데이터가 모두 표시된다.

-vvv

관리 호스트 연결에 대한 정보를 포함한다.

-vvvv

각 원격 호스트에서 실행되는 스크립트와 각 스크립트를 실행하는 사용자와 같은 추가 정보가 포함된다.

 

플레이북을 관리할 때 권장사항

1. 플레이와 작업의 이름을 정하기 위해 플레이나 작업 목적에 대한 간결한 설명을 사용한다. 플레이 name, 작업 name은 플레이북이 실행되면 표시된다. 

2. 작업에 대한 추가 인라인 설명서를 추가할 정의를 포함한다.

3. 세로 공백을 효율적으로 사용한다. 일반적으로 작업 속성을 세로로 구성하여 읽기 쉽게 만든다.

4. 일관된 수평 들여쓰기가 중요하다. 탭이 아닌 공백을 사용하여 들여쓰기 오류를 방지한다. 이를 쉽게 하기 위해 tab를 누르면 공백을 쓰도록 텍스트 편집기를 설정한다.

5. 가능한 간단하게 플레이북을 유지한다. 필요한 기능만.

 

 

 

문제 검증 예시

위 예시처럼 Failed to connect to the host via ssh: ssh: Could not resolve hostname servera.lab.example.com: Name or service not known 이런식으로 뜬다면, 여러가지를 해볼 수 있지만 먼저 해볼 것은 아래 4가지이다.

 

1.해당 관리 호스트 servera.lab.example.com 이 살아있는지 핑으로 확인

2. ssh 접속이 잘 되는지 확인, ssh 키가 있는지 확인

3. 더 자세한 정보를 얻기위해 -vvvv 옵션으로 실행.

4. inventory 파일의 철자 확인

 



 

 

 

테스트 도구로 검사 모드 사용하기

- 테스트를 위해 두가지 옵션을 사용할 수 있다.

 

* --check 옵션

ansible-playbook --check playbook.yml

이 옵션은 검사모드로, 즉 관리 호스트의 구성을 변경하지 않고 (즉 효력이 없고) 플레이북을 실행한다. 플레이북 내에서 사용된 모듈이 검사 모드를 지원하는 경우 관리 호스트에서 변경한 사항이 표시되지만 수행되지 않는다. 검사 모드가 모듈에서 지원되지 않으면 변경 사항은 표시되지 않지만, 모듈은 여전히 조치를 취하지 않는다. 참고로, 작업에서 조건문을 사용하는 경우, --chcek 명령이 제대로 작동하지 않을 수 있다. 유의할 것.

 

* --diff 옵션

클라이언트의 템플릿 파일에 변경이 가해졌다면, 그 변경 사항을 보고한다. 이 옵션을 사용할 수 있는 모듈이 따로 정해져 있다. 아래 예시는 template 모듈을 사용했고, 다른 모듈도 사용할 수 있는지는 확인해보아야 한다.

 

 

* --check, --diff 옵션 사용 예시

 

test.j2

{% if users is defined and users %}
{% for user in users %}{{ user }}
{% endfor %}
{% endif %}

jinja2test.yml

---
- hosts: 127.0.0.1
  tasks:
  - name: Test jinja2template
    template:
      src=test.j2
      dest=test.conf
  vars:
    users:
      - mike
      - smith
      - clare
      - alex

 

아무 파일도 없으므로, 붉은색 --- before 부분에는 아무것도 나오지 않는다. 그리고 mike, smith, klare, alex가 추가되었다는 것을 알 수 있다.

 

이제 jinja2test.yml 을 다음과 같이 변수를 수정해보자.

---
- hosts: 127.0.0.1
  tasks:
  - name: Test jinja2template
    template:
      src=test.j2
      dest=test.conf
  vars:
    users:
      - 1234
      - 112
      - 4038
      - 0327

그리고 다시 실행하면, 아래와 같이 붉은색은 before, 이전 값이고, 녹색은 이번에 적용된 값을 확인할 수 있다. 그런데 --check 옵션을 썼으므로 결과만 확인이 가능하고 실제로 적용되지는 않는다.

 

 

디버깅이나 상태에 대한 추가정보를 제공하는 모듈들

* uri 모듈

-RESTful API가 필요한 콘텐츠를 반환하는지 확인하는 방법을 제공한다.

- name: test
  hosts: web1.example.com
  tasks:
    - uri:
        url: http://api.myapp.com
        return_content: yes
        register: apiresponse
    - fail:
        msg: 'version was not provided'
      when: "'version' not in apiresponse.content"

 

* script 모듈

script 모듈은 관리 호스트에서 스크립트 실행을 지원하고 해당 스크립트의 반환 코드가 0이 아닌 경우 실패한다. 스크립트는 제어 노드에 있어야 하며 관리 호스트로 전송되어 실행된다.

- name: test
  hosts: web1.example.com
  tasks:
    - script: check_free_memory

 

 

* fail 모듈

- fail 모듈 task가 실행되면, 그 시점에서 fail이 발생하고 플레이북은 중단된다. 따라서 조건문을 넣어서 자주 사용한다.

- name: show failed system requirements message
  fail:
    msg: "the {{ inventory_hostname }} did not meet minimum reqs."
  when: >
    ansible_memtotal_mb*1024*1024 < min_ram_megabytes*1000000 or
    ansible_distribution != "redhat"

- 위 예시는 2개의 조건 중 하나라도 만족하면 fail을 발생시키고 메시지를 뿌리는 것이다.

 

 

* stat 모듈

stat 모듈은 stat 명령과 유사하게 파일에 대한 사실을 수집한다. 이를 사용해 번수를 등록하고 테스트하여 파일이 존재하는지 또는 파일에 대한 다른 정보를 얻을 수 있는지 테스트할 수 있다.

 

즉, 특정 파일에 대해 stat 모듈을 사용하며, 그 파일이 존재하면 stat 결과에 포함되는 값인 [register변수.stat.exists]에 true를 보고하고, ok가 된다. (changed가 아님) 만약 그 파일이 존재하지 않는다면, stat 결과에 포함되는 값인 [register변수.stat.exists]에 false를 보고한다. 따라서 이 false, true를 가지고 뭔가 작업을 수행할 수 있다.

 

아래 예제는 특정 파일이 존재하면 playbook을 fail시켜서 중단시키는 예제이다. fail 모듈은 조건이 true이면 해당 playbook을 fail시키고 중단시킨다.

---
- hosts: 127.0.0.1
  tasks:
  
  - name: check if /var/run/app.lock exists
    stat:
      path: /var/run/app.lock1
    register: lock
    
  - name: fail if the application is running
    fail:
    when: not lock.stat.exists

 

파일이 존재하는 경우 이렇게 레지스터 변수의 stat의 exists가 true가 나온다. 그리고 true이므로 조건문에 따라 fail 부분은 skip 하게 된다. 서비스가 살아있으면, 즉 파일이 존재하면 not true이므로 false 된다그러면 fail 실행하지 않는다.

 

만약 파일 이름을 바꿔서 파일이 없는것처럼 되었다면, 아래처럼 레지스터 변수의 stat의 exists가 false가 나온다. 그리고 false 이므로 조건문에 따라 fail이 진행되고 플레이가 중단된다. 서비스가 죽어있으면, 즉 파일이 없으면 not false이므로 true가 된다. 그러면 fail을 실행한다.

 

 

 

 

* assert 모듈

assert 모듈은 fail 모듈에 대한 대안이다.  이 모듈은 조건문 "목록"을 취하는 that 옵션을 지원한다. 여러 조건이 있을 때 이러한 조건문 중 하나가 false이면 작업이 실패한다.

---
- hosts: 127.0.0.1
  tasks:
  - name: check if /var/run/app.lock exists
    stat:
      path: /var/run/app.lock1
    register: lock
  - name: fail if the application is running
    assert:
      that:
        - lock.stat.exists

 

stat 모듈 예시와 동일하지만 that 이하에 조건이 not이 빠졌다. 여기서는 해당 조건이 false가 나면 fail이 되어 playbook이 중단되기 때문이다. 따라서 위 구문은 파일이 존재해서 true를 받으면, 그대로 assert에서도 true를 받아 아무일도 일어나지 않는다.

만약 파일이 없다면, 파일이 없으므로 false가 나오고, 그대로 assert에서도 false를 받아 playbook이 중단된다.

 

 

연결 문제를 진단하기

일반적으로 연결 자체에 대한 문제는 호스트 연결 및 원격 사용자와의 권한 에스컬레이션 관련하여 문제가 많이 발생한다.  이러한 문제가 발새하는 경우 아래 내용을 검토한다.

 

- 클라이언트에 인증하는데 문제가 있다면, 구성 파일이나 플레이에서 remote_user를 올바르게 썼는지 확인

- 올바른 ssh 키를 설정했는지, 올바른 암호를 제공했는지 확인

- become이 올바르게 설정되어있고 올바른 become_user를 사용하는지 확인 (default는 root이다)

- 올바른 sudo 암호를 입력하며 관리 호스트에 sudo 설정이 잘 되어있는지 확인

 

 

 

 

 

ansible-playbook을 실행하다 중간에 에러가 났다면?

- ansible은 플레이북에 포함되고 해당 모듈에서 수행한 구성이 올바른지 확인하도록 설계되었다.

- 모든 모듈에서 보고된 오류를 모니터링하고 오류가 발생하면 플레이북을 바로 중지한다.

- 이렇게 하면 오류 이전에 수행된 작업에는 오류가 없다. 

- 그러므로 앤서블에서 관리한 작업의 결과가 관리 호스트에서 올바르게 적용되었는지 일반적으로 확인하지 않아도 된다.

- 직접 문제를 해결해야 하는 경우 플레이북에 몇 가지 상태 검사를 추가하거나, 애드혹 명령으로 그러한 상태 검사를 실행하는 것이 좋다.

- 하지만 모듈 자체에서 수행하는 테스트를 다시 확인하기 위해 작업 및 플레이를 너무 복잡하게 만드는건 조심해야 한다.

 

 

 

 

예제 - 문제가 발생하는 것 확인하고 해결하기

 

* inventory 파일 내용

 

* ansible.cfg 파일 내용

 

* 템플릿 파일 내용 (postfix-relay-main.conf.j2)

 

* 사용할 yml 파일

 

* 결과

ansible-playbook mailrelay.yml --check 로 실행

task들을 쭉 보면, 설치 및 서비스 시작 등이 잘 시작되었는데도, 에러가 난다. 이 이유는 알고보니 그냥 --check로 실행했기 때문에 실제로 설치가 되지 않아 실제 작업 구문이 fail이 난 것이다. 아래처럼 애드혹 명령으로 확인해보니, /etc/postfix/main.cf 파일이 없다고 한다.

--check를 빼고 실행하면, 아래와 같이 잘 실행된다.

결과 부분에 Ansible managed라고 뜨는것은 , 템플릿 파일에 {{ ansible_managed }} 라고 해 두었고 ansible.cfg에 설정했기 때문이다. 15장 참고

2021.02.26 - [Ansible] - 15장. ansible에서 jinja2 사용하기

 

 

 

 

참조링크

 

ansible 구성

https://docs.ansible.com/ansible/2.7/installation_guide/intro_configuration.html 

 

Configuring Ansible — Ansible Documentation

Docs » » Configuring Ansible You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansible documentat

docs.ansible.com

debug

https://docs.ansible.com/ansible/2.7/modules/debug_module.html 

 

debug – Print statements during execution — Ansible Documentation

Docs » debug – Print statements during execution You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the late

docs.ansible.com

모범 사례

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_best_practices.html 

 

Best Practices — Ansible Documentation

Here are some tips for making the most of Ansible and Ansible playbooks. You can find some example playbooks illustrating these best practices in our ansible-examples repository. (NOTE: These may not use all of the features in the latest release, but are s

docs.ansible.com

검사 모드

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_checkmode.html 

 

Check Mode (“Dry Run”) — Ansible Documentation

You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansible documentation. When ansible-playbook is e

docs.ansible.com

테스트 전략

https://docs.ansible.com/ansible/2.7/reference_appendices/test_strategies.html 

 

 

ansible galaxy란?

여러 ansible 관리자와 사용자가 작성한 공용 ansible role 라이브러리이다. 수천개의 ansible role이 있고, ansible 사용자가 관리 작업을 수행하는 데 도움이 되는 role을 식별할 수 있는 검색 가능한 데이터베이스가 있다. 또한 ansible-galaxy 명령어는 자신의 git에서 연동하도록 할 수도 있다. 도커허브랑 거의 동일하다고 볼 수 있다.

 

https://www.galaxy.ansible.com

 

* ansible-galaxy 문서 찾기

https://galaxy.ansible.com/docs 

- 위 링크에서 ansible-galaxy를 사용하는 방법을 자세하게 확인할 수 있다.

 

 

ansible galaxy에서 role 검색하기

ansible galaxy 검색인터페이스에서 키워드 검색은 role의 README파일컨텐츠 이름컨텐츠 설명에 있는 단어/구문을 검색하여 결과를 출력한다. ansible galaxy의 search 항목에서 아래와 같이 role을 검색할 수 있다.

- 여기서 각 role이 다운로드 된 수, 해당 role의 별점, 버전, 태그 등의 여러정보를 확인할 수 있다. 

- 검색 시 filters와 type를 사용하여 원하는 대로 상세하게 검색할 수 있다.

 

* 태그

- 인기있는 태그와 사용하는 플랫폼을 검색하는데 사용한다. 참고로 EL은 RHEL(CentOS)이다.

 

# 참고 : 점수 관련

- 아래와 같이 5점 만점에 3.8점이라는 점수를 확인할 수 있는데, 이러한 점수를 매기는 방식이 따로 존재하며 아래 링크를 통해 확인할 수 있다.

https://galaxy.ansible.com/docs/contributing/content_scoring.html

 

Content Scoring — Ansible Documentation

This topic describes how content is scored. Content Scoring is in early iterations, to be improved with user feedback and future additions to ansible-lint. The overall score is a combination of the community score, the quality score and the number of surve

galaxy.ansible.com

 

 

 

 

ansible galaxy CLI 명령어

 

1. ansible-galaxy search

 

* 설명

- role을 검색하는 명령이다.

 

* 옵션

--author

--platforms

--galaxy-tags

 

* 예시

ansible-galaxy search 'redis' --platforms 'EL' --galaxy-tags 'security''

 

2. ansible-galaxy info


* 설명

role에 대한 세부 정보를 표시한다. 이러한 정보는 meta/main.yml 및 해당 github 레포지토리 등 여러 소스에서 정보를 가져온다.

 

* 예시

ansible-galaxy info juju4.misp

 

3. ansible-galaxy install

 

* 설명

role을 다운받아 설치한다. 기본적으로 ansible에 설정된 기본 path인 ~/.ansible/roles 디렉토리에 설치된다.

 

* 옵션

-p 디렉토리 : role을 설치할 위치를 기본값이 아닌 특정 디렉토리 지정

-c : ignore certs : SSL certificate를 무시한다. 특정 보안설정 없이 설치하려면 이 옵션을 꼭 추가해야 한다.

 

# 참고 : 설치 시 에러 뜨는 경우

- 이런 에러가 뜨는 경우, -c 옵션을 사용하면 된다.

- 그래도 안되는 경우, yum install ca-certificates 패키지를 설치 또는 최신업데이트를 수행한다.

 

* 예시

ansible-galaxy install geerlingguy.redis -p ~/.ansible/roles/ -c

- 다운로드 후 tree 명령으로 전체 내역을 간단하게 훑어볼 수 있다.

 

# 참고 : 다운받은 role 참조하기

- 다운받은 role도 일반 role과 마찬가지로 참조할 때 이름으로 참조하면 된다.

---
- name: use downloaded role
  hosts: web.example.com
  roles:
     - geerlingguy.redis

- 이 role의 이름은 4번에서 설명할 ansible-galaxy list로 확인하면 되며, 참조경로는 이 예시의 yaml 파일의 위치를 기준으로 지정하거나 절대경로를 지정하면 된다.

 

 

4. ansible-galaxy list

 

* 설명

- 설치된 roles의 리스트를 보여준다.

- roles가 저장되는 default 다운로드 위치 3곳에 설치된 roles를 보여준다. 기본 위치는 다음과 같다.

     - /home/유저명/.ansible/roles (가장 우선되는 기본경로)

     - /usr/share/ansible/roles

     - /etc/ansible/roles

-c 옵션으로 경로를 지정하는 경우, 해당 경로에 설치된 roles를 보여준다.

 

* 옵션

-p 디렉토리 : role을 검색할 위치를 기본값이 아닌 특정 디렉토리 지정

 

* 예시

 

<기본 명령 사용>

<-c 옵션으로 특정 경로 지정>

 

 

5. ansible-galaxy remove

 

* 설명

- 설치된 role을 삭제한다.

 

* 옵션

-p 디렉토리 : role을 삭제할 위치를 기본값이 아닌 특정 디렉토리 지정

 

* 예시

ansible-galaxy remove votum.php -p /tmp/roles

만약 /tmp/roles,와 /home/devops/.ansible/roles 두군데에 동일한 votum.php가 설치되었다면, 위의 예시대로 한다면 /tmp/roles의 votum.php가 삭제된다. 만약 아무런 옵션이 없다면 /home/devops/.ansible/roles에 설치된 votum.php가 삭제된다.

 

 

 

Redhat에서 제공하는 role 사용하기

Redhat에서는 특정 서비스에 대한 role을 공식적으로 제공한다. 이러한 role은 무료로 사용할 수 없으며, 해당 role을 제공하는 서브스크립션을 구매해야만 다운로드 및 사용할 수 있다. 이러한 role은 일반적인 다른 role보다 훨씬 안정적이며 범용적으로 사용할 수 있고, 사후 지원도 받을 수 있다. (서브스크립션을 구매하고 기술지원 관련해서도 구매를 해야 할 것으로 보임) 

 

Redhat 에서 제공하는 것이지만 실제로는 CentOS에서도 사용할 수 있다. 다운로드하고 사용하는것은 가능하지만 사후지원은 받을 수 없다.

 

* redhat에서 제공하는 role 종류

redhat에서 제공하는 role은 다음과 같다. 이 role은 extra 채널에서 rhel-system-roles 패키지에 포함된다.

이름

상태

설명

rhel-system-roles.kdump

전체 지원

kdump 충돌 복구 서비스를 구성한다.

rhel-system-roles.network

전체 지원

네트워크 인터페이스 구성

rhel-system-roles.selinux

전체 지원

selinux 모드,파일 및 포트 컨텍스트, 부울 설정 및 selinux 사용자를 포함하여 selinux 사용자 지정을 구성하고 관리한다.

rhel-system-roles.timesync

전체 지원

네트워크 시간 프로토콜 또는 정밀 시간 프로토콜을 사용하여 시간 동기화를 구성한다.

rhel-system-roles.postfix

기술 프리뷰

postfix 서비스를 사용하여 각 호스트를 메일 전송 에이전트로 구성한다.

rhel-system-roles.firewall

개발중

호스트의 방화벽을 구성

rhel-system-roles.tuned

개발중

시스템 성능을 조정하도록 조정된 서비스를 구성한다.

예를들어, RHEL7은 chronyd를 쓰고 RHEL6은 ntpd를 쓰는데, 이런 구분 상관없이 rhel-system-roles.timesync role을 사용하면 네트워크 타임 서비스를 간단하게 구축할 수 있다.

 

# 참고 : role의 상태 정보

- 전체지원 : 안정적임. 향후 버전에서 동일한 role 변수를 계속 쓴다. 시스템 role 변경으로 인한 playbook의 리팩토링은 최소화된다.

- 기술 프리뷰 : 향후 다른 role 변수를 쓸 수도 있다. 업데이트에 따라 playbook에서 리팩토링을 해야할 수 있다.

- 개발중 : 현재 개발중인 role

 

 

* redhat에서 제공하는 role 설치하기

 

<Redhat 에서 설치하기>

-아래 명령은 서브스크립션을 구매했다고 가정한 것이다.

subscription-manager repos --eanble rhel-7-server-extras-rpms
yum install rhel-system-roles

<CentOS 에서 설치하기>

yum install rhel-system-roles

두 명령 모두 설치된 roel은 /usr/share/ansible/roles에 저장된다.

 

 

* redhat에서 제공하는 role의 문서 보기

해당 문서는 "/usr/share/doc/rhel-system-roles-버전" 경로에서 확인할 수 있다. 각 role 에 대한 디렉토리가 있으며 README 파일, 그리고 예제파일 등이 있으므로 참고할 수 있다.

 

참고링크

 

ansible-galaxy 설명서

https://docs.ansible.com/ansible/2.7/reference_appendices/galaxy.html

 

Ansible Galaxy — Ansible Documentation

Docs » Ansible Galaxy You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansible documentation. Ans

docs.ansible.com

 

'Ansible' 카테고리의 다른 글

20장. playbook의 문제 해결하기  (0) 2021.03.15
17장. ansible role  (0) 2021.03.12
16장. playbook에 파일 포함하기 및 가져오기  (0) 2021.02.27
15장. 병렬 구성 작업  (1) 2021.02.27
14장. ansible에서 jinja2 사용하기  (0) 2021.02.26

ansible playbook의 재사용

ansible 사용 시 사용자가 직접 playbook을 만드는 것도 좋지만, 일반적으로 이미 작성한 플레이북에서 코드를 재사용하는게 훨씬 효율이 좋다.

 

예를들어 특정 어플리케이션과 연동하는 MYSQL을 설치한다면, 다른 어플리케이션도 연동할 수 있게 호스트명, 어플리케이션, 암호, 사용자 등을 변수로 만들어서 작업할 수 있을 것이다. 하지만, 현실에서는 다양한 파일을 포함하거나 다양한 상황을 관리하기 위한 작업과 핸들러를 사용하는 복잡한 작업 등이 있을 수 있어서, 모든 코드를 다른 플레이북에 복사해서 재사용하는게 쉽지 않을 수 있다.

 

Ansible에서는 "Role"을 사용하여 일반적인 방식으로 ansible 코드를 더 쉽게 재사용하는 방법을 제공한다. role은 인프라를 프로비저닝하고, 애플리케이션을 배포하는 등의 모든 작업에 대해 변수, 파일, 템플릿 등의 기타 리소스들을 표준화된 디렉토리 구조로 패키징한다. 다시 정리하면, role 쉬운 공유휴대성  재사용을 위해 특정 구조로 배열된 yaml 작업파일  지원 항목들의 모음이다.

 

이러한 role은 자신이 만든 playbook을 공개할 때, 다른 사람들과 협업할 때 항상 사용한다. 사실상 진짜 실무에서는 여태까지 배운 playbook yml파일 하나가 아닌, role로 업무를 수행한다.

 

# 참고 : 프로비저닝이란?

프로비저닝은 IT 인프라를 설정하는 프로세스이다. 또한 사용자와 시스템에서 사용할 수 있도록, 데이터와 리소스에 대한 액세스를 관리하는 데 필요한 단계를 지칭하기도 한다. 프로비저닝과 설정은 각기 다른 작업이지만, 둘 다 배포 프로세스의 단계에 포함되며 일단 프로비저닝이 완료되어야 설정 단계를 진행할 수 있다. 프로비저닝에는 서버 프로비저닝, 네트워크 프로비저닝, 사용자 프로비저닝, 서비스 프로비저닝 등 다양한 유형이 있다.

www.redhat.com/ko/topics/automation/what-is-provisioning

 

프로비저닝(Provisioning)이란? 종류, 설정, 배포, 자동화 방법

프로비저닝은 IT 인프라 설정 프로세스를 뜻하며, 데이터와 리소스에 대한 액세스 관리에 필요한 단계입니다. 서버, 네트워크, 사용자, 서비스 유형이 있습니다.

www.redhat.com

 

ansible role의 장점

- 컨텐츠를 그룹화하여 코드를 다른 사용자와 쉽게 공유할 수 있다.

- 큰 프로젝트를 관리하기 쉽게 할 수 있다.

- 여러 관리자가 동시에 함께 개발하기 편하다.

- role은 여러 소스에서 가져올 수 있다. 여러 소스가 있지만 대표적으로 아래와 같다.

     - 레드햇에서 서브스크립션으로 지원하는 rhel-system-roles 패키지

     - 사용자가 관리하는 git 등

     - 퍼블릭 레포지토리인 ansible galaxy라는 웹 사이트

 

 

 

ansible role의 구조 요소

role은 하위 디렉토리 및 파일의 표준화된 구조에 의해 정의된다. 최상위 디렉토리는 role 자체의 이름으로 정의한다. 그 아래의 파일들은 tasks, handlers 등 role에서 각 파일의 목적에 따라 이름이 지정된 하위 디렉토리로 구성된다. 예를들어 timesync 라는 디렉토리 안에는 아래 예시같은 디렉토리 구조가 있으며, README.md 파일도 포함할 수 있다.

defaults
   - main.yml
files
handlers
   - main.yml
meta
   - main.yml
tasks
   main.yml
templates
tests
   - inventory
   - test.yml
vars
   - main.yml
README.md

 

각 디렉토리 및 파일의 설명은 다음과 같다.

defaults

이 디렉토리의 main.yml 파일에는 role이 사용될 때 덮어쓸 수 있는 role 변수의 기본값이 포함되어 있다. 이러한 변수는 우선 순위가 낮으며 플레이에서 변경하고 사용자 지정할 수 있다.

이러한 변수는 role을 사용하는 플레이를 작성하는 사람에게 할 일을 정확하게 사용자 지정하거나 제어할 방법을 제공하기 위한 것이다. default 변수는 해당 값을 재정의하려는 경우에만 사용해야 한다.

files

이 디렉토리에는 role 작업에서 참조하는 일반적인 정적 파일이 있다.

handlers

이 디렉토리의 main.yml 파일에는 role의 핸들러 정의가 들어있다.

meta

이 디렉토리의 main.yml 파일에는 작성자, 라이센스, 플랫폼 및 role 종속성 등을 포함한 role의 메타데이터 정보가 들어있다.

tasks

이 디렉토리의 main.yml 파일에는 role의 task들을 정의한 내용이 포함되어 있다.

templates

이 디렉토리에는 role에서 참조하는 jinja2 템플릿이 들어있다.

tests

이 디렉토리에는 role을 테스트하는데 사용할 수 있는 인벤토리와 test.yml 플레이북이 포함될 수 있다. 테스트용이므로 따로 사용하지 않는다면 무시해도 무방하다.

vars

이 디렉토리의 main.yml파일은 role의 변수 값을 정의한다. 종종 이러한 변수는 role 내에서 내부 목적으로 사용된다. 이러한 변수는 우선순위가 높으며 플레이북에서 사용될 때 변경되지 않는다.  vars 변수의 의도는 ROLE의 내부 기능에 의해 사용되는 변수를 정의하도록 하는 것이다.

README.md

사용자가 읽을 수 있는 role의 기본 설명, 사용방법, 설명서, 예제, 작업하기 위해 보유할 수 있는 비 ansible 요구사항 등을 제공한다.

main.yml

위에서 명시한 각 디렉토리에 내용을 넣을 경우, 이 이름을 사용해서 넣는다. 각 파일의 내용에서 들여쓰기는 그냥 처음부터 시작한다.  해당 role을 참조하는 파일의 들여쓰기 수준만큼 쓰는 것이 아니다.

 

# 참고

- 여기 명시된 각 디렉토리의 이름은 바꾸면 안된다. 또한 그 아래의 yml파일도 main.yml 로 해야한다. 모두 동일하다.

- 이러한 디렉토리는 필수가 아니며, 필요한 디렉토리만 있으면 된다.

 

ansible role 사용시 보안 관련 유의사항

- role에는 사이트 특정 데이터가 포함되어 있으면 안된다.

- 암호나 개인 키 같은 비밀은 절대 포함하면 안된다. 민감한 값은 민감하지 않은 기본값을 사용해 변수로 매개변수화해야 한다.

- 사이트 특정 세부 사항을 하드코딩해서는 안된다.

- secret은 다른 수단을 통해 role에 제공해야 한다. role을 호출할 때 role 변수를 설정하는 이유 중 하나이다.

- play에 설정된 role 변수는 secret을 제공하거나 secret을 포함하는 ansible vault-encrypted 파일을 가리킬 수 있다.

 

 

ansible role의 효과를 극대화 하기 위한 제언

- 자체 버전 제어 리포지토리에서 각 role을 유지관리한다. ansible은 git 기반 리포지토리와 잘 맞는다.

- ansible-galaxy init을 사용하여 뼈대를 만들고, 이후 필요없는 디렉토리와 파일은 다 지운다.

- README.md, meta/main.yml 파일을 생성하고 유지관리하여 role이 무엇인지, 작성한 사람은 누구인지, 어떻게 쓰는지 등을 문서화한다.

- role은 특정 목적이나 기능에 집중한다. 하나의 role에 여러 기능을 넣는 것보다는 하나 이상의 role로 하나하나 기능을 넣는게 낫다.

- role을 자주 재사용하고 리팩토링한다. 한마디로 자주 새로고침하고 기존 플레이북에 문제가 발생하지 않도록 한다.

 

 

ansible role 사용하기 - 기본

ansible playbook에서 role을 사용하는 것은 아주 간단하다. 아래 예시대로 roles 지시자를 사용하면 된다.

---
- host: all
  roles:
    - role1
    - role2

 

이렇게 하면, 지정한 role1, role2 (이름임) 의 디렉토리에서 tasks, handler, vars 등 모든 내용들을 불러와서 해당 role을 실행한다.

 

role에서 cp, script, template 또는 import_task, include_task 등은 절대경로/상대경로, 이름이 없는 관련 파일, 템플릿 또는 작업 파일을 참조할 수 있다. ansible은 files, templates, tasks 하위 디렉토리에서 이러한 각각의 항목들을 찾는다.

 

 

role이 포함된 playbook에서 실행 순서 제어하기

role이 포함된 playbook에서 실행 순서를 제어하기 위해 2가지 지시자를 사용한다. pre_tasks, post_tasks

 

기본적으로 tasks의 내용은 roles에 있는 내용보다 늦게 실행한다. 특정 시나리오에서는 roles 실행 전에 일부 플레이 task를 실행해야 할 수도 있다. 이러한 시나리오를 지원하기 위해 pre_tasks 섹션으로 플레이를 구성할 수 있다. 이 섹션에 나열된 작업은 모든 role이 실행되기 전에 실행된다. 이러한 task 중 하나라도 핸들러가 트리거되면, 해당 핸들러의 task가 role 또는 일반 작업 전에 실행된다. 또한 post_tasks는 이러한 작업은 pre_tasks, tasks, roles가 모두 실행된 후에, 마지막으로 실행된다.

 

순서를 정리하면 다음과 같다.

 

1. pre_tasks에 정의된 play 및 handlers

2. roles에 정의된 roles, 만약 dependency가 정의되어있다면 해당 dependency가 해당 role보다 먼저 실행되고 role이 실행된다. 명시된 role 리스트들이 이렇게 순서대로 실행된다.

3. tasks에 정의된 play 및 handlers

4. post_tasks에 정의된 play 및 handlers

 

예시 (이렇게 모든 섹션이 다 있는 경우는 일반적으로 드물다)

---
- name: play to illustrate order of execution
  hosts: web.example.com

  pre_tasks:
    - debug:
        msg: 'pre-task'
      notify: my handler

  roles:
    - role1

  tasks:
    - debug:
        msg: 'first task'
      notify: my handler

  post_tasks:
    - debug:
        msg: 'post-task'
      notify: myhandler

  handlers:
    - name: my handler
      debug:
        msg: running my handler

위 예제에서 debug는 각 섹션에서 실행되어 my handler에 알린다. 즉 my handler는 3번 실행된다.

- 모든 pre_tasks 작업 실행 후

- 모든 role, 일반 tasks 작업 실행 후

- 모든 post_tasks 실행 후

 

 

 

playbook에 role을 포함하기

role은 단순히 플레이의 roles 섹션에 포함하는 것이 아닌 일반적인 작업을 사용하여 플레이에 추가할수도 있다. 이전에 설명한 playbook을 포함하는 것과 동일한 방식으로 두가지의 모듈을 사용한다.

- include_role 모듈을 사용하여 role을 동적으로 포함할 수 있다. (ansible 2.3에서 추가된 기능)

- import_role 모듈을 사용하여 role을 정적으로 가져올 수 있다. (ansible 2.4에서 추가된 기능)

 

* 예시

---
- name: execute a role as a task
  hosts: web.example.com
  tasks:
    - name: a normal task
      debug:
        msg: 'first task'
    - name: a task to include role2 here
      include_role: role2

 

 

 

role 생성 및 구성하기

role을 사용하는 process는 다음과 같다. 

1. role 디렉토리 구조 생성

2. role의 내용 정의

3. playbook에서 role 사용하기

 

 

* role 생성 및 구성 예시

 

1. role 디렉토리 구조 생성하기

ansible-galaxy 명령줄 도구에서 제공하는 ansible-galaxy init [role이름] 명령을 쓰면 디렉토리 구조를 자동으로 만든다.

 

2. role 내용 작성하기

 

<예시1>

이 role은 /etc/motd 파일을 관리하며 template 모듈을 사용해 /etc/motd 파일을 템플릿으로 배포한다.

 

tasks 디렉토리의 main.yml

templates 디렉토리의 motd.j2 (jinja2 템플릿 파일이므로 j2 사용)

defaults 디렉토리의 main.yml

 

<예시2>

이 role은 단순히 변수를 사용해보는 예제이다.

 

tasks 디렉토리의 main.yml

---
# tasks file for role1
- debug:
    msg: messages in role1 var1-{{var1}} var2-{{var2}}

 

vars 디렉토리의 main.yml

---
# variables for role1
var1: var1-role1
var2: var2-role1

(참고 : "var1-role1" 이게 하나의 값이다)

 

 

3. playbook에서 role 사용하기

 

<예시1을 사용하는 playbook>

- hosts: servera
  tasks:
    - debug:
            msg: "update /etc/motd"
  roles:
    - motd

 

<예시2를 사용하는 playbook>

- hosts: servera
  tasks:
    - debug:
            msg: "hello"
  roles:
    - role: role1
    - role: role2

- 예시2는 role1밖에 없지만, 여러개의 role을 사용할 수 있고 tasks와도 함께 사용할 수 있다는 것을 보여주는 것임. 

- role을 참조하는 playbook을 만들 때는, role의 기본 위치를 잘 파악해야 한다. 예시1은 해당 유저의 ~/.ansible/role/motd 에 해당 role 내용이 있어야 한다.

 

 

 

role 종속성 정의

특정 role에 다른 role을 종속성으로 포함할 수 있다. 종속성은 meta 디렉토리에 main.yaml에 정의한다. 아래와 같은 예시가 있을 수 있다. 아래처럼 정의하면, apache, postgres 두개의 role을 먼저 실행해야 해당 특정 롤을 실행하게 된다. 

meta/main.yaml

---
depenencies:
  - role: apache
    port: 8000
  - role: postgres
    dbname: serverlist
    admin_user: felix

기본적으로 role은 playbook에서 여러번 정의되어도 (dependency든 다른 playbook에서든) 여러번 실행하지 않는다. 한번만 실행한다. 아래처럼 정의되어있어도 foo role은 한번만 실행한다.

---
- hosts: webservers
  roles:
    - foo
    - foo

그렇지만 foo role의 meta/main.yml에다가 allow_duplicates: true를 넣으면 두 번 실행한다.

 

# 중요 : dependency 사용 시 주의

role에서 dependency를 복잡하게 사용했을 때 role의 유지 관리가 더 어려울 수 있다. 주의할 것.

 

 

 

 

 

role에서 변수를 참조하는 우선순위

- 아래 순서대로 높은순으로 우선순위가 높다.

 

 

1. role을 참조하는 yml파일에 특정 role을 명시할 때,그 role 과 같은 수준에서 명시한 변수

예시1
---
- name: use motd role playtbook
  hosts: web.example.com
  roles:
    - role: motd
      system_owner: someone@host.example.com


예시2
---
- hosts: servera
  roles:
    - role: role1
    - role: role2
      var1: var1
      var2: var2

- include_vars로 로드된 변수, register 변수 등은 이 1번과 같은 수준의 우선순위를 가진다.

- 원래 변수 기입 규칙은 vars: 지시자 아래에 넣지만, role과 같은 수전에서 명시한 변수에서는 vars: 밑이 아닌 그냥 바로 쓸 수 있다. (위 예시2 참고)

 

2. roles 디렉토리에 있는 특정 role의 vars 디렉토리에 명시된 변수

 

3. 해당 role을 참조하는 yml파일에 vars로 명시한 변수

---
- name: use motd role playbook
  hosts: web.example.com
  roles:
    - motd
  vars:
    system_owner: someone@host.example.com
  roles:
    - role: motd

- 아래 2가지 변수는 이 3번과 같은 수준의 우선 순위를 가진다.      

     - 인벤토리 파일에서 명시한 호스트 변수 또는 그룹 변수

     - 플레이북 프로젝트 내의 group_vars, host_vars 디렉토리 아래의 yaml파일

 

4. defaults : roles의 defaults 디렉토리에 명시된 변수. 가장 우선순위가 낮다.

 

 

 

# 참고예시 : role을 명시한 playbook에서 변수 처리

예를들어, 아래 예제는 2개의 role과 role 변수에 대한 값을 설정한다. role 1은 이전 예제와 같은 방식으로 사용된다. role2가 사용될때는 var1,var2가 적용되어 재정의된다.

---
- hosts: all
  roles:
    - role: role1
    - role: role2
      var1: val1
      var2: val2

 

 

 

ansible role을 찾는 경로

 

기본적으로 ansible은 ansible 플레이북을 포함하는 디렉토리의 roles 라는 하위 디렉토리에서 role을 찾는다. 이를 통해 playbook및 기타 지원 파일과 함께 role을 저장할 수 있다. 19장의 ansible-galaxy에서 다운받는 role도 기본적으로 아래 경로를 사용한다.

 

기본 경로 : ~/.ansible/roles

 

ansible이 기본 경로에서 role을 찾을 수 없는 경우, 아래 순서대로 ansible 구성 설정인 role_path에서 지정한 디렉토리에서 찾는다.

 

1. ~/.ansible/roles : 특정 유저에게 role 설치할 때 사용

2. /usr/share/ansible/roles  : 모든 사용자에 대해 role을 설치할 때 사용

3. /etc/ansible/roles

 

ansible role의 default path를 변경하려면 아래와 같이 2가지 방법을 사용할 수 있다.

 

1. 임시 변경

해당 유저의 ansible role 경로를 임시로 변경한다. 해당 유저를 logout 하면 이 설정은 사라진다.

구문 : export ANSIBLE_ROLES_PATH=원하는경로
예시 : export ANSIBLE_ROLES_PATH=/tmp/roles

 

2. 영구 변경

특정 유저의 .bashrc 파일, 또는 전체 유저에 대해서는 /etc/bashrc 파일에 아래 내용을 포함한다.

ANSIBLE_ROLES_PATH=원하는경로

또는 특정 디렉토리 기준이라면 ansible.cfg에 roles_path 항목을 설정한다.

 

 

role 예시 - vhost httpd를 만드는 role 생성

 

1. 디렉토리 생성

- 아래 경로대로 myvhosts 디렉토리를 생성한다.

mkdir -pv ~/role-create/roles/myvhosts 

 

2. myvhosts 디렉토리 안에 tasks 디렉토리를 만들고, main.yml 파일을 생성한다.

---
- name: ensure httpd is installed
  yum:
     name: httpd
     state: latest
- name: ensure httpd is started and enabled
  service:
     name: httpd
     state: started
     enabled: true
- name : vhost file is installed
  template:
     src: vhost.conf.j2
     dest: /etc/httpd/conf.d/vhost.conf
     owner: root
     group: root
     mode: 0644
  notify:
     - restart httpd
- name: html content is installed
  copy:
     src: html/
     dest: "/var/www/vhosts/{{ansible_hostname}}"

* 설명

- httpd 서비스를 최신으로 설치

- httpd 서비스를 시작하고 활성화

- vhost.conf.j2 템플릿을 /etc/httpd/conf.d/vhost.conf 파일로 복사 및 오너쉽 등 수정

- 템플릿이 수정되면, httpd를 자동으로 재시작

- html/ 디렉토리 안에 있는 모든 내용을 /var/www/vhosts/호스트명 으로 복사

 

 

3. myvhosts 디렉토리 안에 handlers 디렉토리를 만들고, main.yml 파일을 생성한다.

---
- name: restart httpd
  service:
     name: httpd
     state: restarted

* 설명

- httpd를 재시작한다.

 

 

4. myvhosts 디렉토리 안에 files/html 디렉토리를 만들고, index.html 파일을 원하는 대로 생성해서 넣는다.

 

5. myvhosts 디렉토리 안에 templates 디렉토리를 만들고, vhosts.conf.j2 파일을 넣는다.

 

6. myvhosts role을 실행할 yml 파일을 생성한다.

vi use-vhost-role.yml

---
- name: use myvhost role playbook
  hosts: web.example.com
  pre_tasks:
     - name: pre_tasks messages
       debug:
          msg: 'ensure web server configuration.'
  roles:
     - myvhost
  post_tasks:
     - name: post_tasks messages
       debug:
          msg: 'web service is configured.'

 

7. 특정 서비스에 대한 방화벽을 허용하는 role을 생성한다.

mkdir -pv ~/role-create/roles/myfirewall

 

8. myfirewall 디렉토리 안에 tasks 디렉토리를 만들고, main.yml 파일을 생성한다.

---
- name: ensure firewalld is installed
  yum:
     name: firewalld
     state: latest

- name: ensure firewalld is started and enabled
  service:
     name: firewalld
     state: started
     enabled: true

- name: ensure firewalld services are enabled
  firewalld:
     state: enabled
     immediate: true
     permanent: true
     service: "{{ item }}"
  loop: "{{ firewall_services }}"

 

9. 변수 기본값들을 정의하기 위해 myfirewall 디렉토리 안에 defaults라는 디렉토리에 main.yml 파일을 정의한다.

---
# defaults file for myfirewall

# by default, no firewall services are enabled.
# firewall_services: []
#
# to enable, for example, FTP and HTTP service in firewalld
# use the following definition for "firewall_services"
# firewall_services:
#   - http
#   - ftp
firewall_service: []

이렇게 firweall_services: [] 대괄호로 묶어서 아무것도 없게 하면, 빈 목록이 되며 이로 인해 기본적으로 role이 포트를 열지 않는다. 이제 사람들이 여기 나와있는 주석 예시대로 원하는 서비스를 아래에 명시하면 된다.

 

10. webservers라는 그룹에서만 조건에 맞는 firewall_service 변수를 넣기 위해 그룹 변수를 명시한다.

- role-create 디렉토리에서 group_vars/webservers 디렉토리를 생성한다.

mkdir -pv group_vars/webservers

- 이 디렉토리 안에 myfirweall.yml 파일을 만들고 아래와 같이 명시한다.

---
firewall_services:
  - http

 

11. myvhosts의 role이 실행되기 전에 myfirewall role을 먼저 실행하도록 dependnecy를 정의한다.

- myvhosts 디렉토리에 meta 디렉토리를 만들고, main.yml을 생성하고 아래와 같이 정의한다.

dependencies:
   - role: myfirewall

- 이  meta/main.yml 파일에는 선택적으로 galaxy_info 변수의 author, company, description, license 필드도 업데이트 할 수 있다.

 

12. 실행

ansible-playbook use-vhost-role.yml

- dependency role은 자동으로 실행되므로 이 메인 yml파일만 실행하면 전체가 실행된다.

 

 

 

 

참고링크

 

role 및 ansible 설명서

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_reuse_roles.html#using-roles

 

Roles — Ansible Documentation

You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansible documentation. Roles are ways of automati

docs.ansible.com

 

변수 및 ansible 설명서

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_variables.html

 

Using Variables — Ansible Documentation

Docs » User Guide » Working With Playbooks » Using Variables You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version.

docs.ansible.com

 

 

 

 

플레이북이 길어지거나 복잡한 경우, 더 작은 파일로 나누면 관리하기가 좋다.  모듈식으로 여러개의 플레이북을 하나의 메인 플레이북에 결합하거나 파일의 작업 목록을 플레이에 삽입할 수 있다. 이런식으로 사용하면 일련의 프로젝트에서 play를 재사용하기 쉬워진다.

 

 

개념이해 : 가져오기, 포함하기

ansible에서 파일이나 role 등을 특정 playbook에서 읽어들일 때, import / include 2가지 방법이 있으며 이 방법은 약간의 차이가 있다.

 

* import : static re-use

role, task, playbook 등을 플레이북에 정적으로(statically) 삽입한다. ansible은 playbook을 처음 구문분석할 때 읽어들인 파일이나 role 등을 최상위 플레이북에서 작업을 실행하기 전에 사전처리한다. 따라서 imported 된 내용들은 최상위 플레이북의 다른 task에 영향을 받지 않는다.

 

* includes : dynamic re-use

role, task, 변수 등을 플레이북에 동적으로(dynamically) 삽입한다. Ansible은 file, role을 playbook에서 읽어들일 때 그것들을 include(포함)한다. included 된 컨텐츠는 최상위 플레이북의 이전 작업의 결과에 영향을 받는다. included 된 role 이나 task는 핸들러와 비슷하다. 그것들은 최상위 플레이북의 다른 task의 결과에 따라 실행될수도 있고 실행되지 않을수도 있다.

 

playbook 가져오기 - import_playbook

- play 목록이 포함된 외부 파일을 playbook으로 가져온다. (정적; static)

- 즉 특정 마스터 playbook에서 한 개 이상의 추가 playbook 자체를 가져오는 것이다.

- 가져오는 컨텐츠가 완전한 playbook이므로 import_playbook 지시문은 playbook의 최상위 수준에서만 사용하고, play 내에서는 사용할 수 없다.

- 여러개의 playbook을 가져오는 경우, 가져오는 순서대로 실행한다.

 

* 예시 : 두개의 추가 플레이북을 가져오는 마스터 플레이북

- 그냥 플레이북에 내용이 없고, 아래 두개만 딱 있음. 이것도 플레이북이다.

---
- name: prepare the web server
  import_playbook: web.yml
  
- name: Prepare the database server
  import_playbook: db.yml

 

* 예시 : 일반적인 플레이북에 import_playbook 추가

- name: play 1
  hosts: localhost
  tasks:
    - debug:
        msg: play 1
        
- name: import playbook
  import_playbook: play2.yml

- 위에서부터 순서대로 실행한다.

 

 

task 가져오기 - import_tasks

task 내용이 있는 파일을 import 방식으로 가져올 있다. 반복문은 import_task 함께 사용할 없다. 또한 변수를 사용하여 가져올 파일 이름을 지정할 , 호스트/그룹 인벤토리 변수를 사용할 없다.

 

* 예시

- name: install web server
  hosts: webservers
  tasks:
    - import_tasks: webserver_tasks.yml

 

task 포함하기 - include_tasks

task 내용이 있는 파일을 include 방식으로 가져올 있다.

 

* 예시

---
- name: install web server
  hosts: webservers
  tasks:
    - include_tasks: webserver_tasks.yml

 

 

파일을 따로 만들어서 쓰는 사용 사례

- 특정 일련의 작업을 playbook과 별도로 외부 파일로 관리하는 것이 유용할 수 있는 경우에 대해, 다음 예시를 참고한다.

 

1. 새 서버에 완전한 구성이 필요한 경우, 관리자는 사용자 생성, 패키지 설치, 서비스 구성, 권한 구성, 공유 파일시스템에 대한 액세스 설정, 서버 강화, 보안 업데이트 설치, 모니터링 에이전트 설치 등을 위해 여러 세트의 작업을 생성할 수 있다. 이러한 각 작업 세트는 별도의 자체 포함 작업 파일을 통해 관리할 수 있다.

2. 서버를 개발자, 시스템 관리자 및 데이터베이스 관리자가 전체적으로 관리하는 경우 모든 조직은 시스템 관리자가 검토하고 통합할 고유한 작업 파일을 작성할 수 있다.

3. 서버에 특정 구성이 필요한 경우 조건에 따라 (즉, 특정 조건을 충족하는 경우에만 작업 포함) 실행할 작업 세트로 통합할 수 있다.

4. 서버 그룹에서 특정 작업 또는 작업 세트를 실행해야 하는 경우 서버가 특정 호스트 그룹의 일부이면 작업을 서버에서만 실행할 수 있다.

 

* 작업 파일 관리하기

- 작업 파일을 관리할 때는, 작업 파일 전용 디렉토리를 생성하고 이 디렉토리에 모든 작업 파일을 저장할 수 있다.

- 그 후 해당 디렉토리에서 작업 파일을 간단하게 포함하거나 가져올 수 있다. 

- 참조되는 yml파일들은 메인파일의 들여쓰기에 맞출 필요 없이 맨 첫라인에서 자신의 들여쓰기 수준에 맞춰 작성하면 된다. 한마디로, 그냥 하면 된다.

 

 

 

재사용하기 좋게 만들기

- 위에서 언급한 가져오기, 포함하기 기능이 있기 때문에 playbook과 작업 파일을 재사용 할 수 있게 잘 만드는게 매우 중요해졌다.

- 재사용 가능성을 극대화하려면, 이러한 task와 play 파일을 최대한 일반화 해야한다.

- 변수를 사용하여 play 및 task 의 요소를 매개변수화하여 유연하게 사용할 수 있다.

 

<import tasks 관련 예시>

 

* 예시1 : 어떤 패키지든 명시해서 최신으로 설치, 서비스 시작, enable까지 수행하는 일반화된 task 파일

package_task.yml

---
- name: install the {{ package }} packge.
  yum:
    name: "{{ package }}"
    state: latest

- name: start the {{ service }} service.
  service:
    name: "{{ service }}"
    enabled: true
    state: started

* 예시2 : 위 task 파일을 메인 playbook에 포함하여 사용하기

---
- name: work
- hosts: all
- tasks: 
    - name: import task file ans set variables
      import_tasks: package_task.yml
      vars:
        package: httpd
        service: httpd

- 이렇게 하고, vars의 package: httpd, service: httpd 두가지 부분을 변수파일로 받아서 for 문을 돌릴수도 있다.

- 결국 이 파일이 최종적으로 내가 원하는 패키지들을 명시하는 구문이고, 위 예시는 명시한 패키지들을 설치하는 구문이 된다.

 

 

 

 

<import_playbook 관련 예시>

 

* 예시 : 일반화된 플레이북을 포함해서 사용하는 플레이북

- name: import play file and set the variable
  import_playbook: play.yml
  vars:
    package: mariadb

- 위 import tasks 관련 예시의 2번과 같은 맥락으로, 일반화되어 잘 만들어진 플레이북에 변수 mariadb만 적용하는 플레이북이다. 

 

 

# 참고

이전 버전의 ansible에서는 버전을 올리면서 include 라는 지시자가 정적 가져오기, 동적 가져오기 등으로 변경되었었는데 문제가 많았음. 그래서 2.4부터 include는 include_tasks, import_tasks, import_playbook 같은 새로운 지시문으로 대체되었다. 이제는 include 지시문을 쓰면 안된다. 다른 playbook을 볼 때 include라는 지시자를 볼 수도 있으니 참고만 할 것.

 

 

 

연습문제

- playbook 마스터파일1개, play파일 1개, task파일 3개가 있고, 마스터파일을 기준으로 각각의 play,task파일을 import하는 예시

 

 

playbook.yml (전체 마스터 파일)

# 메인 마스터 playbook 파일
---
- name: configure web server
  hosts: was.example.com
  tasks:

# 패키지 설치 및 서비스를 시작, enable을 수행하는 task 파일 삽입
    - name: import the environment task file ans set the variables
      import_tasks: environment.yml
      vars:
        package: httpd
        service: httpd
        
# 방화벽 소프트웨어를 설치 및 구성하는 task 파일 삽입
    - name: import the firewall task file and set the variable.
      import_tasks: firewall.yml
      vars:
        firewall_pkg: firewalld
        firewall_svc: firewalld
        rule: http

# 웹페이지 파일을 생성하는 task 파일 삽입
    - name: import the placeholder task file and set the variable
      import_tasks: placeholder.yml
      vars:
        file: /var/www/html/index.html

# 모든 작업 수행 후, 제대로 작동하는지 테스트하는 playbook 파일 삽입
- name: import test play file and set the variable
  import_playbook: test.yml
  vars:
    url: 'http://web1.example.com'

 

environment.yml (패키지 설치 및 서비스 시작, enable 수행)

---
  - name: install the {{ package }} packge.
    yum:
      name: "{{ package }}"
      state: latest
        
  - name: start the {{ service }} service.
    service:
      name: "{{ service }}"
      enabled: true
      state: started

 

firewall.yml (방화벽 소프트웨어 설치 및 구성)

---
  - name: Install the firewall
    yum:
      name: "{{ firewall_pkg }}"
      state: latest
  
  - name: start the firewall
    service:
       name: "{{ firewall_svc }}"
       enabled: true
       state: started
  
  - name: openm the port for {{ rule }}
    firewalld:
       service: "{{ rule }}"
       immediate: true
       permanent: true
       state: enabled

 

placeholder.yml (웹사이트 파일 생성)

--- 
  - name: create placeholder file
    copy:
      content: "{{ ansible_facts['fqdn'] }} has been customized using ansible. \n"
      dest: "{{ file }}"

 

test.yml (웹사이트 연결 테스트)

---
  - name: test web service
    hosts: localhost # was.example.com 자기 자신에 대해서 수행하는 것
    become: no
    tasks:
      - name: connect to internet web server
        uri:
          url: "{{ url }}"
          status_code: 200

 

결과

- 모두 changed 뜨고, (firewalld은 이미 start되어있는 서버였음) 웹페이지 내용도 잘 확인할 수 있다.

 

 

 

참조링크

 

import_tasks와 include_tasks 간의 작동 차이점

https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html#applying-when-to-roles-imports-and-includes 

 

Conditionals — Ansible Documentation

In a playbook, you may want to execute different tasks, or have different goals, depending on the value of a fact (data about the remote system), a variable, or the result of a previous task. You may want the value of some variables to depend on the value

docs.ansible.com

포함하기 및 가져오기 ansible 설명서

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_reuse_includes.html 

재사용 가능한 플레이북 만들기 ansible 설명서

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_reuse.html

 

Creating Reusable Playbooks — Ansible Documentation

Docs » User Guide » Working With Playbooks » Creating Reusable Playbooks You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintain

docs.ansible.com

조건문 ansible 설명서

https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html 

 

Conditionals — Ansible Documentation

In a playbook, you may want to execute different tasks, or have different goals, depending on the value of a fact (data about the remote system), a variable, or the result of a previous task. You may want the value of some variables to depend on the value

docs.ansible.com

 

ansible에서 playbook 처리 루틴 이해

- ansible에서 playbook을 처리하면, 순서대로 각 play를 실행한다. 일반적으로 클라이언트가 플레이에서 다음 작업을 시작하기 전에, 모든 클라이언트가 작업을 성공적으로 완료해야 한다.

- 이론상으로는 ansible이 play실행 시 각 작업의 모든 클라이언트에 동시에 연결할 수 있다. 이것은 소규모의 경우 잘 작동한다. 하지만 play가 수백개의 호스트를 대상으로 하는 경우, 제어노드에 많은 부하가 걸릴 수 있다.

- ansible이 만드는 최대 동시 연결 수는 ansible 구성 파일에서 forks 매개 변수로 제어할 수 있다. 이 값의 default는 5이다.

- 예시 : 만약 play에 10개의 클라이언트가 있다면 ansible은 처음 5개의 클라이언트에 대해 첫번째 play 작업을 끝내고, 그 다음 다른 5개의 클라이언트의 첫번째 play작업을 두번째로 실행한다. 이런식으로 여러개의 클라이언트에 대해 play가 끝날때까지 이 작업을 수행한다.

 

forks 지시문 사용하기

- forks 지시문은 ansible.cfg의 [defaults] 섹션에 명시한다.

- forks = 20 이런식으로 사용.

- ansible.cfg에 설정하지 않았더라도, 명령행의 ansible, ansible-playbook 명령 각각에서 -f / --forks 옵션을 사용해 forks 수를 지정할수도 있다.

 

- play는 순서대로지만, 해당 play가 실행되는 클라이언트들은 하나가 아닌 여러개면 순서가 따로 정해진 게 아니라 fork 수만큼 한번에 명령을 전달하며, 응답한 순서대로 결과를 출력한다. 따라서 출력 결과는 항상 다를 수 있다.

- 예를들어 example1~4 호스트가 있다면, ping 모듈을 써서 명령을 쳤을 때 4가 먼저 나올수도 있고 2가 먼저 나올수도 있다.

 

 

 

ansible host (제어 노드)의 부하

- ansible host가 리눅스 클라이언트들을 관리하는 경우, 대부분 작업은 클라이언트에서 실행되므로 ansible host는 로드가 적다. 이 경우에는 일반적으로 forks는 높은 값으로(100 전후) 설정하면 성능이 향상되는 것을 볼 수 있다.

- ansible host가 네트워크 라우터,스위치 등을 관리하면 대부분의 모듈이 ansible host에서 실행되기 때문에 ansible host의 부하가 심하다. 리눅스 클라이언트와 비교했을 때 지원 가능한 forks의 수가 현저히 낮을 수 있다.

- 다시 정리하면, 어떤 환경이든 ansible host의 부하가 심할 수 있다면 forks 값을 적절히 조절해야 한다. 

 

 

play 실행 구조의 문제점과 롤링 업데이트

위에서 언급한 대로, ansible이 play를 실행하면, 모든 클라이언트가 해당 play를 완료해야만 다음 작업으로 넘어간다. 또한 모든 클라이언트가 모든 작업을 완료한 후에는 알림을 받은 핸들러가 실행된다.

 

그런데 이렇게 하면 문제의 여지가 있다. 예를 들어, 하나의 플레이가 부하 분산된 웹 서버 클러스터를 업데이트 한다면, 업데이트 하면서 웹 서버 클러스터 안의 모든 웹서버들이 다 다운타임을 갖게 된다. 따라서 클러스터임에도 서비스가 중지된다.  따라서 ansible에서 한번에 작업을 다 하지 않고 rolling으로 작업할 수 있는 구문이 필요하다.

 

 

serial 지시문

하나의 play에 모든 클라이언트이 한번에 작업이 완료되어야 하지 않도록, serial이라는 키워드를 사용할 수 있다. serial 지시문을 2로 설정하면, 예를들어 hosts에 명시된 클라이언트가 6개인 경우, 2개의 클라이언트에 대해 play를 실행하고, 핸들러까지 실행해서 모두 다 완료한다. 그 후에 그 다음 2개의 클라이언트에 대해 또 동일하게 진행하고 또 그 다음 남은 2개의 클라이언트에 대해 동일하게 진행한다.

 

* 예시

---
- name: rolling update
  hosts: webservers
  serial: 2
  tasks:
    - name: ....

- 이런 방식으로 사용된다. 또한 개수(숫자)가 아닌 백분율로도 지정할 수 있다. 이 백분율은 클라이언트의 갯수에 적용된다. 

 

* 예시 결과

- 클라이언트가 5개이고, serial: 2 로 설정하면, 아래와 같이 2개씩 나눠서 따로따로 수행하는것을 확인할 수 있다.

 

 

# 참고 : 에러가 발생하는 경우

- serial: 2로 했을 때 첫번째 2개가 실패하면, 플레이북이 중지되고 이후 남은 4개는 아예 실행되지 않는다.

 

 

 

결론

전체적으로 간단하게 정리하면, 다음과 같다.

- forks : ansible이 만드는 최대 동시 연결 수.

- serial : 한번에 play를 실행할 호스트 수

 

 

 

 

 

 

참조 링크

 

롤링 업데이트 배치 크기, 위임, 롤링 업데이트 및 로컬 작업 ansible 설명서

docs.ansible.com/ansible/2.7/user_guide/playbooks_delegation.html#rolling-update-batch-size

 

Delegation, Rolling Updates, and Local Actions — Ansible Documentation

You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansible documentation. Being designed for multi-t

docs.ansible.com

 

ansible 성능 튜닝

https://www.ansible.com/blog/ansible-performance-tuning

 

ansible에서 템플릿 사용과 jinja2 소개

ansible에서 기존 파일의 내용을 수정하는데에는 여러 모듈을 쓸 수 있다. (lineinfile, blockinfile 등) 이것들은 단순 수정하는데는 좋지만, 어떤 규칙에 의해 체계적으로 관리하는 파일에서 쓰기에는 부족하다. 

 

파일을 관리하는데 더 훨씬 강력한 방법은 템플릿을 지정하는 것이다. 템플릿은 파일이 배포될 때 ansible client에 대해 ansible 변수 및 팩트변수를 사용해 자동으로 지정되는 템플릿 파일을 작성할 수 있다. 이것은 제어하기 더 쉽고 오류 발생률이 낮다.

 

ansible에서는 템플릿파일용으로 jinja2라는 템플릿 시스템을 사용한다.  jinja2는 위에서 말한 템플릿을 사용하는데 쓰기도 하지만, playbook에서 변수를 참조하고 여러가지 확장된 사용을 가능하게 한다.

 

jinja2 템플릿 구문 사용하기

- jinja2 템플릿은 데이터, 변수, 식 등 여러 요소로 구성되는데, 이러한 변수와 식은 jinja2 템플릿이 랜더링되면(jinja2문법이 번역되어 실행되면) 해당 값으로 변경된다. 

- 템플릿에 사용하는 변수는 playbook의 vars 섹션에서 지정할 수 있다.

- 템플릿에 해당 ansible client의 팩트변수를 사용할 수 있다.

- jinja2의 기본적인 사용은 {{ }} , {% %} , {# #} 3가지 방법이 있다.

     - {{ }} : 식/변수 결과를 최종 사용자에게 출력

     - {% %} : 식 또는 논리(반복문 등)에 사용

     - {# #} : 주석

- jinja2 템플릿이 들어있는 파일에는 따로 확장명이 필요 없다. 하지만 .j2 이런식으로 확장명을 제공하면 템플릿인지 쉽게 알 수 있다.

 

 

* template 모듈

- 기본적인 핵심 기능은 ansible host에 있는 파일을 ansible client에 배포하는 것이다. 하지만 같은 기능을 하는 모듈은 많으므로 일반적으로 jinja2 템플릿 파일을 배포하는데 사용된다.

- template 지시문을 사용하며, src는 ansible host에 있는 배포"할" 템플릿 소스파일의 경로, dest는 ansible client에서 해당 파일을 받을 경로이다.

- template 모듈은 file 모듈과 같이 배포된 파일의 소유자, 그룹, 권한, selinux 컨텍스트 등을 지정할 수 있다.

- template 모듈과 copy 모듈은 비슷하지만 다른점은, template는 파일 안에 변수 등이 있으면 그걸 랜더링해서 보여준다.

- 또한 validate 옵션으로 임의의 명령(visudo -c 같은)을 실행해 파일을 올바른 위치에 복사하기 전에 구문검사를 수행할 수 있다. 자세한 내용은 ansible-doc template 명령의 validate 부분 참고할 것

 

 

* 예시 : ansible client의 팩트변수로 템플릿 생성하기

 

템플릿 파일

vi test.j2
Welcome to {{ ansible_facts.hostname }}.
Today's date is : {{ ansible_facts.date_time.date }}.

플레이북 파일

- name: jinja2 test
  hosts: web.example.com
  tasks:
    - name: jinja2 template
      template:
        src: /home/devops/ansible_test/test.j2
        dest: /tmp/jinja-test-result
        owner: root
        group: root
        mode: 0644

결과

이렇게 하면, ansible host에는 템플릿파일플레이북파일을 사용하여 특정 ansible client에 결과파일을 만들어 내는 작업을 할 수 있는 것이다. 이렇게 간단하게 배포가 가능하다.

 

 

* 템플릿 파일에 관리자용 주석 달기

- 관리자가 template으로 만든 결과파일에 대해 수정하지 않도록 요구하거나 특별한 주석을 달고 싶을때, 아래와 같이 주석을 달 수 있다.

- 여러 방법이 있지만 가장 간단한 방법은, ansible.cfg의 [defaults] 섹션에 ansible_managed = 라는 부분을 추가하는 것이다.

- 아래 예시를 참고한다.

- 이렇게 구성해둔 후, 템플릿 파일에는 아래와 같이 {{ ansible_managed }} 라는 값을 맨 위에 추가해준다.

- 결과는 다음과 같다.

 

 

jinja2 제어구조 - 반복문

템플릿 파일에서도 제어구조인 반복문, 조건문 등을 사용할 수 있다.

 

* 반복문 사용하기

- for 문을 사용하여 반복문을 쓸 수 있다. 

- 기본 구문은 다음과 같다.

{% for user in users %}
	{{ user }}
{% endfor %}

- 이 구문에서 user 변수는 users 변수에 포함된 모든 값으로 대체되게 된다. 즉 리스트만 제공하면 알아서 그 리스트에서 변수를 하나씩 넣는다는 것이다.

 

 

* 반복문 예시1 - 직접 jinja2 템플릿에 변수를 정의하여 사용

vi template1.js

{% set numbers = [1,2,3,4,5,6,7,8,9,10] %}
{% for number in numbers %}
The number is {{ number }}
{% endfor %}


vi jinja2-template1.yml 

---
- hosts: all
  remote_user: devops
  become: true
  tasks:
    - template:
        src: jinja2.j2
        dest: /tmp/jinja2
        owner: root
        group: root
        mode: 0644

 

* 반복문 예시2  - 플레이북에서 직접 정의한 변수 사용

vi template2.js

{% for number in numbers %}
The number is {{ number }}
{% endfor %}

vi jinja2-template2.yml 

---
- hosts: all
  vars:
    numbers: 
      [1,2,3,4,5,6,7,8,9,10]
  remote_user: devops
  become: true
  tasks:
    - template:
        src: jinja2.j2
        dest: /tmp/jinja2
        owner: root
        group: root
        mode: 0644
로그인할 때 출력하는 motd파일 수정

vi motd.j2

this is the system {{ ansible_hostname }}.
today date is : {{ ansible_date_time.date }}.
only use this system with permission.
you can ask {{ system_owner }} for access.


vi motd.yml

---
- hosts: all
  vars:
    system_owner: clyde@example.com
  tasks:
    - template:
        src: motd.j2
        dest: /etc/motd
        owner: root
        group: root
        mode: 0644
로그인시 시스템 메모리 상태를 보여주기

vi motd2.j2

this system total memory is: {{ ansible_memtotal_mb }} MBs.
this current free memory is: {{ ansible_memfree_mb }} MBs.


vi motd2.yaml

---
- hosts: all
  remote_user: devops
  become: true
  tasks:
    - template:
        src: motd2.j2
        dest: /etc/motd
        owner: root
        group: root
        mode: 0644

- 참고로, 변수를 날짜로 하면 랜더링 할때만 날짜가 갱신되므로 이미 템플릿의 결과로 생성된 날짜는 고정되며 변동되지 않는다. 따라서 날짜를 표현하는데는 효과적이지 않다.

 

* 반복문 예시 - 매직변수 & 팩트 변수 사용

- 인벤토리의 모든 클라이언트를 대상으로 ip주소 확인하기

- groups 매직변수와 hostvars 매직변수를 사용한다. hostvars 매직변수에는 ansible_facts 변수가 포함된다. (gathring을 해야만 포함된다. gathering을 하지 않으면 포함되지 않는다)

gethring_ip.j2

{% for host in groups['all'] %}
HOST {{ hostvars[host]['ansible_facts']['hostname'] }} IPADDR : {{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }}
{% endfor %}

gathering_ip.yml

- name: jinja2 test
  hosts: all
  tasks:
    - name: jinja2 template
      template:
        src: /home/devops/ansible_test/template.j2
        dest: /tmp/jinja-template-test

# 참고 : 매직변수, 팩트변수 사용 시 참고

- 이렇게 여러개의 ansible host를 대상으로 팩트변수를 얻는 구문을 쓸 때는 ansible-playbook 여기에도 해당 호스트를 동일하게 명시해줘야 한다.

- 동일하게 명시하지 않으면 팩트변수가 제대로 수집되지 않아 에러가 발생한다.

- 예를들어, playbook에서는 web.example.com 하나만 했는데, 템플릿에서는 for 문으로 모든 클라이언트를 지정하면 안된다.

 

 

* loop.index

- loop.index는 반복을 1번 돌때마다 숫자 1을 증가시킨다. 즉 반복의 횟수를 보여준다.

{% for host in groups['all'] %}
HOST {{ hostvars[host]['ansible_facts']['hostname'] }} IPADDR : {{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }}
{{ loop.index }}
{% endfor %}

 

- 반복의 횟수에 따라 특정 구문을 실행하도록 할 때 사용할 수도 있고, 여러 방면에서 활용 가능하다.

 

 

 

jinja2 제어구조 - 조건문

템플릿 파일에서도 제어구조인 반복문, 조건문 등을 사용할 수 있다.

 

* 조건문 사용하기

- if 문을 사용하여 조건문을 만들 수 있다.

- 기본 구문은 다음과 같다.

{% if 조건문 %}
조건이 true인 경우 실행할 내용
{% endif %}

 

* 조건문 간단한 예시

- finished 변수의 값이 true일때만 result변수의 값을 찍어낸다.

{% if finished %}
{{ result }}
{% endif %}

 

# 참고 : 조건문과 반복문을 함께 사용할수도 있다.

{# for statement #}
{% for myuser in users if not myuser == "root" %}
User number {{loop.index}} - {{myuser }}
{% endfor %}

 

# 참고 : 템플릿에서는 jinja2 반복문과 조건문을 쓸 수 있지만, ansible-playbook에서는 사용할 수 없다.

 

 

 

변수 필터

- jinja2 에서는 템플릿 식에 대한 출력 형식을 변경할 수 있다. 이것을 필터라고 한다.

- 출력 형식은 yaml, json 등이 있다.

- 아래와 같이 여러 방식이 있으며, 필요한 방식대로 사용할 수 있다.

 

* 예시

vi template.j2

{{ hostvars['web.example.com'] | to_nice_json }}

- 이렇게 하면, hostvars['web.example.com']의 결과에 대해 to_nice_json 필터를 적용하는 것이다.

 

 

* 각 필터의 결과 예시

 

to_json : json 형식으로 보여준다.

 

to_yaml : yaml 형식으로 보여준다.

 

to_nice_json : json형식을 사람이 보기 편하게 보여준다.

 

to_nice_yaml : yaml 형식을 사람이 보기 편하게 보여준다.

 

 

 

 

참고 링크

 

jinja 테스트 ansible 설명서

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_tests.html 

 

Tests — Ansible Documentation

You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See the latest Ansible documentation. Tests in Jinja are a way o

docs.ansible.com

 

템플릿 - 원격 서버로 파일을 출력하는 템플릿 ansible 설명서

https://docs.ansible.com/ansible/2.7/modules/template_module.html 

 

template – Templates a file out to a remote server — Ansible Documentation

Docs » template – Templates a file out to a remote server You are reading an unmaintained version of the Ansible documentation. Unmaintained Ansible versions can contain unfixed security vulnerabilities (CVE). Please upgrade to a maintained version. See

docs.ansible.com

변수 ansible 설명서

https://docs.ansible.com/ansible/2.7/user_guide/playbooks_variables.html 

필터 및 ansible 설명서

https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html 

 

+ Recent posts