RHCE8 资料整理
- 第 33 章 jinja2模板的使用
- 31.1 if 判断
- 33.2 for循环
- 33.3 handlers
第 33 章 jinja2模板的使用
详细参考
https://blog.csdn.net/u010230019/article/details/128561872
https://blog.csdn.net/u010230019/article/details/128477679
假设目前Nginx的配置文件在所有的服务器上都是相同的,但我希望能根据每一台服务器的性能去定制服务的启动进程。 同时定制每一台Nginx服务的响应头,以便于当某台服务出现问题时能快速定位到具体的服务器。
要做这样的定制势必会导致一个问题,Nginx 在每台物理服务器上的配置文件都不一样,这样的配置文件如何管理呢? 再使用copy 模块去做管理显然已经不合适。此时使用Ansible 提供的另一个模块(template
) 功能,它可以帮助我们完美的解决问题。
template
模块使用了Jinjia2格式作为文件模版,可以进行文档内变量的替换。 它的每次使用都会被ansible标记为”changed”状态。文件以 .j2 结尾,模块常用参数如下:
backup 创建一个包含时间戳信息的备份文件,这样如果您以某种方式错误地破坏了原始文件,就可以将其恢复原状。yes/noforce 默认值是yes,当内容与源不同时,它将替换远程文件。如果no,仅在目标不存在时才传输文件。src 指定 Ansible 控制端的文件路径dest 指定 Ansible 被控端的文件路径owner 指定文件的属主group 指定文件的属组mode 指定文件的权限newline_sequence 指定新文件的换行符; \n,\r, 或 \r\n
Jiaja2是Flask
默认支持的模板引擎,它的主要作用是渲染模板
- jinja2 文件以 .j2 为后缀, 也可以不写后缀。
- jinja2 中存在三种定界符
注释: {# 注释内容 #}变量引用: {{ var }}逻辑表达: {% %}
示例,
[root@node-137 ansible]# cat templates/aa.j2
myIP: {{ansible_default_ipv4.address}}[root@node-137 ansible]# cat jinja2-1.yml
---
- hosts: db1gather_facts: truetasks:- template: src=aa.j2 dest=/home/yurq/aa.txt[root@node-137 ansible]# ansible-playbook jinja2-1.yml
PLAY [db1] ****************************************************************************************************************************TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]TASK [template] ***********************************************************************************************************************
ok: [node-138]PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0[root@node-137 ansible]# ansible db1 -m shell -a "cat /home/yurq/aa.txt"
node-138 | CHANGED | rc=0 >>
myIP: 192.168.81.138
如果jinja2模板文件中没有写路径,则会优先
在当前目录的templates
中查找
31.1 if 判断
{# 如果定义了 idc 变量, 则输出 #}
{% if 判断1 %} 内容1
{% elif 判断2 %}内容2
{% else %} 内容3
{% endif %}
注意:
%
两边有没有空格都可以,不过所有的%
前后空格要保持一致if
或elif
中的内容过多,可以另起一行elif
和else
不是必需的- 如果
判断1
成立,则打印内容1
,后面的条件不再执行,直接跳到endif
后面的内容;如果判断1
不成立,则执行elif
后面的判断2
,成功则跳到endif
后面的内容,如果判断2
不成立,则执行else
后面内容3
。如果if
或elif
都不成立,则打印else
后面内容3
。
示例,
[root@node-137 ansible]# cat templates/if-1.j2
{% if ansible_default_ipv4.address=='192.168.17.138' %}{{ ansible_default_ipv4.address }}
{% elif ansible_fqdn=="node-138" %}{{ ansible_fqdn }}
{% else %}{{ ansible_distribution_major_version }}
{% endif %}"end"[root@node-137 ansible]# cat if-1.yml
---
- hosts: db1gather_facts: truetasks:- template: src=if-1.j2 dest=/home/yurq/if.txt[root@node-137 ansible]# ansible-playbook if-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [template] ***********************************************************************************************************************
fatal: [node-138]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'ansible_default_ipv4' is undefined"}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0[root@node-137 ansible]# ansible db1 -m shell -a "cat /home/yurq/if.txt"
node-138 | CHANGED | rc=0 >>node-138"end"
33.2 for循环
一个列表中有多个元素,如果需要依次对列表中的每个元素操作,则可以使用for
循环来实现,语法,
{% for i in 列表名%}{{i}}
{% endfor %}
示例,
[root@node-137 ansible]# cat templates/for-1.j2
{% set list1=['aa','bb','cc'] %}
111
{% for i in list1 %}
{{i}}
{% endfor %}
222
[root@node-137 ansible]# cat for-1.yml
---
- hosts: db1gather_facts: falsetasks:- template: src=for-1.j2 dest=/home/yurq/for-1.txt
[root@node-137 ansible]# ansible-playbook for-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [template] ***********************************************************************************************************************
changed: [node-138]PLAY RECAP ****************************************************************************************************************************
node-138 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0[root@node-137 ansible]# ansible db1 -m shell -a "cat /home/yurq/for-1.txt"
node-138 | CHANGED | rc=0 >>
111
aa
bb
cc
222
除了jinja2模板中手动定义的列表,一般情况下,我们会在playbook中定义列表,然后对列表中的元素进行循环
[root@node-137 ansible]# cat templates/ee.j2
{% for i in users %}
{{i.uname}}
{% endfor %}
[root@node-137 ansible]# cat user_list.txt
users:- uname: "tom"age: 18- uname: "jerry"age: 19- uname: "jacky"age: 18
[root@node-137 ansible]# cat for-2.yml
---
- hosts: db1gather_facts: falsevars_files:- user_list.txttasks:- template: src=ee.j2 dest=/home/yurq/for-2.txt
[root@node-137 ansible]# ansible-playbook for-2.ymlPLAY [db1] ****************************************************************************************************************************TASK [template] ***********************************************************************************************************************
ok: [node-138]PLAY RECAP ****************************************************************************************************************************
node-138 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0[root@node-137 ansible]# ansible db1 -m shell -a "cat /home/yurq/for-2.txt"
node-138 | CHANGED | rc=0 >>
tom
jerry
jacky
33.3 handlers
Handlers是Ansible Playbooks中的一种特殊任务类型。它们类似于事件处理程序,用于在特定条件下触发和执行任务。Handlers通常与任务关联,当任务的状态发生变化时,Handlers会被触发执行。Handlers可以用于执行各种操作,如重启服务、重新加载配置文件等。
1.handlers是ansible提供的条件机制之一,handlers和tasks很类似,但是只在被tasks通知的时候才会触发执行;
2.handlers只会在任务执行完成后执行。即使被通知了很多次,也只会执行一次。
3.当一个tasks中有多个notify,只会执行最后一个。
4.当tasks所有需要执行的任务执行完毕,才会执行handlers中的任务,并非跳转执行
[root@node-137 ansible]# cat hand-1.yml
---
- hosts: db1gather_facts: falsevars:myport: 8080tasks:- template: src=httpd.conf1.j2 dest=/etc/httpd/conf/httpd.confnotify: stop httpd1- shell: "systemctl is-active httpd"ignore_errors: trueregister: a- debug: msg={{a.rc}}- service: name=httpd state=started- shell: "systemctl is-active httpd"register: b- debug: msg={{b.rc}}handlers:- name: stop httpd1service: name=httpd state=stopped
- hosts: db1gather_facts: falsetasks:- shell: "systemctl is-active httpd"ignore_errors: trueregister: a- debug: msg={{a.rc}}
[root@node-137 ansible]# ansible-playbook hand-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [template] ***********************************************************************************************************************
changed: [node-138]TASK [shell] **************************************************************************************************************************
fatal: [node-138]: FAILED! => {"changed": true, "cmd": "systemctl is-active httpd", "delta": "0:00:00.037178", "end": "2023-12-21 16:20:43.782274", "msg": "non-zero return code", "rc": 3, "start": "2023-12-21 16:20:43.745096", "stderr": "", "stderr_lines": [], "stdout": "unknown", "stdout_lines": ["unknown"]}
...ignoringTASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "3"
}TASK [service] ************************************************************************************************************************
changed: [node-138]TASK [shell] **************************************************************************************************************************
changed: [node-138]TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "0"
}RUNNING HANDLER [stop httpd1] *********************************************************************************************************
changed: [node-138]PLAY [db1] ****************************************************************************************************************************TASK [shell] **************************************************************************************************************************
fatal: [node-138]: FAILED! => {"changed": true, "cmd": "systemctl is-active httpd", "delta": "0:00:00.034846", "end": "2023-12-21 16:20:48.079788", "msg": "non-zero return code", "rc": 3, "start": "2023-12-21 16:20:48.044942", "stderr": "", "stderr_lines": [], "stdout": "unknown", "stdout_lines": ["unknown"]}
...ignoringTASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "3"
}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=9 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=2