• Ansible Jinja2 模板使用


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

    主机规划

    添加用户账号

    说明:

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

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

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

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

    Ansible 配置清单Inventory

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

    复制代码
     1 [yun@ansi-manager ansible_info]$ pwd
     2 /app/ansible_info
     3 [yun@ansi-manager ansible_info]$ cat hosts_key 
     4 # 方式1、主机 + 端口 + 密钥
     5 [manageservers]
     6 172.16.1.180:22
     7 
     8 [proxyservers]
     9 172.16.1.18[1:2]:22
    10 
    11 # 方式2:别名 + 主机 + 端口 + 密码
    12 [webservers]
    13 web01 ansible_ssh_host=172.16.1.183 ansible_ssh_port=22
    14 web02 ansible_ssh_host=172.16.1.184 ansible_ssh_port=22
    15 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 中的优先级。

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

    注释

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

    变量

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

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

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

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

    条件判断

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

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

    简单形式:

    1 {% if 条件表达式 %}
    2   ……
    3 {% endif %}

    多分支形式:

    复制代码
    1 {% if 条件表达式 %}
    2   ……
    3 {% elif 条件表达式 %}
    4   ……
    5 {% else %}
    6   ……
    7 {% endif %}
    复制代码

    循环语句

    for 循环语句

    1 {% for user in users %}
    2     {{ user.username }}
    3 {% endfor %}

    空白控制

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

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

    1 {% for item in range(1,9) -%}
    2     {{ item }}
    3 {%- endfor %}

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

    转义

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

    单行转义:简单方式

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

    {{ '{{' }}

    多行转义:

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

    复制代码
    1 {% raw %}
    2     <ul>
    3     {% for item in seq %}
    4         <li>{{ item }}</li>
    5     {% endfor %}
    6     </ul>
    7 {% endraw %}
    复制代码

    HTML 手动转义

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

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

    {{ user.username|e }} 

    宏定义

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

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

    示例:

    复制代码
    1 ## 宏变量顺序和具体内容变量顺序一致「推荐写法」
    2 {% macro input(name, value='', type='text', size=20) -%}
    3     <input name="{{ name }}" value="{{ value|e }}" type="{{ type }}" size="{{ size }}">
    4 {%- endmacro %}
    5 ## 宏变量顺序和具体内容变量的顺序可以交错「不推荐写法」
    6 {% macro input(name, value='', type='text', size=20) -%}
    7     <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}" size="{{ size }}">
    8 {%- endmacro %}
    复制代码

    宏变量解释:

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

    value:默认为空字符串

    type:默认为 text

    size:默认为 20

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

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

    import 导入

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

    1 # 示例:导入 nginx 变量
    2 {% 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 + 1 }} 等于 2。但是如果两者是字符串或列表,你可以用这种方式来衔接它们【连接字符串推荐使用 ~ 运算符】。
     2 
     3 -:用第一个数减去第二个数。如:{{ 3 - 2 }} 等于 1 。
     4 
     5 /:对两个数做除法。返回值会是一个浮点数。如:{{ 1 / 2 }} 等于 {{ 0.5 }} 。
     6 
     7 //:对两个数做除法,返回整数商。如:{{ 20 // 7 }} 等于 2 。
     8 
     9 %:计算整数除法的余数。如:{{ 11 % 7 }} 等于 4 。
    10 
    11 *:用右边的数乘左边的操作数。如:{{ 2 * 2 }} 会返回 4。也可以用于重复一个字符串多次。如:{{ '=' * 80 }} 会打印 80 个等号的横条。
    12 
    13 **:取左操作数的右操作数次幂。如:{{ 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) 。

    其它运算符

    复制代码
    1 in:运行序列/映射包含检查。如果左操作数 包含于 右操作数,返回 true 。比如 {{ 1 in [1,2,3] }} 会返回 true。
    2 
    3 is:运行一个 测验。参见上述
    4 
    5 |:应用一个 过滤器。参见上述
    6 
    7 ~:把所有的操作数转换为字符串,并且连接它们。 {{ "Hello " ~ name ~ "!" }} 会返回(假设 name 值为 'John' ) Hello John!。
    复制代码

    全局函数

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

    Ansible Jinja2 使用案例-常见功能

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

    目录结构

    复制代码
    1 [yun@ansi-manager jinja]$ pwd
    2 /app/ansible_info/jinja
    3 [yun@ansi-manager jinja]$ ll
    4 total 4
    5 drwxrwxr-x 2 yun yun  65 Sep  5 19:34 file
    6 -rw-rw-r-- 1 yun yun 188 Sep  5 16:45 test_jinja2_01.yml
    7 [yun@ansi-manager jinja]$ ll file/
    8 total 16
    9 -rw-rw-r-- 1 yun yun 1562 Sep  5 19:36 test_jinja2_01.conf.j2
    复制代码

    配置文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat file/test_jinja2_01.conf.j2  # 涉及的文件
     2 ##### 注释、赋值、变量 示例
     3 # 为变量赋值,优先级高于 playbook 中的变量赋值
     4 {# 注释    支持单行或多行  不会在受控机显示任何注释信息  #}
     5 {# 简单赋值 #}
     6 {% set username = 'zhangsan' %}
     7 {# 赋值一个数组 #}
     8 {% set info = ('name', 'age', 'address') %}  {# 或者 {% set info = ['name', 'age', 'address'] %} #}
     9 {# 赋值一个二维数组 #}
    10 {% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
    11 {# 或者如下写法
    12 {% set navigation = (('index.html', 'Index'), ('about.html', 'About')) %}
    13 #}
    14 
    15 username = {{ username }}
    16 
    17 info[1] = {{ info[1] }}
    18 info = {{ info }}
    19 
    20 navigation[0][1] = {{ navigation[0][1] }}
    21 navigation = {{ navigation }}
    22 
    23 # 变量    打印 DNS 信息 信息来自于 Ansible Facts
    24 host_DNS1 = {{ ansible_dns['nameservers'][0] }}
    25 host_DNS2 = {{ ansible_dns.nameservers[0] }}
    26 
    27 ##### 条件判断、循环、空白控制、转义 示例
    28 # 条件判断
    29 {# {% if username == 'zhangsan' %} #}
    30 {% if username == 'zhangsan1' %}
    31   username1
    32 {# {% elif username == 'zhangsan' %} #}
    33 {% elif username == 'zhangsan2' %}
    34   username2
    35 {% else %}
    36   username_other
    37 {% endif %}
    38 
    39 # 循环
    40 {% for host_dns in ansible_dns['nameservers'] %}
    41   {{ host_dns }}
    42 {% endfor %}
    43 
    44 # 去掉前后空白
    45 {% for host_dns in ansible_dns['nameservers'] -%}
    46   {{ host_dns }}
    47 {%- endfor %}
    48 
    49 # 单行转义
    50 {{ '{{' }}
    51 
    52 # 多行转义
    53 ## 块中的所有代码不做任何处理,直接原样输出
    54 {% raw %}
    55     <ul>
    56     {% for item in range(1,5) %}
    57         <li>{{ item }}</li>
    58     {% endfor %}
    59     </ul>
    60 {% endraw %}
    复制代码

    playbook 文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat test_jinja2_01.yml  # playbook 文件
     2 ---
     3 # ansible jinja2 测试案例1
     4 - hosts: proxyservers
     5   vars:
     6     - username: coco
     7 
     8   tasks:
     9     - name: "test jinja2 01"
    10       template:
    11         src: ./file/test_jinja2_01.conf.j2
    12         dest: /tmp/test_jinja2_01.conf
    复制代码

    文件执行

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

    Ansible Jinja2 使用案例-宏与导入

    本例包含:宏、from 导入

    目录结构

    复制代码
     1 [yun@ansi-manager jinja]$ pwd
     2 /app/ansible_info/jinja
     3 [yun@ansi-manager jinja]$ ll
     4 total 8
     5 drwxrwxr-x 2 yun yun  95 Sep  5 20:00 file
     6 -rw-rw-r-- 1 yun yun 196 Sep  5 20:08 test_jinja2_02.yml
     7 [yun@ansi-manager jinja]$ ll file/
     8 total 12
     9 -rw-rw-r-- 1 yun yun  300 Sep  5 20:00 test_jinja2_02.conf.j2
    10 -rw-rw-r-- 1 yun yun  209 Sep  5 19:58 test_jinja2_macro.info
    复制代码

    宏文件和配置文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat file/test_jinja2_macro.info 
     2 {# 配置文件中使用宏 #}
     3 
     4 {% macro nginx_package_path(nginx_path="/tmp/package/nginx") -%}
     5   {{ nginx_path }}
     6 {%- endmacro %}
     7 
     8 {% macro nginx_version(version='1.14.2') -%}
     9   {{ version }}
    10 {%- endmacro %}
    11 
    12 [yun@ansi-manager jinja]$ cat file/test_jinja2_02.conf.j2 
    13 {# from 导入 nginx 变量 #}
    14 {% from 'test_jinja2_macro.info' import nginx_package_path, nginx_version %}
    15 
    16 {# 没有指定,那么就是宏定义的默认值 #}
    17 nginx_package_path = {{ nginx_package_path() }}
    18 
    19 {# 有给定值,那么会覆盖默认值 #}
    20 nginx_version = {{ nginx_version("1.12.4") }}
    复制代码

    playbook 文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat test_jinja2_02.yml 
     2 ---
     3 # ansible jinja2 测试案例2
     4 - hosts: proxyservers
     5 
     6   tasks:
     7     - name: "test jinja2 02"
     8       template:
     9         src: ./file/test_jinja2_02.conf.j2
    10         dest: /tmp/test_jinja2_02.conf
    复制代码

    文件执行

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

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

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

    目录结构

    复制代码
    1 [yun@ansi-manager jinja]$ pwd
    2 /app/ansible_info/jinja
    3 [yun@ansi-manager jinja]$ ll
    4 total 8
    5 drwxrwxr-x 2 yun yun  95 Sep  5 20:00 file
    6 -rw-rw-r-- 1 yun yun 196 Sep  5 20:08 test_jinja2_03.yml
    7 [yun@ansi-manager jinja]$ ll file/
    8 total 12
    9 -rw-rw-r-- 1 yun yun  300 Sep  5 20:00 test_jinja2_03.conf.j2
    复制代码

    配置文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat file/test_jinja2_03.conf.j2 
     2 ### 算术
     3 加法运算: 3.2 + 5.3 = {{ 3.2 + 5.3 }}
     4 减法运算: 5.3 - 3.2 = {{ 5.3 - 3.2 }}
     5 除法运算: 5.3 / 3.2 = {{ 5.3 / 3.2 }}
     6 取商运算: 5.3 // 3.2 = {{ 5.3 // 3.2 }}
     7 取余运算: 5.3 % 3.2 = {{ 5.3 % 3.2 }}
     8 乘法运算: 3.2 * 3 = {{ 3.2 * 3 }}
     9 次幂运算: 3.2 ** 3 = {{ 3.2 ** 3 }}
    10 
    11 重复一个字符多次:'$' * 20 = {{ '$' * 20 }}
    12 
    13 
    14 ### 比较
    15 比较是否相等: 'zhang' == "zhang"  为:{{ 'zhang' == "zhang" }}
    16 比较是否相等: 'zhang' == "zhang1" 为:{{ 'zhang' == "zhang1" }}
    17 比较是否不等: 'zhang' != "zhang1" 为:{{ 'zhang' != "zhang1" }}
    18 比较是否不等: 'zhang' != "zhang"  为:{{ 'zhang' != "zhang" }}
    19 左边大于右边: 5.3 > 3.2 为:{{ 5.3 > 3.2 }}
    20 左边大于右边: 3.2 > 5.3 为:{{ 3.2 > 5.3 }}
    21 左边大于等于右边: 5.3 >= 5.3 为:{{ 5.3 >= 5.3 }}
    22 左边大于等于右边: 3.2 >= 5.3 为:{{ 3.2 >= 5.3 }}
    23 左边小于右边: 5.3 < 3.2 为:{{ 5.3 < 3.2 }}
    24 左边小于右边: 3.2 < 5.3 为:{{ 3.2 < 5.3 }}
    25 左边小于等于右边: 5.3 <= 3.2 为:{{ 5.3 <= 3.2 }}
    26 左边小于等于右边: 5.3 <= 5.3 为:{{ 5.3 <= 5.3 }}
    27 
    28 
    29 ### 逻辑
    30 {% set name1 = 'zhang' %}
    31 {% set name2 = "zhang" %}
    32 {% set name3 = "li" %}
    33 
    34 ##### and 测验
    35 {% if name1 == 'zhang' and name2 == 'zhang' %}
    36 结果:True.
    37 {% else %}
    38 结果:False.
    39 {% endif %}
    40 
    41 {% if name1 == 'zhang' and name3 == 'zhang' %}
    42 结果:True.
    43 {% else %}
    44 结果:False.
    45 {% endif %}
    46 
    47 ##### or 测验
    48 {% if name1 == 'zhang' or name2 == 'zhang' %}
    49 结果:True.
    50 {% else %}
    51 结果:False.
    52 {% endif %}
    53 
    54 {% if name1 == 'zhang' or name3 == 'zhang' %}
    55 结果:True.
    56 {% else %}
    57 结果:False.
    58 {% endif %}
    59 
    60 ##### (expr) 测验
    61 {% if name3 == 'zhang' or ( name1 == 'zhang' and name2 == 'zhang' ) %}
    62 结果:True.
    63 {% else %}
    64 结果:False.
    65 {% endif %}
    66 
    67 ##### not 测验
    68 {% if name3 == 'zhang' or not (name1 == 'zhang' and name2 == 'zhang') %}
    69 结果:True.
    70 {% else %}
    71 结果:False.
    72 {% endif %}
    复制代码

    playbook 文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat test_jinja2_03.yml 
     2 ---
     3 
     4 # ansible jinja2 测试案例3
     5 - hosts: proxyservers
     6 
     7   tasks:
     8     - name: "test jinja2 03"
     9       template:
    10         src: ./file/test_jinja2_03.conf.j2
    11         dest: /tmp/test_jinja2_03.conf
    复制代码

    文件执行

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

    Ansible Jinja2 使用案例-其它运算

    本例包含:其它运算符

    目录结构

    复制代码
    1 [yun@ansi-manager jinja]$ pwd
    2 /app/ansible_info/jinja
    3 [yun@ansi-manager jinja]$ ll
    4 total 8
    5 drwxrwxr-x 2 yun yun  95 Sep  5 20:00 file
    6 -rw-rw-r-- 1 yun yun 196 Sep  5 20:08 test_jinja2_04.yml
    7 [yun@ansi-manager jinja]$ ll file/
    8 total 12
    9 -rw-rw-r-- 1 yun yun  300 Sep  5 20:00 test_jinja2_04.conf.j2
    复制代码

    配置文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat file/test_jinja2_04.conf.j2 
     2 # 其他运算符
     3 
     4 ## in
     5 左操作数包含于右操作数: {{ 1 in [1,2,3] }}
     6 左操作数包含于右操作数: {{ 10 in [1,2,3] }}
     7 
     8 ## is
     9 {% set pawd = '123abc' %}
    10 Test: {{ pawd is defined }}
    11 
    12 ## ~
    13 {% set name = 'zhang' %}
    14 字符串连接: "Hello" ~ name ~ '!' ~ 123 = {{ "Hello" ~ name ~ '!' ~ 123 }}
    复制代码

    playbook 文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat test_jinja2_04.yml 
     2 ---
     3 
     4 # ansible jinja2 测试案例4
     5 - hosts: proxyservers
     6 
     7   tasks:
     8     - name: "test jinja2 04"
     9       template:
    10         src: ./file/test_jinja2_04.conf.j2
    11         dest: /tmp/test_jinja2_04.conf
    复制代码

    文件执行

    1 [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_04.yml  # 语法检测
    2 [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key -C test_jinja2_04.yml  # 预执行,测试执行
    3 [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

    目录结构

    复制代码
    1 [yun@ansi-manager jinja]$ pwd
    2 /app/ansible_info/jinja
    3 [yun@ansi-manager jinja]$ ll
    4 total 8
    5 drwxrwxr-x 2 yun yun  95 Sep  5 20:00 file
    6 -rw-rw-r-- 1 yun yun 196 Sep  5 20:08 test_jinja2_05.yml
    7 [yun@ansi-manager jinja]$ ll file/
    8 total 12
    9 -rw-rw-r-- 1 yun yun  300 Sep  5 20:00 test_jinja2_05.conf.j2
    复制代码

    配置文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat file/test_jinja2_05.conf.j2 
     2 {# 变量定义 #}
     3 {% set filter01 = -24.5 %}
     4 {% set filter02 = 'abcDEGg' %}
     5 {% set filter03 = "  abCDef G hkIL   " %}
     6 {% set filter04 = ['physics', 'chemistry', 1997, 2000] %}
     7 
     8 # 过滤器 使用
     9 ## 取绝对值
    10 {{ filter01|abs() }} 或者 {{ filter01|abs }}
    11 ## 首字符大写,其他小写
    12 {{ filter02|capitalize() }} 或者 {{ filter02|capitalize }}
    13 ## 去掉两端空格
    14 |{{ filter03|trim() }}| 或者 |{{ filter03|trim }}|
    15 ## 返回序列的第一个
    16 {{ filter04|first() }} 或者 {{ filter04|first }}
    17 ## 将序列变为字符串,可以指定每个元素间加入什么字符,默认空
    18 默认情况: {{ filter04|join() }} 或者 {{ filter04|join }}
    19 加入字符: {{ filter04|join('|') }}
    20 
    21 # Tests 测验 使用
    22 ## 变量是否定义
    23 未定义: {{ filter00 is defined }}
    24 已定义: {{ filter01 is defined }}
    25 ## 变量是否是数字
    26 {{ filter01 is number }} === {{ filter02 is number }}
    27 ## 变量是否是小写
    28 {{ filter02 is lower }}
    29 ## 变量是否是字符串
    30 {{ filter02 is string }}
    31 
    32 ## 变量在 if 中的判断是否已定义
    33 {# ***** 变量已经被定义,直接判断表达式是 True或False ***** #}
    34 {# {% if filter01 %} #}{# 如果变量没有定义,那么执行会报错 #}
    35 {# 由于 filter00 之前未定义,因此这里定义为 false,不然执行会报错【生产中会在 playbook中定义】
    36 {% set filter00 = false %}
    37 {% if filter00 %}
    38 #}
    39 {# ***** 通过判断变量是否被定义,得到到True或False ***** #}
    40 {# {% if filter01 is defined %} #}
    41 {% if filter00 is defined %}
    42 variable is defined
    43 {% else %}
    44 variable is undefined
    45 {% endif %}
    46 
    47 # range 使用
    48 {% for i in range(1,20) %}
    49   server 172.16.1.{{ i }}:80
    50 {% endfor %}
    复制代码

    playbook 文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat test_jinja2_05.yml 
     2 ---
     3 # ansible jinja2 测试案例5
     4 - hosts: proxyservers
     5 
     6   tasks:
     7     - name: "test jinja2 05"
     8       template:
     9         src: ./file/test_jinja2_05.conf.j2
    10         dest: /tmp/test_jinja2_05.conf
    复制代码

    文件执行

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

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

    本例在 ansible 的 playbook 中使用 jinja2.

    目录结构

    1 [yun@ansi-manager jinja]$ pwd
    2 /app/ansible_info/jinja
    3 [yun@ansi-manager jinja]$ ll
    4 total 28
    5 -rw-rw-r-- 1 yun yun 1103 Jan 15 21:06 test_jinja2_06.yml

    playbook 文件

    复制代码
     1 [yun@ansi-manager jinja]$ cat test_jinja2_06.yml 
     2 ---
     3 # 在 playbook 中使用 jinja2 模板
     4 - hosts: proxyservers
     5 
     6 
     7   tasks:
     8     - name: "test_jinja2_06.info create"
     9       file:
    10         path: "/tmp/test_jinja2_06.info"
    11         owner: yun
    12         group: yun
    13         state: touch
    14 
    15     # 这里用了 jinja2 的过滤器,计算,in 判断,赋值,条件判断,循环
    16     - name: "test jinja2 06"
    17       blockinfile:
    18         path: "/tmp/test_jinja2_06.info"
    19         marker: "### {mark} ANSIBLE MANAGED BLOCK jinja2 test ###"
    20         block: |
    21           name: "{{ ansible_eth0['ipv4']['address']|replace('.', '-') }}"
    22           host: "{{ ansible_eth0['ipv4']['address'] }}"
    23           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 }}"
    24           other_count: "{{ 1 in [1,2,3] }}"
    25           ifelse:
    26           {% set name1 = 'zhang' %}
    27           {% if name1 == 'zhang' %}
    28           结果:True.
    29           {% else %}
    30           结果:False.
    31           {% endif %}
    32           loop:
    33           {% for i in range(1,20) %}
    34             server 172.16.1.{{ i }}:80
    35           {% endfor %}
    复制代码

    文件执行

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

    受控机结果查看

    复制代码
     1 [yun@ansi-haproxy01 ~]$ cat /tmp/test_jinja2_06.info 
     2 ### BEGIN ANSIBLE MANAGED BLOCK jinja2 test ###
     3 name: "172-16-1-181"
     4 host: "172.16.1.181"
     5 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"
     6 other_count: "True"
     7 ifelse:
     8 结果:False.
     9 loop:
    10   server 172.16.1.1:80
    11   server 172.16.1.2:80
    12   server 172.16.1.3:80
    13   server 172.16.1.4:80
    14   server 172.16.1.5:80
    15   server 172.16.1.6:80
    16   server 172.16.1.7:80
    17   server 172.16.1.8:80
    18   server 172.16.1.9:80
    19   server 172.16.1.10:80
    20   server 172.16.1.11:80
    21   server 172.16.1.12:80
    22   server 172.16.1.13:80
    23   server 172.16.1.14:80
    24   server 172.16.1.15:80
    25   server 172.16.1.16:80
    26   server 172.16.1.17:80
    27   server 172.16.1.18:80
    28   server 172.16.1.19:80
    29 ### END ANSIBLE MANAGED BLOCK jinja2 test ###
    复制代码

    以上!

  • 相关阅读:
    VBS控制鼠标移动和点击(附源代码下载)
    用VBS控制鼠标的实现代码(获取鼠标坐标、鼠标移动、鼠标单击、鼠标双击)
    vbs鼠标方法——模拟鼠标按键
    vbs 获取当前目录的实现代码
    如何在VBS脚本中显示“选择文件对话框”或“选择目录对话框”
    loadrunner使用socket协议来实现客户端对服务器产生压力实例。(通过发送心跳包,达到连接多个客户端的目的)
    loadunner使用socket协议来实现多客户端连接同一服务器脚本(使用到IP欺骗技术)
    Loadrunner中参数和变量的使用
    LoadRunner学习知多少--IP欺骗使用
    Linux下tar bz gz等压缩包的压缩和解压
  • 原文地址:https://www.cnblogs.com/shetao/p/14338732.html
Copyright © 2020-2023  润新知