Ansible的模板

                                              作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.Ansible模板与Jinjia2快速入门

1.模板概述

模板的概念在很多技术栈都有用到,就是基于一个目标创造一个实体。有点类似于类和实例的关系。

Ansible和helm一样,模板语法采用了Jinjia2语言,支持变量,变量文件,参数,条件判断,流程控制等特性。


如上所示,Ansible默认使用的Jinja版本是3.0.3
[root@worker232 yinzhengjie]# ansible --version | grep jinja
  jinja version = 3.0.3
[root@worker232 yinzhengjie]# 

2.Jinjia2语言概述

Jinjia2是Python环境一个被广泛引用的模板引擎, 它的设计思想来源于Django的模板引擎,并扩展了其语法和系列强大的功能。

Jinjia2的特点:
	- 沙箱中执行;
	- 强大的HTML自动转义系统保护免受XSS攻击;
	- 模板继承;
	- 及时编译最优的Python代码;
	- 可选提前编译模板的时间;
	- 易于调试,异常的行数直接指向模板中的对应行;
	- 可配置的语法;


参考链接:
	https://docs.jinkan.org/docs/jinja2/

3.Jinjia2的数据类型

数据类型 描述
字符串 使用单引号或双引号引起来。
数值型 包括整数,浮点数,有小数点表示浮点数,在Python中,1和1.0含义是不一样的。
列表 [A,B,C,D]
元祖 (X,Y,Z)
字典
布尔 true|false
Jinjia2支持的数据类型如上表所示。	

4.Jinjia2的运算符

运算符种类 示例 描述
算数运算符 +、-、*、/、//、%、** 其中2**3表示2的3次方,结果为8。
比较运算符 ==、!=、>、>=、<、<= 一般用于比较。
逻辑运算符 or、and、not 与或非
布尔运算符 true、false 判断真假
如上表所示,表示Jinjia2常用的运算符。

5.Jinjia2的if条件判断

单分支语句:
    {% if EXPR %}
    ...
    {% endif %}
    
    
双分支语句:  
    {% if EXPR %}
    ...
    {% else %}
    ...
    {% endif %}
    
    
多分支语句:
    {% if EXPR %}
    ...
    {% elif EXPR %}
    ...
    {% else %}
    ...
    {% endif %}

6.Jinjia的流程控制

{% for i in EXPR %}
...
{% endfor %}

二.template的基本替换

1.template的存放路径

template文件建议存放在Playbook文件同级目录的templates目录下,且以".j2"结尾。

这样Playbook中使用模板文件时,就不需要指定模板文件路径啦~

2.template的存放路径示例

	1.查看目录结果
[root@worker232 01-case-demo]# tree 
.
├── case-demo.yaml
└── templates
    └── test.j2

1 directory, 2 files
[root@worker232 01-case-demo]# 


	2.编写模板文件
[root@worker232 01-case-demo]# cat templates/test.j2 
string ---> {{ name }} --- {{ name * 3 }}

int ---> {{ age }} --- {{ age + 5 }} --- {{ age - 5  }} --- {{ age * 5 }} --- {{ age / 5 }} --- {{ age % 5 }}

float ---> {{ pi }} --- {{ pi*100 }}

facts ---> {{ ansible_default_ipv4.address }}
[root@worker232 01-case-demo]# 


	3.编写Playbook
[root@worker232 01-case-demo]# cat case-demo.yaml 
- hosts: 10.0.0.231
  gather_facts: yes
  vars:
    name: "尹正杰"
    age: 20
    pi: 3.1415926
  tasks:
    - name: t1
      # 在"tmplates/test.j2"会加载我们定义的变量,并将输出结果放在远程主机的"/tmp/ansible-case-damo01.log"纹路下
      template: src=test.j2 dest=/tmp/ansible-case-damo01-template.log
    - name: t2
      # copy模块仅用于拷贝文件,并不会加载变量模板哟
      copy: src=./templates/test.j2 dest=/tmp/ansible-case-damo01-copy.log
[root@worker232 01-case-demo]# 


	4.执行剧本测试
[root@worker232 01-case-demo]# ansible-playbook case-demo.yaml

	5.远端主机观察数据文件
[root@master231 ~]# ll  /tmp/ansible-case-damo01*
-rw-r--r-- 1 root root 238 Jan 14 21:06 /tmp/ansible-case-damo01-copy.log
-rw-r--r-- 1 root root 162 Jan 14 21:06 /tmp/ansible-case-damo01-template.log
[root@master231 ~]# 

三.template的流程控制

1.template的for循环和if判断

template的流程控制主要针对的是if多分支语句和for循环。

参考链接:
	https://docs.jinkan.org/docs/jinja2/templates.html#if
	https://docs.jinkan.org/docs/jinja2/templates.html#for

2.for循环和if语句结合案例

	1.文件目录组织结构
[root@worker232 02-case-demo]# tree 
.
├── case-demo.yaml
└── templates
    └── test.j2

1 directory, 2 files
[root@worker232 02-case-demo]# 


	2.编写模板文件
[root@worker232 02-case-demo]# cat templates/test.j2 
{% if name == 'yinzhengjie' %}
My name is YinZhengJie
{% endif %}

{% if age > 18 %}
  大于18岁,做你想做的事情。
{% elif age == 18 %}
  18岁,恭喜你成年啦~
{% else %}
  未成年,要听妈妈的话~
{% endif %}


{% for i in range(5,10) %}
  {{ i }} x 2 = {{ i*2 }}
{% endfor %}


{% for i in cluster %}
 {% if i.master == true %} 
   {{ i.ip }}:{{ i.port }} 角色:  leader 
 {% else %} 
   {{ i.ip }}:{{ i.port }} 角色:  follower 
 {% endif %}
{% endfor %}

[root@worker232 02-case-demo]# 


	3.编写剧本
[root@worker232 02-case-demo]# cat case-demo.yaml 
- hosts: 10.0.0.231
  gather_facts: no
  vars:
    name: "yinzhengjie"
    age: 20
    cluster:
    - {id: 91, ip: 10.0.0.91, port: 2181, master: false}
    - {id: 92, ip: 10.0.0.92, port: 2181, master: true}
    - {id: 93, ip: 10.0.0.93, port: 2181, master: false}

  tasks:
    - name: t1
      template: src=test.j2 dest=/tmp/ansible-case-damo02-template.log
[root@worker232 02-case-demo]# 


	4.执行剧本
[root@worker232 02-case-demo]# ansible-playbook case-demo.yaml 
	
	5.远端主机查看文件
[root@master231 ~]# ll /tmp/ansible-case-damo02-template.log 
-rw-r--r-- 1 root root 257 Jan 14 22:02 /tmp/ansible-case-damo02-template.log
[root@master231 ~]# 

3.for循环嵌套

	1.目录组织结构
[root@worker232 03-case-demo]# tree 
.
├── case-demo.yaml
└── templates
    └── test.j2

1 directory, 2 files
[root@worker232 03-case-demo]# 
[root@worker232 03-case-demo]# cat templates/test.j2 
{% for city in province %}
  {% for i in city  %}
城市名称: {{ i }}
  {% endfor %}
{% endfor %}


{% for i in xiuxian %}
  {% for j in i  %}
动漫名称: {{ j }}
  {% endfor %}
{% endfor %}


{% for i in hobby %}
   {{ i.name }}的爱好: {% for j in i.hobby %} {{ j }} {% endfor %}
{% endfor %}

[root@worker232 03-case-demo]# 


	2.编写剧本
[root@worker232 03-case-demo]# cat case-demo.yaml 
- hosts: 10.0.0.231
  gather_facts: no
  vars:
    province: [ [北京,上海,深圳], [西安,武汉,成都]]
    xiuxian:
      - ["凡人修仙传","仙逆"]
      - ["一念永恒","完美世界","斗破苍穹","遮天"]
    hobby:
      - {id: 1001, name: 孙悟空, hobby: [桃子,七仙女,打妖怪]}
      - {id: 1002, name: 猪八戒, hobby: [高老庄,嫦娥,吃饭]}

  tasks:
    - name: t1
      template: src=test.j2 dest=/tmp/ansible-case-damo03-template.log
[root@worker232 03-case-demo]# 


	3.执行剧本
[root@worker232 03-case-demo]# ansible-playbook case-demo.yaml 


	4.查看远程主机文件内容
[root@master231 ~]# ll /tmp/ansible-case-damo03-template.log
-rw-r--r-- 1 root root 420 Jan 14 22:36 /tmp/ansible-case-damo03-template.log
[root@master231 ~]# 

posted @ 2025-01-17 00:24  尹正杰  阅读(116)  评论(0)    收藏  举报