[Ansible] 08. Template
카테고리: ANSIBLE
태그: ansible
[Ansible] 08. Template
🔔 자세한 모듈 내용은 아래 문서를 참고
모듈 내용 : https://docs.ansible.com/ansible/latest/collections/ansible/builtin/index.html#modules
예제 Github : https://github.com/revenge1005/Ansible_study
🔔 Template
Ansible에서는 기존 파일 내용을 수정할 수 있는 여러 모듈을 제공하며, 대표적으로 lineinfile, blockinfile 등이 있는데 이것들은 단순 수정하는데는 좋지만 어떤 규칙에 의해 체계적으로 관리하는 파일에서 쓰기에는 부족했고, 그래서 Ansible은 파일을 관리하는데 템플릿(Template)을 지정하는 것이다.
템플릿은 파일이 배포될 때 Ansible Client에 대해 Ansible 변수 및 팩트 변수를 사용해 자동으로 지정되는 템플릿 파일을 작성할 수 있어 제어하기 더 쉽고 오류 발생률도 낮다.
Ansible에서는 템플릿 파일을 jinja2라는 템플릿 시스템을 사용하며, jinja2는 위에서 말한 템플릿을 사용하는데 쓰기도 하지만, Playbook에서 지정한 변수를 참조하고 여러가지 확장된 사용을 가능하게 한다.
🔔 jinja2 템플릿 구문 사용하기
jinja2 템플릿은 데이터, 변수, 식 등 여러 요소로 구성되는데, 이러한 변수와 식은 jinja2 템플릿이 랜더링되면(jinja2 문법이 변역되어 실해되면) 해당 값으로 변경된다.
템플릿에 사용하는 변수는 playbook의 vars 섹션에서 지정과 Ansible Client의 팩트 변수를 사용할 있다.
jinja2 템플릿이 들어있는 파일에는 따로 확장자명은 필요 없지만, j2 이런식으로 확장명을 제공하면 템플릿인지 쉽게 알 수 있다.
# << 사용 방법 >>
{{ }} : 식/변수 결과를 최종 사용자에게 출력
{% %} : 식 또는 논리(반복문 등)에 사용
{# #} : 주석
🔔 template 모듈 정보
기능은 ansible host에 있는 파일을 ansible client에 배포하는 것이지만, 같은 기능을 하는 모듈이 많으므로 일반적으로 jinja2 템플릿 파일을 배포하는데 사용된다.
Template 모듈 : https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html#ansible-collections-ansible-builtin-template-module
📜 템플릿 예제 - 1
(1) 템플릿 파일 작성
$ cat <<EOF > test01.j2
Welcome to {{ ansible_facts.hostname }}.
Today's date is : {{ ansible_facts.date_time.date }}
EOF
(2) 템플릿 파일 작성
cat <<EOF > template_playbook.yml
---
- name: jinja2 test
hosts: all
tasks:
- name: jinja2 template
template:
src: ./test01.j2
dest: /tmp/jinja-test-result
owner: root
group: root
mode: 0644
EOF

📜 템플릿 예제 - 2
관리자가 template으로 만든 결과파일에 대해 수정하지 않도록 요구하거나 특별한 주석을 달고 싶을때, 여러 방법이 있지만 가장 간단한 방법은 ansible.cfg의 [defaults] 섹션에 “ansible_managed=” 라는 부분을 추가하는 것이다.
(1) ansible.cfg
$ cat ansible.cfg
[defaults]
inventory = inventory
private_key_file = ~/.ssh/id_ed25519
# 아래 내용 추가
ansible_managed = NOTICE : This file is ansible managed : {file} modified on %Y-%m-d %H:%M:%S by {uid} on {host}
(2) 템플릿 파일 작성
cat <<EOF > test02.j2
{{ ansible_managed }}
Welcome to {{ ansible_facts.hostname }}.
Today's date is : {{ ansible_facts.date_time.date }}
EOF
(3) Playbook - 예제 (1)과 동일 (src: ./test02.j2 로 변경됨)
cat <<EOF > template_playbook.yml
---
- name: jinja2 test
hosts: all
tasks:
- name: jinja2 template
template:
src: ./test02.j2
dest: /tmp/jinja-test-result
owner: root
group: root
mode: 0644
EOF

📜 템플릿 예제 - 3 (반복문)
(1) 사용법
{% for user in users %}
{{ user }}
{% endfor %}
(2) 예1) 직접 jinja2 템플릿에 변수를 정의하여 사용
$ cat <<EOF > jinja2-template1.j2
{% set numbers = [1,2,3,4,5,6,7,8,9,10] %}
{% for number in numbers %}
The number is {{ number }}
{% endfor %}
EOF
$ cat <<EOF > jinja2-template1.yml
---
- hosts: all
become: true
tasks:
- template:
src: jinja2-template1.j2
dest: /tmp/jinja2
mode: 0644
EOF
(3) 예2) 플레이북에서 직접 정의한 변수 사용
cat <<EOF > jinja2-template2.j2
{% for number in numbers %}
The number is {{ number }}
{% endfor %}
EOF
cat <<EOF > jinja2-template2.yml
---
- hosts: all
vars:
numbers:
[1,2,3,4,5,6,7,8,9,10]
become: true
tasks:
- template:
src: jinja2-template2.j2
dest: /tmp/jinja2
mode: 0644
EOF
(4) 예1, 2) 결과
[root@master ansible_test]# ssh node01 cat /tmp/jinja2
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
The number is 6
The number is 7
The number is 8
The number is 9
The number is 10
(5) 예3) 매직변수 & 팩트 변수 사용
-
이렇게 여러개의 ansible host를 대상으로 팩트변수를 얻는 구문을 쓸 때는 ansible-playbook에도 해당 호스트를 동일하게 명시해야 한다.
-
“loop.index”는 반복 횟수를 보여주며, 반복 횟수에 따라 특정 구문을 실행하도록 할 때 사용할 수 있고, 여러 방면에서 활용 가능하다
$ cat <<EOF > jinja2-template3.j2
{% for host in groups['all'] %}
HOST {{ hostvars[host]['ansible_facts']['hostname'] }} IPADDR : {{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }}
{{ loop.index }}
{% endfor %}
EOF
$ cat <<EOF > jinja2-template3.yml
---
- hosts: all
become: true
tasks:
- template:
src: jinja2-template3.j2
dest: /tmp/jinja2
mode: 0644
EOF
ssh node02 cat /tmp/jinja2
HOST node01 IPADDR : 192.168.219.201
1
HOST node02 IPADDR : 192.168.219.202
2
HOST choi IPADDR : 192.168.219.203
3
📜 템플릿 예제 - 4 (조건문)
(1) 사용법
{% if 조건문 %}
조건이 true인 경우 실행할 내용
{% endif %}
(2) 예1) finished 변수의 값이 true 일 때만 result 변수의 값을 찍어낸다.
{% if finished %}
{{ result }}
{% endif %}
(3) 예2)
{# for statement #}
{% for myuser in users if not myuser == "root" %}
User number {{loop.index}} - {{myuser }}
{% endfor %}
댓글 남기기