共计 11111 个字符,预计需要花费 28 分钟才能阅读完成。
template模块通常用来渲染配置文件,通过使用模板语言的语义在任务执行时自动翻译渲染出自定义格式的配置文件
template模块
使用方式
- name: Copy a new sudoers file into place, after passing validation with visudo
template:
src: /mine/sudoers
dest: /etc/sudoers
validate: /usr/sbin/visudo -cf %s
- name: Update sshd configuration safely, avoid locking yourself out
template:
src: etc/ssh/sshd_config.j2
dest: /etc/ssh/sshd_config
owner: root
group: root
mode: '0600'
validate: /usr/sbin/sshd -t -f %s
backup: yes
模板文件内支持的数据类型和操作
- 字符串:使用单引号或双引号
- 数字:整数,浮点数
- 列表: [item1, item2, …]
- 元组: (item1, item2, …)
- 字典: {key1:value1, key2:value2, …}
- 布尔型: true/false
- 算术运算: +, -, *, /, //, %, **
- 比较操作: ==, !=, >, >=, <, <=
- 逻辑运算: and, or, not
- 流表达式: For If When
nginx模板配置样例
nginx简单样例
目标实现的最终文件为
[root@manager web]# cat test.xadocker.cn.conf
server {
listen 80;
server_name test.xadocker.cn;
index index.html;
root /home/wwwroot/test.xadocker.cn/public;
# logging
access_log /home/wwwlogs/test.xadocker.cn.access.log combined buffer=512k flush=1m;
}
用模板语言进行提取域名和端口为变量
[root@manager web]# cat web.conf.j2
server {
listen {{ port }};
server_name {{ server_name }};
index index.html;
root /home/wwwroot/{{ server_name }}/public;
# logging
access_log /home/wwwlogs/{{ server_name }}.access.log combined buffer=512k flush=1m;
}
playbook则为
[root@manager web]# cat nginx-template.yaml
---
- name: render nginx web conf
hosts: web
vars:
server_name: "test.xadocker.cn"
port: "80"
tasks:
- name: render nginx web conf
template:
src: ./web.conf.j2
dest: /etc/nginx/conf.d/{{ server_name }}.conf
任务运行并查看
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port
PLAY [render nginx web conf] *******************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [192.168.44.151]
TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151]
PLAY RECAP *************************************************************************************************************
192.168.44.151 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@k8s-master web]# cat /etc/nginx/conf.d/test.xadocker.cn.conf
server {
listen 80;
server_name test.xadocker.cn;
index index.html;
root /home/wwwroot/test.xadocker.cn/public;
# logging
access_log /home/wwwlogs/test.xadocker.cn.access.log combined buffer=512k flush=1m;
}
循环渲染多个配置文件
# 模板文件
[root@manager web]# cat web.conf.j2
server {
listen {{ port }};
server_name {{ item }};
index index.html;
root /home/wwwroot/{{ item }}/public;
# logging
access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
}
# playbook配置
[root@manager web]# cat nginx-template.yaml
---
- name: render nginx web conf
hosts: web
vars:
server_name:
- "test1.xadocker.cn"
- "test2.xadocker.cn"
port: "80"
tasks:
- name: render nginx web conf
template:
src: ./web.conf.j2
dest: /etc/nginx/conf.d/{{ item }}.conf
with_items:
- "{{ server_name }}"
# 任务输出
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port
PLAY [render nginx web conf] *******************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [192.168.44.151]
TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151] => (item=test1.xadocker.cn)
changed: [192.168.44.151] => (item=test2.xadocker.cn)
PLAY RECAP *************************************************************************************************************
192.168.44.151 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@k8s-master web]# cat /etc/nginx/conf.d/test1.xadocker.cn.conf
server {
listen 80;
server_name test1.xadocker.cn;
index index.html;
root /home/wwwroot/test1.xadocker.cn/public;
# logging
access_log /home/wwwlogs/test1.xadocker.cn.access.log combined buffer=512k flush=1m;
}
[root@k8s-master web]# cat /etc/nginx/conf.d/test2.xadocker.cn.conf
server {
listen 80;
server_name test2.xadocker.cn;
index index.html;
root /home/wwwroot/test2.xadocker.cn/public;
# logging
access_log /home/wwwlogs/test2.xadocker.cn.access.log combined buffer=512k flush=1m;
}
模板文件中的判断
判断使用以下语法
{% if condition %}
{% endif %}
{% if condition %}
{% else %}
{% endif %}
{% if condition1 %}
{% elif condition2 %}
{% endif %}
我们将nginx的日志提取出来做判断是否开启日志记录
# 模板文件
[root@manager web]# cat web.conf.j2
server {
listen {{ port }};
server_name {{ item }};
index index.html;
root /home/wwwroot/{{ item }}/public;
{% if item == "test1.xadocker.cn" %}
# logging
access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
{% endif %}
}
# playbook配置
[root@k8s-master web]# cat nginx-template.yaml
---
- name: render nginx web conf
hosts: web
vars:
server_name:
- "test1.xadocker.cn"
- "test2.xadocker.cn"
port: "80"
tasks:
- name: render nginx web conf
template:
src: ./web.conf.j2
dest: /etc/nginx/conf.d/{{ item }}.conf
with_items:
- "{{ server_name }}"
# 任务输出
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port
PLAY [render nginx web conf] *******************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [192.168.44.151]
TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151] => (item=test1.xadocker.cn)
changed: [192.168.44.151] => (item=test2.xadocker.cn)
PLAY RECAP *************************************************************************************************************
192.168.44.151 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@manager web]# cat /etc/nginx/conf.d/test1.xadocker.cn.conf
server {
listen 80;
server_name test1.xadocker.cn;
index index.html;
root /home/wwwroot/test1.xadocker.cn/public;
# logging
access_log /home/wwwlogs/test1.xadocker.cn.access.log combined buffer=512k flush=1m;
}
[root@manager web]# cat /etc/nginx/conf.d/test2.xadocker.cn.conf
server {
listen 80;
server_name test2.xadocker.cn;
index index.html;
root /home/wwwroot/test2.xadocker.cn/public;
}
模板语言循环
循环可以使用以下方法
{% for i in you_vars %}
{% endfor %}
{% for user in users %}
{%- if loop.index is even %}{% continue %}{% endif %}
...
{% endfor %}
{% for user in users %}
{%- if loop.index >= 10 %}{% break %}{% endif %}
{%- endfor %}
循环中可以使用这些特殊变量
变量 | 描述 |
---|---|
loop.index | 当前循环迭代的次数(从 1 开始) |
loop.index0 | 当前循环迭代的次数(从 0 开始) |
loop.revindex | 到循环结束需要迭代的次数(从 1 开始) |
loop.revindex0 | 到循环结束需要迭代的次数(从 0 开始) |
loop.first | 如果是第一次迭代,为 True 。 |
loop.last | 如果是最后一次迭代,为 True 。 |
loop.length | 序列中的项目数 |
循环渲染配置ip百名单
# 模板文件
[root@manager web]# cat web.conf.j2
server {
listen {{ port }};
server_name {{ item }};
index index.html;
root /home/wwwroot/{{ item }}/public;
{% if item == "test1.xadocker.cn" %}
# logging
access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
{% endif %}
# check file
location ~ ^/.*check\.txt$ {
{% for ip in allow_list %}
allow {{ ip }};
{% endfor %}
deny all;
}
}
# playbook配置
[root@manager web]# cat nginx-template.yaml
---
- name: render nginx web conf
hosts: web
vars:
server_name:
- "test1.xadocker.cn"
- "test2.xadocker.cn"
port: "80"
allow_list:
- "192.168.1.0/24"
- "192.168.2.0/24"
- "192.168.3.0/24"
tasks:
- name: render nginx web conf
template:
src: ./web.conf.j2
dest: /etc/nginx/conf.d/{{ item }}.conf
with_items:
- "{{ server_name }}"
# 任务输出
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port
PLAY [render nginx web conf] *******************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [192.168.44.151]
TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151] => (item=test1.xadocker.cn)
changed: [192.168.44.151] => (item=test2.xadocker.cn)
PLAY RECAP *************************************************************************************************************
192.168.44.151 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@manager web]# cat /etc/nginx/conf.d/test1.xadocker.cn.conf
server {
listen 80;
server_name test1.xadocker.cn;
index index.html;
root /home/wwwroot/test1.xadocker.cn/public;
# logging
access_log /home/wwwlogs/test1.xadocker.cn.access.log combined buffer=512k flush=1m;
# check file
location ~ ^/.*check\.txt$ {
allow 192.168.1.0/24;
allow 192.168.2.0/24;
allow 192.168.3.0/24;
deny all;
}
}
模板语言移除空白
{%- for item in seq -%}
{{ item }}
{%- endfor -%}
这会产出中间不带空白的所有元素。如果 seq 是 1
到 9
的数字的列表, 输出会是 123456789
给nginx配置增加静态文件缓存时间
# 模板文件
[root@manager web]# cat web.conf.j2
server {
listen {{ port }};
server_name {{ item }};
index index.html;
root /home/wwwroot/{{ item }}/public;
{% if item == "test1.xadocker.cn" %}
# logging
access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
{% endif %}
# check file
location ~ ^/.*check\.txt$ {
{% for ip in allow_list %}
allow {{ ip }};
{% endfor %}
deny all;
}
location ~* \.(
{%- for i in static_file_ext -%}
{%- if loop.last -%}
{{ i }}
{%- else -%}
{{ i }}|
{%- endif -%}
{%- endfor -%}
)$ {
expires 7d;
}
}
# playbook配置
[root@manager web]# cat nginx-template.yaml
---
- name: render nginx web conf
hosts: web
vars:
server_name:
- "test1.xadocker.cn"
- "test2.xadocker.cn"
port: "80"
allow_list:
- "192.168.1.0/24"
- "192.168.2.0/24"
- "192.168.3.0/24"
static_file_ext:
- "js"
- "css"
- "jpg"
- "jpeg"
- "png"
tasks:
- name: render nginx web conf
template:
src: ./web.conf.j2
dest: /etc/nginx/conf.d/{{ item }}.conf
with_items:
- "{{ server_name }}"
# 任务输出
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port
PLAY [render nginx web conf] *******************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [192.168.44.151]
TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151] => (item=test1.xadocker.cn)
changed: [192.168.44.151] => (item=test2.xadocker.cn)
PLAY RECAP *************************************************************************************************************
192.168.44.151 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@manager web]# cat /etc/nginx/conf.d/test1.xadocker.cn.conf
server {
listen 80;
server_name test1.xadocker.cn;
index index.html;
root /home/wwwroot/test1.xadocker.cn/public;
# logging
access_log /home/wwwlogs/test1.xadocker.cn.access.log combined buffer=512k flush=1m;
# check file
location ~ ^/.*check\.txt$ {
allow 192.168.1.0/24;
allow 192.168.2.0/24;
allow 192.168.3.0/24;
deny all;
}
location ~* \.(js|css|jpg|jpeg|png)$ {
expires 7d;
}
}
另外一种更简便的行内列表拼接方式就是使用过滤器join
{{ [1, 2, 3]|join('|') }}
-> 1|2|3
{{ [1, 2, 3]|join }}
-> 123
之前的例子可以改写为
[root@manager web]# cat web.conf.j2
server {
listen {{ port }};
server_name {{ item }};
index index.html;
root /home/wwwroot/{{ item }}/public;
{% if item == "test1.xadocker.cn" %}
# logging
access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
{% endif %}
# check file
location ~ ^/.*check\.txt$ {
{% for ip in allow_list %}
allow {{ ip }};
{% endfor %}
deny all;
}
location ~* \.({{ static_file_ext|join('|') }})$ {
expires 7d;
}
}
模板语言注释
要把模板中一行的部分注释掉,默认使用 {# ... #}
注释语法。这在调试或 添加给你自己或其它模板设计者的信息时是有用的
{# note: disabled template because we no longer use this
{% for user in users %}
...
{% endfor %}
#}
模板语言自动转义
可以在模版中开启或者关闭自动转义,例如用template渲染为模板文件,而不是渲染成最钟的配置文件
{% autoescape true %}
自动转义在这块文本中是开启的。
{% endautoescape %}
{% autoescape false %}
自动转义在这块文本中是关闭的。
{% endautoescape %}
模板语言的各种方法还有很多,此处就举例一些博主层级常用的方式。若读者有其他需求可以查看jinja2的官方文档学习:http://doc.yonyoucloud.com/doc/jinja2-docs-cn/index.html
正文完