主机规划
主机名称 | 操作系统版本 | 内网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 提权)。
1 | # 使用一个专门的用户,避免直接使用root用户 |
Ansible 配置清单Inventory
之后文章都是如下主机配置清单
1 | [yun@ansi-manager ansible_info]$ pwd |
Jinja2 模板概述
官网地址
1 | 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' %} |
注释
1 | {# ... #}:要把模板中一行或多行注释掉,默认的注释语法。 |
变量
1 | {{ ... }}:把表达式的结果打印到模板上。 |
你可以使用点( . )来访问变量的属性,作为替代,也可以使用所谓的“下标”语 法( [] )。如下示例:
1 | {{ foo.bar }} |
1 | 示例:{{ a_variable }}、{{ foo.bar }}、{{ foo['bar'] }} |
花括号不是变量的一部分,而是打印语句的重要一部分。
条件判断
Jinja 中的 if 语句可比 Python 中的 if 语句。
在最简单的形式中,你可以测试一个变量是否未定义,为空或 false:
简单形式:
1 | {% if 条件表达式 %} |
多分支形式:
1 | {% if 条件表达式 %} |
循环语句
for 循环语句
1 | {% for user in users %} |
空白控制
默认配置中,模板引擎不会对空白做进一步修改,所以每个空白(空格、制表符、换行符 等等)都会原封不动返回。
此外,你也可以手动剥离模板中的空白。当你在块(比如一个 for 标签、一段注释或变量表达式)的开始或结束放置一个减号( - ),可以移除块前或块后的空白。如下:
1 | {% for item in range(1,9) -%} |
输出的所有元素前后不会有任何空白,输出会是 123456789 。
转义
有时想要或甚至必要让 Jinja 忽略部分,而不会把它作为变量或块来处理。那么有如下两种方式:
单行转义:简单方式
需求:把 “{ {“ 作为原始字符串使用,而不是一个变量的开始部分。
1 | {{ '{{' }} |
多行转义:
需求:将如下一块代码不进行任何处理,直接打印输出。
1 | {% raw %} |
HTML 手动转义
如果你有一个可能包含 >、<、& 或 " 字符的变量,那么你需要转义它;否则会被 HTML 使用。
转义通过用管道传递到过滤器 |e 来实现,如:
1 | {{ user.username|e }} 。 |
宏定义
宏类似常规编程语言中的函数。它们用于把常用行为作为可重用的函数,取代手动重复的工作。
如果宏在不同的模板中定义,你需要首先使用 import 。
示例:
1 | ## 宏变量顺序和具体内容变量顺序一致「推荐写法」 |
宏变量解释:
name:默认为空,引用时必填
value:默认为空字符串
type:默认为 text
size:默认为 20
在命名空间中,宏之后可以像函数一样调用:
1 | <p>{{ input('username') }}</p> ## 结果为:<p><input name="username" value="" type="text" size="20"></p> |
import 导入
导入宏,并在不同的模板中使用。
1 | # 示例:导入 nginx 变量 |
过滤器
变量可以通过 过滤器 修改。过滤器与变量用管道符号( | )分割,并且也可以用圆括号传递可选参数。多个过滤器可以链式调用,前一个过滤器的输出会被作为后一个过滤器的输入。
1 | 例如 {{ name|striptags|title }}、{{ list|join(', ') }} |
内置过滤器清单
1 | http://docs.jinkan.org/docs/jinja2/templates.html#builtin-filters |
ansible 自带过滤器
1 | https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html?highlight=filter |
Tests 测验
除了过滤器,所谓的「Tests」也是可用的。要测验一个变量或表达式,你要在变量后加上一个 is 和 Tests 的名称。当然 Tests 也可以接受参数。
内置测验清单
1 | http://docs.jinkan.org/docs/jinja2/templates.html#builtin-tests |
ansible 自带测验
1 | https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html |
算术
Jinja 允许用计算值。这在模板中很少用到,但是为了完整性允许其存在。
支持如下运算符:
1 | +:把两个对象加到一起。如:{{ 1 + 1 }} 等于 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) 。
其它运算符
1 | in:运行序列/映射包含检查。如果左操作数 包含于 右操作数,返回 true 。比如 {{ 1 in [1,2,3] }} 会返回 true。 |
全局函数
range([start], stop[, step]):返回一个包含整等差级数的列表。
Ansible Jinja2 使用案例-常见功能
本例包含:注释、赋值、变量、条件判断、循环、空白控制、转义。
目录结构
1 | [yun@ansi-manager jinja]$ pwd |
配置文件
1 | [yun@ansi-manager jinja]$ cat file/test_jinja2_01.conf.j2 # 涉及的文件 |
playbook 文件
1 | [yun@ansi-manager jinja]$ cat test_jinja2_01.yml # playbook 文件 |
文件执行
1 | [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_01.yml # 语法检测 |
Ansible Jinja2 使用案例-宏与导入
本例包含:宏、from 导入
目录结构
1 | [yun@ansi-manager jinja]$ pwd |
宏文件和配置文件
1 | [yun@ansi-manager jinja]$ cat file/test_jinja2_macro.info |
playbook 文件
1 | [yun@ansi-manager jinja]$ cat test_jinja2_02.yml |
文件执行
1 | [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_02.yml # 语法检测 |
Ansible Jinja2 使用案例-算术、比较、逻辑
本例包含:算术、比较、逻辑与其它运算符
目录结构
1 | [yun@ansi-manager jinja]$ pwd |
配置文件
1 | [yun@ansi-manager jinja]$ cat file/test_jinja2_03.conf.j2 |
playbook 文件
1 | [yun@ansi-manager jinja]$ cat test_jinja2_03.yml |
文件执行
1 | [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_03.yml # 语法检测 |
Ansible Jinja2 使用案例-其它运算
本例包含:其它运算符
目录结构
1 | [yun@ansi-manager jinja]$ pwd |
配置文件
1 | [yun@ansi-manager jinja]$ cat file/test_jinja2_04.conf.j2 |
playbook 文件
1 | [yun@ansi-manager jinja]$ cat test_jinja2_04.yml |
文件执行
1 | [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_04.yml # 语法检测 |
Ansible Jinja2 使用案例-过滤器和测验
本例包含:filters、tests 和 range。
内置过滤清单
1 | http://docs.jinkan.org/docs/jinja2/templates.html#builtin-tests |
内置测验清单
1 | http://docs.jinkan.org/docs/jinja2/templates.html#tests |
目录结构
1 | [yun@ansi-manager jinja]$ pwd |
配置文件
1 | [yun@ansi-manager jinja]$ cat file/test_jinja2_05.conf.j2 |
playbook 文件
1 | [yun@ansi-manager jinja]$ cat test_jinja2_05.yml |
文件执行
1 | [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_05.yml # 语法检测 |
Ansible Jinja2 使用案例-在playbook中使用
本例在 ansible 的 playbook 中使用 jinja2.
目录结构
1 | [yun@ansi-manager jinja]$ pwd |
playbook 文件
1 | [yun@ansi-manager jinja]$ cat test_jinja2_06.yml |
文件执行
1 | [yun@ansi-manager jinja]$ ansible-playbook -b -i ../hosts_key --syntax-check test_jinja2_06.yml # 语法检测 |
受控机结果查看
1 | [yun@ansi-haproxy01 ~]$ cat /tmp/test_jinja2_06.info |