Ansible Jinja2 模板使用、语法与使用案例

主机规划

添加用户账号

说明:

1、 运维人员使用的登录账号;

2、 所有的业务都放在 /app/ 下「yun用户的家目录」,避免业务数据乱放;

3、 该用户也被 ansible 使用,因为几乎所有的生产环境都是禁止 root 远程登录的(因此该 yun 用户也进行了 sudo 提权)。

 # 使用一个专门的用户,避免直接使用root用户
# 添加用户、指定家目录并指定用户密码
# sudo提权
# 让其它普通用户可以进入该目录查看信息
useradd -u -d /app yun && echo '' | /usr/bin/passwd --stdin yun
echo "yun ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
chmod /app/

Ansible 配置清单Inventory

之后文章都是如下主机配置清单

 [yun@ansi-manager ansible_info]$ pwd
/app/ansible_info
[yun@ansi-manager ansible_info]$ cat hosts_key
# 方式1、主机 + 端口 + 密钥
[manageservers]
172.16.1.180: [proxyservers]
172.16.1.18[:]: # 方式2:别名 + 主机 + 端口 + 密码
[webservers]
web01 ansible_ssh_host=172.16.1.183 ansible_ssh_port=
web02 ansible_ssh_host=172.16.1.184 ansible_ssh_port=
web03 ansible_ssh_host=172.16.1.185 ansible_ssh_port=

Jinja2 模板概述

官网地址

http://docs.jinkan.org/docs/jinja2/

Jinja2 是一个现代的,设计者友好的,仿照 Django 模板的 Python 模板语言。 它速度快,被广泛使用,并且提供了可选的沙箱模板执行环境保证安全。

Ansible 如何使用 jinja2 模板

Ansible 使用 jinja2 模板,也就是 template 模板。该模块和 copy 模块一样,都是将文件复制到目标机器,但是区别在于 template 模块可以获取要复制文件中的变量的值,而 copy 则是原封不动的把文件内容复制过去。

实际运用,比如:针对不同的主机定义不同的变量,template 会在将文件分发前读取变量到 jinja2 模板,之后再然后分发到不同的被管理主机上。

Jinja2 常用语法

赋值

为变量赋值,优先级高于 playbook 中的优先级。

 {% set username = 'zhang' %}
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}

注释

{# ... #}:要把模板中一行或多行注释掉,默认的注释语法。

变量

{{ ... }}:把表达式的结果打印到模板上。

你可以使用点( . )来访问变量的属性,作为替代,也可以使用所谓的“下标”语 法( [] )。如下示例:

 {{ foo.bar }}
{{ foo['bar'] }}
示例:{{ a_variable }}、{{ foo.bar }}、{{ foo['bar'] }}

花括号不是变量的一部分,而是打印语句的重要一部分。

条件判断

Jinja 中的 if 语句可比 Python 中的 if 语句。

在最简单的形式中,你可以测试一个变量是否未定义,为空或 false:

简单形式:

 {% if 条件表达式 %}
……
{% endif %}

多分支形式:

 {% if 条件表达式 %}
……
{% elif 条件表达式 %}
……
{% else %}
……
{% endif %}

循环语句

for 循环语句

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

空白控制

默认配置中,模板引擎不会对空白做进一步修改,所以每个空白(空格、制表符、换行符 等等)都会原封不动返回。

此外,你也可以手动剥离模板中的空白。当你在块(比如一个 for 标签、一段注释或变量表达式)的开始或结束放置一个减号( - ),可以移除块前或块后的空白。如下:

 {% for item in range(,) -%}
{{ item }}
{%- endfor %}

输出的所有元素前后不会有任何空白,输出会是 123456789 。

转义

有时想要或甚至必要让 Jinja 忽略部分,而不会把它作为变量或块来处理。那么有如下两种方式:

单行转义:简单方式

需求:把 “{ {“ 作为原始字符串使用,而不是一个变量的开始部分。

{{ '{{' }}

多行转义:

需求:将如下一块代码不进行任何处理,直接打印输出。

 {% raw %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}

HTML 手动转义

如果你有一个可能包含 >、<、& 或 " 字符的变量,那么你需要转义它;否则会被 HTML 使用。

转义通过用管道传递到过滤器 |e 来实现,如:

{{ user.username|e }} 

宏定义

宏类似常规编程语言中的函数。它们用于把常用行为作为可重用的函数,取代手动重复的工作。

如果宏在不同的模板中定义,你需要首先使用 import 。

示例:

 ## 宏变量顺序和具体内容变量顺序一致「推荐写法」
{% macro input(name, value='', type='text', size=) -%}
<input name="{{ name }}" value="{{ value|e }}" type="{{ type }}" size="{{ size }}">
{%- endmacro %}
## 宏变量顺序和具体内容变量的顺序可以交错「不推荐写法」
{% macro input(name, value='', type='text', size=) -%}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}">
{%- endmacro %}

宏变量解释:

name:默认为空,引用时必填

value:默认为空字符串

type:默认为 text

size:默认为 20

在命名空间中,宏之后可以像函数一样调用:

 <p>{{ input('username') }}</p>    ## 结果为:<p><input name="username" value="" type="text" size=""></p>
<p>{{ input('password', type='password') }}</p> ## 结果为:<p><input name="password" value="" type="password" size=""></p>

import 导入

导入宏,并在不同的模板中使用。

 # 示例:导入 nginx 变量
{% from 'nginx_var.info' import nginx_package_path, nginx_version %}

过滤器

变量可以通过 过滤器 修改。过滤器与变量用管道符号( | )分割,并且也可以用圆括号传递可选参数。多个过滤器可以链式调用,前一个过滤器的输出会被作为后一个过滤器的输入。

例如 {{ name|striptags|title }}、{{ list|join(', ') }}

内置过滤器清单

http://docs.jinkan.org/docs/jinja2/templates.html#builtin-filters

ansible 自带过滤器

https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html?highlight=filter

Tests 测验

除了过滤器,所谓的「Tests」也是可用的。要测验一个变量或表达式,你要在变量后加上一个 is 和 Tests 的名称。当然 Tests 也可以接受参数。

内置测验清单

http://docs.jinkan.org/docs/jinja2/templates.html#builtin-tests

ansible 自带测验

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

算术

Jinja 允许用计算值。这在模板中很少用到,但是为了完整性允许其存在。

支持如下运算符:

 +:把两个对象加到一起。如:{{  +  }} 等于 。但是如果两者是字符串或列表,你可以用这种方式来衔接它们【连接字符串推荐使用 ~ 运算符】。

 -:用第一个数减去第二个数。如:{{  -  }} 等于  。

 /:对两个数做除法。返回值会是一个浮点数。如:{{  /  }} 等于 {{ 0.5 }} 。

 //:对两个数做除法,返回整数商。如:{{ 20 // 7 }} 等于 2 。

 %:计算整数除法的余数。如:{{  %  }} 等于  。

 *:用右边的数乘左边的操作数。如:{{  *  }} 会返回 。也可以用于重复一个字符串多次。如:{{ '=' *  }} 会打印  个等号的横条。

 **:取左操作数的右操作数次幂。如:{{  **  }} 会返回 。

比较

==:比较两个对象是否相等。

!=:比较两个对象是否不等。

>:如果左边大于右边,返回 true。

>=:如果左边大于等于右边,返回 true。

<:如果左边小于右边,返回 true。

<=:如果左边小于等于右边,返回 true。

逻辑

对于逻辑判断,在 for 过滤或 if 表达式中,它可以用于联合多个表达式:

and:如果左操作数和右操作数同为真,返回 true。

or:如果左操作数或右操作数有一个为真,返回 true。

not:对一个表达式取反(见下)。

(expr):表达式组。

提示:is 和 in 运算符同样支持使用中缀记法:foo is not bar 和 foo not in bar。所有的其它表达式需要前缀记法:not (foo and bar) 。

其它运算符

 in:运行序列/映射包含检查。如果左操作数 包含于 右操作数,返回 true 。比如 {{  in [,,] }} 会返回 true。

 is:运行一个 测验。参见上述

 |:应用一个 过滤器。参见上述

 ~:把所有的操作数转换为字符串,并且连接它们。 {{ "Hello " ~ name ~ "!" }} 会返回(假设 name 值为 'John' ) Hello John!。

全局函数

range([start], stop[, step]):返回一个包含整等差级数的列表。

Ansible Jinja2 使用案例-常见功能

本例包含:注释、赋值、变量、条件判断、循环、空白控制、转义。

目录结构

 [yun@ansi-manager jinja]$ pwd
/app/ansible_info/jinja
[yun@ansi-manager jinja]$ ll
total
drwxrwxr-x yun yun Sep : file
-rw-rw-r-- yun yun Sep : test_jinja2_01.yml
[yun@ansi-manager jinja]$ ll file/
total
-rw-rw-r-- yun yun Sep : test_jinja2_01.conf.j2

配置文件

 [yun@ansi-manager jinja]$ cat file/test_jinja2_01.conf.j2  # 涉及的文件
##### 注释、赋值、变量 示例
# 为变量赋值,优先级高于 playbook 中的变量赋值
{# 注释 支持单行或多行 不会在受控机显示任何注释信息 #}
{# 简单赋值 #}
{% set username = 'zhangsan' %}
{# 赋值一个数组 #}
{% set info = ('name', 'age', 'address') %} {# 或者 {% set info = ['name', 'age', 'address'] %} #}
{# 赋值一个二维数组 #}
{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{# 或者如下写法
{% set navigation = (('index.html', 'Index'), ('about.html', 'About')) %}
#} username = {{ username }} info[] = {{ info[] }}
info = {{ info }} navigation[][] = {{ navigation[][] }}
navigation = {{ navigation }} # 变量 打印 DNS 信息 信息来自于 Ansible Facts
host_DNS1 = {{ ansible_dns['nameservers'][] }}
host_DNS2 = {{ ansible_dns.nameservers[] }} ##### 条件判断、循环、空白控制、转义 示例
# 条件判断
{# {% if username == 'zhangsan' %} #}
{% if username == 'zhangsan1' %}
username1
{# {% elif username == 'zhangsan' %} #}
{% elif username == 'zhangsan2' %}
username2
{% else %}
username_other
{% endif %} # 循环
{% for host_dns in ansible_dns['nameservers'] %}
{{ host_dns }}
{% endfor %} # 去掉前后空白
{% for host_dns in ansible_dns['nameservers'] -%}
{{ host_dns }}
{%- endfor %} # 单行转义
{{ '{{' }} # 多行转义
## 块中的所有代码不做任何处理,直接原样输出
{% raw %}
<ul>
{% for item in range(,) %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}

playbook 文件

 [yun@ansi-manager jinja]$ cat test_jinja2_01.yml  # playbook 文件
---
# ansible jinja2 测试案例1
- hosts: proxyservers
vars:
- username: coco tasks:
- name: "test jinja2 01"
template:
src: ./file/test_jinja2_01.conf.j2
dest: /tmp/test_jinja2_01.conf

文件执行

 [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_01.yml  # 语法检测
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key -C test_jinja2_01.yml # 预执行,测试执行
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key test_jinja2_01.yml # 执行

Ansible Jinja2 使用案例-宏与导入

本例包含:宏、from 导入

目录结构

 [yun@ansi-manager jinja]$ pwd
/app/ansible_info/jinja
[yun@ansi-manager jinja]$ ll
total
drwxrwxr-x yun yun Sep : file
-rw-rw-r-- yun yun Sep : test_jinja2_02.yml
[yun@ansi-manager jinja]$ ll file/
total
-rw-rw-r-- yun yun Sep : test_jinja2_02.conf.j2
-rw-rw-r-- yun yun Sep : test_jinja2_macro.info

宏文件和配置文件

 [yun@ansi-manager jinja]$ cat file/test_jinja2_macro.info
{# 配置文件中使用宏 #} {% macro nginx_package_path(nginx_path="/tmp/package/nginx") -%}
{{ nginx_path }}
{%- endmacro %} {% macro nginx_version(version='1.14.2') -%}
{{ version }}
{%- endmacro %} [yun@ansi-manager jinja]$ cat file/test_jinja2_02.conf.j2
{# from 导入 nginx 变量 #}
{% from 'test_jinja2_macro.info' import nginx_package_path, nginx_version %} {# 没有指定,那么就是宏定义的默认值 #}
nginx_package_path = {{ nginx_package_path() }} {# 有给定值,那么会覆盖默认值 #}
nginx_version = {{ nginx_version("1.12.4") }}

playbook 文件

 [yun@ansi-manager jinja]$ cat test_jinja2_02.yml
---
# ansible jinja2 测试案例2
- hosts: proxyservers tasks:
- name: "test jinja2 02"
template:
src: ./file/test_jinja2_02.conf.j2
dest: /tmp/test_jinja2_02.conf

文件执行

 [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_02.yml  # 语法检测
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key -C test_jinja2_02.yml # 预执行,测试执行
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key test_jinja2_02.yml # 执行

Ansible Jinja2 使用案例-算术、比较、逻辑

本例包含:算术、比较、逻辑与其它运算符

目录结构

 [yun@ansi-manager jinja]$ pwd
/app/ansible_info/jinja
[yun@ansi-manager jinja]$ ll
total
drwxrwxr-x yun yun Sep : file
-rw-rw-r-- yun yun Sep : test_jinja2_03.yml
[yun@ansi-manager jinja]$ ll file/
total
-rw-rw-r-- yun yun Sep : test_jinja2_03.conf.j2

配置文件

 [yun@ansi-manager jinja]$ cat file/test_jinja2_03.conf.j2
### 算术
加法运算: 3.2 + 5.3 = {{ 3.2 + 5.3 }}
减法运算: 5.3 - 3.2 = {{ 5.3 - 3.2 }}
除法运算: 5.3 / 3.2 = {{ 5.3 / 3.2 }}
取商运算: 5.3 // 3.2 = {{ 5.3 // 3.2 }}
取余运算: 5.3 % 3.2 = {{ 5.3 % 3.2 }}
乘法运算: 3.2 * = {{ 3.2 * }}
次幂运算: 3.2 ** = {{ 3.2 ** }} 重复一个字符多次:'$' * = {{ '$' * }} ### 比较
比较是否相等: 'zhang' == "zhang" 为:{{ 'zhang' == "zhang" }}
比较是否相等: 'zhang' == "zhang1" 为:{{ 'zhang' == "zhang1" }}
比较是否不等: 'zhang' != "zhang1" 为:{{ 'zhang' != "zhang1" }}
比较是否不等: 'zhang' != "zhang" 为:{{ 'zhang' != "zhang" }}
左边大于右边: 5.3 > 3.2 为:{{ 5.3 > 3.2 }}
左边大于右边: 3.2 > 5.3 为:{{ 3.2 > 5.3 }}
左边大于等于右边: 5.3 >= 5.3 为:{{ 5.3 >= 5.3 }}
左边大于等于右边: 3.2 >= 5.3 为:{{ 3.2 >= 5.3 }}
左边小于右边: 5.3 < 3.2 为:{{ 5.3 < 3.2 }}
左边小于右边: 3.2 < 5.3 为:{{ 3.2 < 5.3 }}
左边小于等于右边: 5.3 <= 3.2 为:{{ 5.3 <= 3.2 }}
左边小于等于右边: 5.3 <= 5.3 为:{{ 5.3 <= 5.3 }} ### 逻辑
{% set name1 = 'zhang' %}
{% set name2 = "zhang" %}
{% set name3 = "li" %} ##### and 测验
{% if name1 == 'zhang' and name2 == 'zhang' %}
结果:True.
{% else %}
结果:False.
{% endif %} {% if name1 == 'zhang' and name3 == 'zhang' %}
结果:True.
{% else %}
结果:False.
{% endif %} ##### or 测验
{% if name1 == 'zhang' or name2 == 'zhang' %}
结果:True.
{% else %}
结果:False.
{% endif %} {% if name1 == 'zhang' or name3 == 'zhang' %}
结果:True.
{% else %}
结果:False.
{% endif %} ##### (expr) 测验
{% if name3 == 'zhang' or ( name1 == 'zhang' and name2 == 'zhang' ) %}
结果:True.
{% else %}
结果:False.
{% endif %} ##### not 测验
{% if name3 == 'zhang' or not (name1 == 'zhang' and name2 == 'zhang') %}
结果:True.
{% else %}
结果:False.
{% endif %}

playbook 文件

 [yun@ansi-manager jinja]$ cat test_jinja2_03.yml
--- # ansible jinja2 测试案例3
- hosts: proxyservers tasks:
- name: "test jinja2 03"
template:
src: ./file/test_jinja2_03.conf.j2
dest: /tmp/test_jinja2_03.conf

文件执行

 [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_03.yml  # 语法检测
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key -C test_jinja2_03.yml # 预执行,测试执行
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key test_jinja2_03.yml # 执行

Ansible Jinja2 使用案例-其它运算

本例包含:其它运算符

目录结构

 [yun@ansi-manager jinja]$ pwd
/app/ansible_info/jinja
[yun@ansi-manager jinja]$ ll
total
drwxrwxr-x yun yun Sep : file
-rw-rw-r-- yun yun Sep : test_jinja2_04.yml
[yun@ansi-manager jinja]$ ll file/
total
-rw-rw-r-- yun yun Sep : test_jinja2_04.conf.j2

配置文件

 [yun@ansi-manager jinja]$ cat file/test_jinja2_04.conf.j2
# 其他运算符 ## in
左操作数包含于右操作数: {{ in [,,] }}
左操作数包含于右操作数: {{ in [,,] }} ## is
{% set pawd = '123abc' %}
Test: {{ pawd is defined }} ## ~
{% set name = 'zhang' %}
字符串连接: "Hello" ~ name ~ '!' ~ = {{ "Hello" ~ name ~ '!' ~ }}

playbook 文件

 [yun@ansi-manager jinja]$ cat test_jinja2_04.yml
--- # ansible jinja2 测试案例4
- hosts: proxyservers tasks:
- name: "test jinja2 04"
template:
src: ./file/test_jinja2_04.conf.j2
dest: /tmp/test_jinja2_04.conf

文件执行

 [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_04.yml  # 语法检测
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key -C test_jinja2_04.yml # 预执行,测试执行
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key test_jinja2_04.yml # 执行

Ansible Jinja2 使用案例-过滤器和测验

本例包含:filters、tests 和 range。

内置过滤清单

http://docs.jinkan.org/docs/jinja2/templates.html#builtin-tests

内置测验清单

http://docs.jinkan.org/docs/jinja2/templates.html#tests

目录结构

 [yun@ansi-manager jinja]$ pwd
/app/ansible_info/jinja
[yun@ansi-manager jinja]$ ll
total
drwxrwxr-x yun yun Sep : file
-rw-rw-r-- yun yun Sep : test_jinja2_05.yml
[yun@ansi-manager jinja]$ ll file/
total
-rw-rw-r-- yun yun Sep : test_jinja2_05.conf.j2

配置文件

 [yun@ansi-manager jinja]$ cat file/test_jinja2_05.conf.j2
{# 变量定义 #}
{% set filter01 = -24.5 %}
{% set filter02 = 'abcDEGg' %}
{% set filter03 = " abCDef G hkIL " %}
{% set filter04 = ['physics', 'chemistry', , ] %} # 过滤器 使用
## 取绝对值
{{ filter01|abs() }} 或者 {{ filter01|abs }}
## 首字符大写,其他小写
{{ filter02|capitalize() }} 或者 {{ filter02|capitalize }}
## 去掉两端空格
|{{ filter03|trim() }}| 或者 |{{ filter03|trim }}|
## 返回序列的第一个
{{ filter04|first() }} 或者 {{ filter04|first }}
## 将序列变为字符串,可以指定每个元素间加入什么字符,默认空
默认情况: {{ filter04|join() }} 或者 {{ filter04|join }}
加入字符: {{ filter04|join('|') }} # Tests 测验 使用
## 变量是否定义
未定义: {{ filter00 is defined }}
已定义: {{ filter01 is defined }}
## 变量是否是数字
{{ filter01 is number }} === {{ filter02 is number }}
## 变量是否是小写
{{ filter02 is lower }}
## 变量是否是字符串
{{ filter02 is string }} ## 变量在 if 中的判断是否已定义
{# ***** 变量已经被定义,直接判断表达式是 True或False ***** #}
{# {% if filter01 %} #}{# 如果变量没有定义,那么执行会报错 #}
{# 由于 filter00 之前未定义,因此这里定义为 false,不然执行会报错【生产中会在 playbook中定义】
{% set filter00 = false %}
{% if filter00 %}
#}
{# ***** 通过判断变量是否被定义,得到到True或False ***** #}
{# {% if filter01 is defined %} #}
{% if filter00 is defined %}
variable is defined
{% else %}
variable is undefined
{% endif %} # range 使用
{% for i in range(,) %}
server 172.16..{{ i }}:
{% endfor %}

playbook 文件

 [yun@ansi-manager jinja]$ cat test_jinja2_05.yml
---
# ansible jinja2 测试案例5
- hosts: proxyservers tasks:
- name: "test jinja2 05"
template:
src: ./file/test_jinja2_05.conf.j2
dest: /tmp/test_jinja2_05.conf

文件执行

 [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_05.yml  # 语法检测
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key -C test_jinja2_05.yml # 预执行,测试执行
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key test_jinja2_05.yml # 执行

Ansible Jinja2 使用案例-在playbook中使用

本例在 ansible 的 playbook 中使用 jinja2.

目录结构

 [yun@ansi-manager jinja]$ pwd
/app/ansible_info/jinja
[yun@ansi-manager jinja]$ ll
total
-rw-rw-r-- yun yun Jan : test_jinja2_06.yml

playbook 文件

 [yun@ansi-manager jinja]$ cat test_jinja2_06.yml
---
# 在 playbook 中使用 jinja2 模板
- hosts: proxyservers tasks:
- name: "test_jinja2_06.info create"
file:
path: "/tmp/test_jinja2_06.info"
owner: yun
group: yun
state: touch # 这里用了 jinja2 的过滤器,计算,in 判断,赋值,条件判断,循环
- name: "test jinja2 06"
blockinfile:
path: "/tmp/test_jinja2_06.info"
marker: "### {mark} ANSIBLE MANAGED BLOCK jinja2 test ###"
block: |
name: "{{ ansible_eth0['ipv4']['address']|replace('.', '-') }}"
host: "{{ ansible_eth0['ipv4']['address'] }}"
count: "3.2 + 5.3 = {{ 3.2 + 5.3 }};5.3 - 3.2 = {{ 5.3 - 3.2 }};5.3 / 3.2 = {{ 5.3 / 3.2 }};5.3 % 3.2 = {{ 5.3 % 3.2 }};3.2 ** 3 = {{ 3.2 ** 3 }}"
other_count: "{{ 1 in [1,2,3] }}"
ifelse:
{% set name1 = 'zhang' %}
{% if name1 == 'zhang' %}
结果:True.
{% else %}
结果:False.
{% endif %}
loop:
{% for i in range(,) %}
server 172.16..{{ i }}:
{% endfor %}

文件执行

 [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_06.yml  # 语法检测
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key -C test_jinja2_06.yml # 预执行,测试执行
[yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key test_jinja2_06.yml # 执行

受控机结果查看

 [yun@ansi-haproxy01 ~]$ cat /tmp/test_jinja2_06.info
### BEGIN ANSIBLE MANAGED BLOCK jinja2 test ###
name: "172-16-1-181"
host: "172.16.1.181"
count: "3.2 + 5.3 = 8.5;5.3 - 3.2 = 2.1;5.3 / 3.2 = 1.65625;5.3 % 3.2 = 2.1;3.2 ** 3 = 32.768"
other_count: "True"
ifelse:
结果:False.
loop:
server 172.16.1.1:
server 172.16.1.2:
server 172.16.1.3:
server 172.16.1.4:
server 172.16.1.5:
server 172.16.1.6:
server 172.16.1.7:
server 172.16.1.8:
server 172.16.1.9:
server 172.16.1.10:
server 172.16.1.11:
server 172.16.1.12:
server 172.16.1.13:
server 172.16.1.14:
server 172.16.1.15:
server 172.16.1.16:
server 172.16.1.17:
server 172.16.1.18:
server 172.16.1.19:
### END ANSIBLE MANAGED BLOCK jinja2 test ###

以上!


———END———
如果觉得不错就关注下呗 (-^O^-) !

Ansible Jinja2 模板使用的更多相关文章

  1. ansible jinja2模板概述

    目录 ansible jinja2模板概述 ansible jinja2模板使用 基本语法 jinja2模板逻辑判断 ansible jinja2管理nginx ansible jinja2管理kee ...

  2. 5.Ansible Jinja2 模板

    1.jinja2渲染NginxProxy配置文件 jinja2 房屋建筑设计固定的 jinja2模板与Ansible关系 Ansible如何使用jinja2模板 template模块 拷贝文件? te ...

  3. Ansible Jinja2 模板

    1.jinja2渲染NginxProxy配置文件 jinja2 房屋建筑设计固定的? jinja2模板与Ansible关系 Ansible如何使用jinja2模板 template模块 拷贝文件? t ...

  4. Ansible --05 ansible jinja2

    ansible jinja2 什么是jinjia2模板 jinjia2是Python的全功能模块引擎 Jinjia2与Ansible的关系 Ansible通常会使用jinjia2模板来修改被管理主机的 ...

  5. Ansible_使用jinja2模板部署自定义文件

    一.jinja2简介 1.jinja2模板 1️⃣:Ansible将jinja2模板系统用于模板文件,Ansible还使用jinja2语法来引用playbook中的变量 2️⃣:变量和逻辑表达式置于标 ...

  6. Flask 框架下 Jinja2 模板引擎高层 API 类——Environment

    Environment 类版本: 本文所描述的 Environment 类对应于 Jinja2-2.7 版本.   Environment 类功能: Environment 是 Jinja2 中的一个 ...

  7. Python框架学习之Flask中的Jinja2模板

    前面也提到过在Flask中最核心的两个组件是Werkzeug和Jinja2模板.其中Werkzeug在前一节已经详细说明了.现在这一节主要是来谈谈Jinja2模板. 一.为什么需要引入模板: 在进行软 ...

  8. python操作三大主流数据库(5)python操作mysql⑤使用Jinja2模板提取优化页面展示

    python操作mysql⑤使用Jinja2模板提取优化页面展示 在templates目录下的index.html.cat.html等页面有一些共同的元素,代码比较冗余可以使用模板提取公共代码,在各网 ...

  9. Flask框架(2)-JinJa2模板

    为了把业务逻辑和表现逻辑分开,Flask把表现逻辑移到JinJa2模板,模板是一个包含响应文本的文件.它用占位变量表示动态部分,其具体要从请求上下文才知道. 把真实值替换掉占位变量成为渲染,JinJa ...

随机推荐

  1. QCustomPlot图形和图例同步方法

    QCustomPlot图形和图例同步前言 我现在有几条折线,折线和图例一一对应,不管点击图例或者折线,相关的都高亮 QCustomPlot图形和图例同步方法 // 链接信号槽 m_plot即为QCus ...

  2. 解决浏览器看不到Flash文档(尤其某慕课)

    最近遇到很多朋友说浏览器看不到网课资源的文档等等,就顺手写一篇说一下情况 为什么会文档空白 某课网站上面的文档是用flash进行展示的,同时flash被很多浏览器逐步抛弃(快凉了,都是H5了) fla ...

  3. SWUSTOJ 960A题总结,又完成一个讨厌的题,内含链表操作启发

    今天debug了一个nice代码,先码在这里,SWUST OJ960 双向链表的操作问题 1000(ms) 10000(kb) 2994 / 8244 建立一个长度为n的带头结点的双向链表,使得该链表 ...

  4. docker搭建可视化portainer

    一.在docker中查询portainer # docker search portainer 二.下载portainer # docker pull portainer/portainer 三.运行 ...

  5. .NET Core 3.1 的REST 和gRPC 性能测试

    看到越南小哥 的github 上的Evaluating Performance of REST vs. gRPC , 使用的是.NET Core 3.0 , 今天我把它升级到.NET Core 3.1 ...

  6. Android Visibility控件显示和隐藏

    Android控件显示和隐藏 visibility 可见(visible) XML文件:android:visibility="visible" Java代码:view.setVi ...

  7. C语言 加密解密

    加密解密算法,对于一个未接触加密的人来说,这听起来是多么可望而不可及,但是只要我们理解了加密的本质,对于它就没那么陌生了,更难的是加密的算法,而不是加密这个术语上! 我们知道,文本文件是以ascii码 ...

  8. python 删除三天前的日志.py

    #获取所有文件def file(): for cur_dir, dirs, files in os.walk(r'/学习/接口自动化/BestTest/作业/logs'): # cur_dir(当前路 ...

  9. C# 发布时出现:在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误

    在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接. (provider: SQL ...

  10. python3(五) if

    age = 20 if age >= 18: print('your age is', age) print('adult') # 如果if语句判断是True,就把缩进的两行print语句执行了 ...