Ansible Jinja2 模板使用

主机规划

主机名称 操作系统版本 内网IP 外网IP(模拟) 安装软件
ansi-manager CentOS7.5 172.16.1.180 10.0.0.180 ansible
ansi-haproxy01 CentOS7.5 172.16.1.181 10.0.0.181
ansi-haproxy02 CentOS7.5 172.16.1.182 10.0.0.182
ansi-web01 CentOS7.5 172.16.1.183 10.0.0.183
ansi-web02 CentOS7.5 172.16.1.184 10.0.0.184
ansi-web03 CentOS7.5 172.16.1.185 10.0.0.185

添加用户账号

说明:

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

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

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

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

[proxyservers]
172.16.1.18[1:2]:22

# 方式2:别名 + 主机 + 端口 + 密码
[webservers]
web01 ansible_ssh_host=172.16.1.183 ansible_ssh_port=22
web02 ansible_ssh_host=172.16.1.184 ansible_ssh_port=22
web03 ansible_ssh_host=172.16.1.185 ansible_ssh_port=22

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(1,9) -%}
    {
    { item }}
{%- endfor %}

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

转义

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

单行转义:简单方式

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

{
    { '{
    {' }}

多行转义:

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

{% raw %}
    
    {% for item in seq %}
  • { { item }}
  • {% endfor %}
{% endraw %}

HTML 手动转义

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

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

{
    { user.username|e }} 。

宏定义

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

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

示例:

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

宏变量解释:

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

value:默认为空字符串

type:默认为 text

size:默认为 20

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

{ { input('username') }}

## 结果为:

{ { input('password', type='password') }}

## 结果为:

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 允许用计算值。这在模板中很少用到,但是为了完整性允许其存在。

支持如下运算符:

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

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

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

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

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

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

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

比较

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

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

>:如果左边大于右边,返回 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 。比如 {
    { 1 in [1,2,3] }} 会返回 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 4
drwxrwxr-x 2 yun yun  65 Sep  5 19:34 file
-rw-rw-r-- 1 yun yun 188 Sep  5 16:45 test_jinja2_01.yml
[yun@ansi-manager jinja]$ ll file/
total 16
-rw-rw-r-- 1 yun yun 1562 Sep  5 19:36 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[1] = {
    { info[1] }}
info = {
    { info }}

navigation[0][1] = {
    { navigation[0][1] }}
navigation = {
    { navigation }}

# 变量    打印 DNS 信息 信息来自于 Ansible Facts
host_DNS1 = {
    { ansible_dns['nameservers'][0] }}
host_DNS2 = {
    { ansible_dns.nameservers[0] }}

##### 条件判断、循环、空白控制、转义 示例
# 条件判断
{# {% 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 %}
    
    {% for item in range(1,5) %}
  • { { item }}
  • {% endfor %}
{% 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 8
drwxrwxr-x 2 yun yun  95 Sep  5 20:00 file
-rw-rw-r-- 1 yun yun 196 Sep  5 20:08 test_jinja2_02.yml
[yun@ansi-manager jinja]$ ll file/
total 12
-rw-rw-r-- 1 yun yun  300 Sep  5 20:00 test_jinja2_02.conf.j2
-rw-rw-r-- 1 yun yun  209 Sep  5 19:58 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 8
drwxrwxr-x 2 yun yun  95 Sep  5 20:00 file
-rw-rw-r-- 1 yun yun 196 Sep  5 20:08 test_jinja2_03.yml
[yun@ansi-manager jinja]$ ll file/
total 12
-rw-rw-r-- 1 yun yun  300 Sep  5 20:00 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 = {
    { 3.2 * 3 }}
次幂运算: 3.2 ** 3 = {
    { 3.2 ** 3 }}

重复一个字符多次:'$' * 20 = {
    { '$' * 20 }}


### 比较
比较是否相等: '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 8
drwxrwxr-x 2 yun yun  95 Sep  5 20:00 file
-rw-rw-r-- 1 yun yun 196 Sep  5 20:08 test_jinja2_04.yml
[yun@ansi-manager jinja]$ ll file/
total 12
-rw-rw-r-- 1 yun yun  300 Sep  5 20:00 test_jinja2_04.conf.j2

配置文件

[yun@ansi-manager jinja]$ cat file/test_jinja2_04.conf.j2 
# 其他运算符

## in
左操作数包含于右操作数: {
    { 1 in [1,2,3] }}
左操作数包含于右操作数: {
    { 10 in [1,2,3] }}

## is
{% set pawd = '123abc' %}
Test: {
    { pawd is defined }}

## ~
{% set name = 'zhang' %}
字符串连接: "Hello" ~ name ~ '!' ~ 123 = {
    { "Hello" ~ name ~ '!' ~ 123 }}

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 8
drwxrwxr-x 2 yun yun  95 Sep  5 20:00 file
-rw-rw-r-- 1 yun yun 196 Sep  5 20:08 test_jinja2_05.yml
[yun@ansi-manager jinja]$ ll file/
total 12
-rw-rw-r-- 1 yun yun  300 Sep  5 20:00 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', 1997, 2000] %}

# 过滤器 使用
## 取绝对值
{
    { 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(1,20) %}
  server 172.16.1.{
    { i }}:80
{% 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 28
-rw-rw-r-- 1 yun yun 1103 Jan 15 21:06 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(1,20) %}
            server 172.16.1.{
    { i }}:80
          {% 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:80
  server 172.16.1.2:80
  server 172.16.1.3:80
  server 172.16.1.4:80
  server 172.16.1.5:80
  server 172.16.1.6:80
  server 172.16.1.7:80
  server 172.16.1.8:80
  server 172.16.1.9:80
  server 172.16.1.10:80
  server 172.16.1.11:80
  server 172.16.1.12:80
  server 172.16.1.13:80
  server 172.16.1.14:80
  server 172.16.1.15:80
  server 172.16.1.16:80
  server 172.16.1.17:80
  server 172.16.1.18:80
  server 172.16.1.19:80
### END ANSIBLE MANAGED BLOCK jinja2 test ###

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

在这里插入图片描述

你可能感兴趣的:(自动化,ansible,devops,linux,ansible,自动化,devops,centos)