Ansible

Ansible Template 활용하기

Joon0464 2021. 7. 24. 18:17

https://www.inflearn.com/course/ansible-%EC%8B%AC%ED%99%94/lecture/10808?tab=curriculum&speed=1.25 

 

[심화] 앤서블(Ansible)을 깊이 있게 활용하기 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

j2 = jinja2

파이썬에서 템플릿을 위해 정의된 엔진이다.

따라서, 파이썬으로 짜여진 Ansible 그리고 SaltStack에서 적극적으로 차용한다.

{%...%} : 제어가 들어가는 라인 -> with_Item, when, if

{{ ... }} : 표현식(문)이 들어가는 구문 -> {{ 변수 }}

{#...#} : 주석 표시

 

 

Example 1

Template을 활용하여 모든 노드의 /etc/hosts에 각 노드와 서버의 호스트 네임을 추가하기

# vi hots_template.yml

---
- name: Create hosts file by template
  hosts: nodes
  become: yes
  vars:
    nu: "{{ groups['nodes'] | count }}"

  tasks:
  - template:
      src: hosts.j2
      dest: /etc/hosts

위 플레이북은 /etc/hosts에 호스트 이름을 모든 노드에 등록하기 위한 것이다.

group['nodes']는 /etc/ansible/hosts에 index 값에 따라 실제 IP 값이 등록되어있다.

/etc/ansible/hosts에 등록된 값

# vi hosts.j2

#Create by Template at {{ ansible_date_time.iso8601 }}

127.0.0.1 {{ ansible_hostname }}
192.168.1.10 ansible-server
{% for ip in range(nu | int) %}
{{ groups['nodes'][ip] }} node{{ groups['nodes'][ip][-3:] }}
{% endfor %}

- {{ ansible_date_time.iso8601 }}

  • 생성 시간을 기록하는 표현식, ansible의 facts 값에서 가져오는 값이다.

- 127.0.0.1 {{ ansible_hostname }}

  • 루프백 IP에 현재의 호스트 이름을 가지도록 설정, ansible의 facts 값에가 가져온 값

- 192.168.1.10 ansible-server

  • 192.168.1.10을 ansible-server 값과 맵핑하기 위한 하드 코딩

- {% for ip in range(nu | int) %} 

  • jinja2의 제어문인 for문을 사용함, ip는 변수값을 선언한 것임,
  • in은 반복을 선언하는 구문으로 in 뒤에 있는 리스트 형식의 객체 내의 개수를 세어 그 만큼 반복해준다.
  • nu는 hosts_template.yml의 선언된 변수에서 가져오는 값이다. hosts_template.yml에서 nu는 정수값이지만 넘어올 때 문자로 바뀌게 되므로 다시 int를 사용하여 정수형으로 전환해준다.

- {{ groups['nodes'][ip] }}

  • group['nodes']는 IP 실제값을 가지는데 거기에 [IP]라는 index 값을 계산해서 개별적으로 치환하도록 작성한 것이다.

- node{{ groups['nodes'][ip][-3:] }}

  • node는 node라는 문자 그 자체이다.
  • [-3]은 뒤에 IP주소의 뒤 3자리가 다르므로 뒤 3자리만 치환하여 가져오도록 설정함

즉, for문을 사용하면 모든 node와 ansible-server의 /etc/hosts에 아래와 같이 작성되는 것이다.

  127.0.0.1 {{ ansible_hostname }}
  192.168.1.10 server
  192.168.1.101 node101
  192.168.1.102 node102
  192.168.1.103 node103
  192.168.1.104 node104
  192.168.1.201 node201
  192.168.1.202 node202
  192.168.1.203 node203
  192.168.1.204 node204

 

탬플릿은 형식을 읽어서 다른곳으로 출력하는 것이다.

 

Example 1 플레이북 적용

ansible-playbook hosts_template.yml

플레이북 실행 결과
/etc/hosts 파일 확인

 

Example2

template을 활용하여 nginx 설치 확인 및 정상 구동 확인을 debug 모듈의 메시지로 출력하기

ins_chk.j2는 무언가를 입력할 때 체크하려는 목적으로 작성된 jinja2 형식의 파일이다.

# vi nginx_install_w_template.yml

---
- name: Install nginx on the nodes
  hosts: nodes
  become: yes

  tasks:
  - name: nginx for Any Linux
    include_tasks: "{{ lnx_name }}.yml"
  - name: Check nginx config
    command: "nginx -t"
    register: nginx
  - debug: msg="{{ nginx.stderr_lines }}"

  - name: Check nginx service
    debug: msg="{{lookup('template','ins_chk.j2').split('\n')}}"

  handlers:
  - name: Restart nginx web server
    service: name=nginx state=restarted

lookup이라는 기능을 사용하여 template을 찾는다.

split을 사용하여 개행 문자별로 구분해주고 해당 메시지를 debug 모듈을 사용하여 출력해준다. 이때 화면에 출력되는 내용이 ins_chk.j2에 작성된 코드이다.

# vi ins_chk.j2

{% if ansible_distribution == 'Ubuntu' %}
   [ OS : Ubuntu ]
    >> dpkg -l | grep nginx
    OR
    >> service nginx status
{% elif ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7' %}
   [ OS : CentOS ver7 ]
    >> yum list installed | grep nginx
    OR
    >> systemctl status nginx
{% elif ansible_distribution == 'CentOS' and ansible_distribution_major_version < '7' %}
   [ OS : CentOS ver6 ]
    >> yum list installed | grep nginx
    OR
    >> service nginx status
{% else %}
    >> service nginx status (* Gernally)
{% endif %}

제어문 if를 사용하여 구현한 모습이다.

각 운영체제에 맞춰 nginx가 정상적으로 설치되고 동작하고 있는지 디버그를 통해 출력될 메시지를 jinja2의 python 코드로 작성한 것이다.

 

Example 2 플레이북 적용

ansible-playbook nginx_install_w_template.yml

각 운영체제에 맞춰 설정된 코드가 실행되어 nginx가 정상 설치 및 정상 구동을 확인 후 debug 모듈을 통해 메시지가 출력된 모습이다.

 

Jinja live parser

Template을 작성하고 Render해봄으로써 테스트가 가능하여 작성을 더욱 쉽게 할 수 있다.

Jinja live parser (cryptic-cliffs-32040.herokuapp.com)

 

Jinja live parser

Values { "name": "John", "test": true } Custom Filters leetify: Leetify text ('a' becomes '4', 'e' becomes '3', etc.)

cryptic-cliffs-32040.herokuapp.com