网站建设素材包,网页做网站的尺寸,wordpress 作者头像,如何在各大网站发布信息环境
控制节点#xff1a;Ubuntu 22.04Ansible 2.10.8管理节点#xff1a;CentOS 8
filter
使用filter可以对数据做操作#xff0c;比如把JSON数据转换为YAML数据#xff0c;从URL中解析出hostname#xff0c;提取字符串的SHA1哈希值#xff0c;做数学运算#xff0c…环境
控制节点Ubuntu 22.04Ansible 2.10.8管理节点CentOS 8
filter
使用filter可以对数据做操作比如把JSON数据转换为YAML数据从URL中解析出hostname提取字符串的SHA1哈希值做数学运算等等。可以使用Ansible特有的filter也可以使用jinja2移植的标准filter。
因为templating发生在Ansible的控制节点而不是目标节点所以filter运行在控制节点并在本地转换数据。
处理未定义变量
提供缺省值
创建文件 test1.yml 如下
---
- hosts: alltasks:- name: task1debug:msg: Hello {{ var1 }}运行结果如下
➜ temp1105_2 ansible-playbook test1.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
fatal: [192.168.1.55]: FAILED! {msg: The task includes an option with an undefined variable. The error was: var1 is undefined\n\nThe error appears to be in /root/temp/temp1105_2/test1.yml: line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: task1\n ^ here\n}PLAY RECAP *****************************************************************************************
192.168.1.55 : ok1 changed0 unreachable0 failed1 skipped0 rescued0 ignored0 这是因为变量 var1 未定义。
为避免出错可以使用jinja2的 default filter
---
- hosts: alltasks:- name: task1debug:msg: Hello {{ var1 | default(ABC) }}, {{var2 | default(\XYZ\)}}, {{ var3 | default(123) }}其中
var1 default值是单引号引起来的字符串var2 default值是双引号引起来的字符串所以用 \ 来转义var3 default值是数值不需要用引号
运行结果如下
➜ temp1105_2 ansible-playbook test1.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
ok: [192.168.1.55] {msg: Hello ABC, XYZ, 123
}PLAY RECAP *****************************************************************************************
192.168.1.55 : ok2 changed0 unreachable0 failed0 skipped0 rescued0 ignored0 注对于role也可以在其 defaults/main.yml 文件里给该role的变量定义缺省值。
如果原值evaluate为false或者空字符串则使用default时需要将其第二个参数设置为true默认值是false
......msg: aaa {{ | default(empty string, true) }} bbb
......运行结果如下
......msg: aaa empty string bbb
......注如果不加第二个参数则不会替换为缺省值。
变量为空值
创建文件 test2.yml 如下
---
- hosts: alltasks:- name: task1debug:msg: aaa {{ item.var1 }} bbb {{ item.var2 | default(omit) }}loop:- var1: Tomvar2: 20- var1: Jerry其中item1指定了 var1 和 var2 而item2只指定了 var1 。
运行结果如下
➜ temp1105_2 ansible-playbook test2.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
ok: [192.168.1.55] (item{var1: Tom, var2: 20}) {msg: aaa Tom bbb 20
}
ok: [192.168.1.55] (item{var1: Jerry}) {msg: aaa Jerry bbb __omit_place_holder__ae2509bf44427378895b86e1e65511fbaaf58727
}PLAY RECAP *****************************************************************************************
192.168.1.55 : ok2 changed0 unreachable0 failed0 skipped0 rescued0 ignored0 可见指定了 default(omit) 则变量默认值为空若打印其值则输出一个占位符。
注对于链式filter官网上说要用 {{ foo | default(None) | some_filter or omit }} 的形式比如
msg: {{ var1 | default(None) | lower or omit }}运行结果如下 msg: none但我试了一下如果不这么做比如
msg: {{ var1 | default(omit) | lower }}也不报错运行结果如下 msg: __omit_place_holder__2212ea218f1e07f0070e5184cf11ebf71e3e5e9e变量必须有值
如果配置了 DEFAULT_UNDEFINED_VAR_BEHAVIOR 为 false 则变量允许为空值。此时如果想要强制变量不得为空值则可以使用 mandatory filter比如
{{ var1 | mandatory }}根据不同值true/false/null做判断
注 ternary 是 三元 的意思。
创建文件 test6.yml 如下
---
- hosts: alltasks:- name: task1debug:msg: {{ (var1 a) | ternary(111, 222) }}vars:- var1: a 本例中由于 var1 a 是true所以会打印 111
➜ temp1105_2 ansible-playbook test6.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
ok: [192.168.1.55] {msg: 111
}PLAY RECAP *****************************************************************************************
192.168.1.55 : ok2 changed0 unreachable0 failed0 skipped0 rescued0 ignored0 创建文件 test7.yml 如下
---
- hosts: alltasks:- name: task1debug:msg: {{ var1 | ternary(111, 222, omit) }}vars:- var1: abc- name: task2debug:msg: {{ var2 | ternary(111, 222, omit) }}vars:- var2: false- name: task3debug:msg: {{ var3 | ternary(111, 222, omit) }}vars:- var3: null运行结果如下
➜ temp1105_2 ansible-playbook test7.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
ok: [192.168.1.55] {msg: 111
}TASK [task2] ***************************************************************************************
ok: [192.168.1.55] {msg: 222
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55] {msg: Hello world!
}PLAY RECAP *****************************************************************************************
192.168.1.55 : ok4 changed0 unreachable0 failed0 skipped0 rescued0 ignored0 var1 有值且不等于 false 表示truevar2 其值为 false 注意没有引号否则是字符串表示falsevar3 其值为 null 注意打印出了 Hello world!
管理数据类型
检测数据类型
创建文件 test8.yml 如下
---
- hosts: alltasks:- name: task1debug:msg: {{ abc | type_debug }}, {{ 123 | type_debug }}, {{ 0.5 | type_debug }}, {{ true | type_debug }}运行结果如下
➜ temp1105_2 ansible-playbook test8.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
ok: [192.168.1.55] {msg: str, int, float, bool
}PLAY RECAP *****************************************************************************************
192.168.1.55 : ok2 changed0 unreachable0 failed0 skipped0 rescued0 ignored0 可见
abc 类型为 str123 类型为 int0.5 类型为 floattrue 类型为 bool
强制类型转换
创建文件 test9.yml 如下
---
- hosts: alltasks:- name: task1debug:msg: {{ var1 | int | type_debug }}, {{ var2 | float | type_debug }}, {{ var3 |bool | type_debug }}, {{ var4 | string | type_debug }}vars:- var1: 123- var2: 0.5- var3: true- var4: 456运行结果如下
➜ temp1105_2 ansible-playbook test9.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
ok: [192.168.1.55] {msg: int, float, bool, str
}PLAY RECAP *****************************************************************************************
192.168.1.55 : ok2 changed0 unreachable0 failed0 skipped0 rescued0 ignored0 JSON和YAML
to_json 转换为JSON格式to_nice_json 转换为可读的JSON格式加上换行缩进等to_yaml 转换为YAML格式to_nice_yaml 转换为可读的YAML格式加上换行缩进等
创建文件 test12.yml 如下
---
- hosts: alltasks:- name: task1template:src: /tmp/src1dest: /tmp/dest1- name: task2template:src: /tmp/src2dest: /tmp/dest2- name: task3template:src: /tmp/src3dest: /tmp/dest3- name: task4template:src: /tmp/src4dest: /tmp/dest4/tmp/src1 如下
{{ ansible_facts[default_ipv4] | to_json }}/tmp/src2 如下
{{ ansible_facts[default_ipv4] | to_nice_json }}/tmp/src3 如下
{{ ansible_facts[default_ipv4] | to_yaml }}/tmp/src4 如下
{{ ansible_facts[default_ipv4] | to_nice_yaml }}运行结果如下
➜ temp1105_2 ansible-playbook test12.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
changed: [192.168.1.55]TASK [task2] ***************************************************************************************
changed: [192.168.1.55]TASK [task3] ***************************************************************************************
changed: [192.168.1.55]TASK [task4] ***************************************************************************************
changed: [192.168.1.55]PLAY RECAP *****************************************************************************************
192.168.1.55 : ok5 changed4 unreachable0 failed0 skipped0 rescued0 ignored0 运行结束后到目标机器上查看。
/tmp/dest1 如下
{gateway: 192.168.1.1, interface: ens33, address: 192.168.1.55, broadcast: 192.168.1.255, netmask: 255.255.255.0, network: 192.168.1.0, macaddress: 00:0c:29:12:a6:b7, mtu: 1500, type: ether, alias: ens33}/tmp/dest2 如下
{address: 192.168.1.55,alias: ens33,broadcast: 192.168.1.255,gateway: 192.168.1.1,interface: ens33,macaddress: 00:0c:29:12:a6:b7,mtu: 1500,netmask: 255.255.255.0,network: 192.168.1.0,type: ether
}/tmp/dest3 如下
{address: 192.168.1.55, alias: ens33, broadcast: 192.168.1.255, gateway: 192.168.1.1,interface: ens33, macaddress: 00:0c:29:12:a6:b7, mtu: 1500, netmask: 255.255.255.0,network: 192.168.1.0, type: ether}/tmp/dest4 如下
address: 192.168.1.55
alias: ens33
broadcast: 192.168.1.255
gateway: 192.168.1.1
interface: ens33
macaddress: 00:0c:29:12:a6:b7
mtu: 1500
netmask: 255.255.255.0
network: 192.168.1.0
type: ether注 to_yaml 和 to_nice_yaml 默认每行包含80个字符当超过80字符后遇到空格就会换行可以指定 width 选项比如
{{ ansible_facts[default_ipv4] | to_yaml(width500) }}结果如下
{address: 192.168.1.55, alias: ens33, broadcast: 192.168.1.255, gateway: 192.168.1.1, interface: ens33, macaddress: 00:0c:29:12:a6:b7, mtu: 1500, netmask: 255.255.255.0, network: 192.168.1.0, type: ether}可以指定 indent 选项默认值貌似是4比如
{{ ansible_facts[default_ipv4] | to_nice_json(indent8) }}结果如下
{address: 192.168.1.55,alias: ens33,broadcast: 192.168.1.255,gateway: 192.168.1.1,interface: ens33,macaddress: 00:0c:29:12:a6:b7,mtu: 1500,netmask: 255.255.255.0,network: 192.168.1.0,type: ether
}可见缩进值变为8了。
from_json 读取已知的JSON数据from_yaml 读取已知的YAML数据
在目标机器上创建 json1.json 如下
{Name: Tom,Age: 20,Sports:[Football, Swimming]
}在目标机器上创建 yaml1.yml 如下
Name: Tom
Age: 20
Sports:- Football- Swimming创建文件 test14.yml 如下
---
- hosts: alltasks:- name: task1shell: cat /tmp/json1.jsonregister: result1- name: task2debug:msg: {{ result1.stdout | type_debug }}- name: task3debug:msg: {{ result1.stdout | from_json | type_debug }}- name: task4shell: cat /tmp/yaml1.ymlregister: result2- name: task5debug:msg: {{ result2.stdout | type_debug }}- name: task6debug:msg: {{ result2.stdout | from_yaml | type_debug }}运行结果如下
➜ temp1105_2 ansible-playbook test14.ymlPLAY [all] *****************************************************************************************TASK [Gathering Facts] *****************************************************************************
ok: [192.168.1.55]TASK [task1] ***************************************************************************************
changed: [192.168.1.55]TASK [task2] ***************************************************************************************
ok: [192.168.1.55] {msg: AnsibleUnsafeText
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55] {msg: dict
}TASK [task4] ***************************************************************************************
changed: [192.168.1.55]TASK [task5] ***************************************************************************************
ok: [192.168.1.55] {msg: AnsibleUnsafeText
}TASK [task6] ***************************************************************************************
ok: [192.168.1.55] {msg: dict
}PLAY RECAP *****************************************************************************************
192.168.1.55 : ok7 changed2 unreachable0 failed0 skipped0 rescued0 ignored0 可见如果不加 from_json 或 from_yaml 则读取的是字符串 AnsibleUnsafeText 加上from_json 或 from_yaml 则读取为 dict 。
随机数
创建文件 test15.yml 如下
---
- hosts: alltasks:- name: task1debug:msg: {{ 60 | random }}运行结果如下 msg: 4多次运行结果也不同。
注意取值范围是0到60左闭右开。
如果想指定起始值可以用 start 选项 msg: {{ 60 | random(start55) }}则取值范围是55到60左闭右开。
如果要求取值是特定值的整倍数可以用 step 选项 msg: {{ 60 | random(step20) }}则取值只能是0或20或40。
如果想在多个目标机器上各自产生不同的随机数但要求每个机器上的随机数多次运行结果不变幂等性则可以添加 seed 选项使用该种子来产生随机数注意seed的值不要变 msg: {{ 60 | random(seedinventory_hostname) }}msg: 50多次运行产生的随机数保持不变。
数学运算
logpowrootabsround
创建文件 test16.yml 如下
---
- hosts: alltasks:- name: task1debug:msg: {{ 100 | log(10) }}, {{ 2 | pow(10) }}, {{ 216 | root(3) }}, {{ -1.5 | abs }}, {{ 12.34 | round }}运行结果如下 msg: 2.0, 1024.0, 5.999999999999999, 1.5, 12.0注释
comment 将内容注释。默认的注释符是 # 可以指定不同语言来做注释。
创建文件 test17.yml 如下
---
- hosts: alltasks:- name: task1template:src: /tmp/src1dest: /tmp/dest1- name: task2template:src: /tmp/src2dest: /tmp/dest2- name: task3template:src: /tmp/src3dest: /tmp/dest3- name: task4template:src: /tmp/src4dest: /tmp/dest4- name: task5template:src: /tmp/src5dest: /tmp/dest5创建文件 /tmp/src1 如下
{{ aaa | comment }}创建文件 /tmp/src2 如下
{{ bbb | comment(c) }}创建文件 /tmp/src3 如下
{{ ccc | comment(cblock) }}创建文件 /tmp/src4 如下
{{ ddd | comment(erlang) }}创建文件 /tmp/src5 如下
{{ eee | comment(xml) }}运行结束后到目标机器上查看
/tmp/dest1 如下
#
# aaa
#/tmp/dest2 如下
//
// bbb
///tmp/dest3 如下
/*** ccc**//tmp/dest4 如下
%
% ddd
%/tmp/dest5 如下
!---- eee-
--字符串操作
quote 给值加上引号 shell: echo {{ var1 | quote }} /tmp/a.txtvars:var1: a\nb\nc运行结束后目标机器 /tmp/a.txt 如下
a
b
c如果没有 quote 则会报错。
join 连接字符串 debug:msg: {{ [a, b, c] | join( ) }}运行结果如下 msg: a b csplit 切割字符串 debug:msg: {{ a,b,c | split(,) }}注需要升级到2.11我用的是2.10会报错。
b64encode Base64 encode debug:msg: {{ abcdefg | b64encode }}运行结果如下 msg: YWJjZGVmZwb64decode Base64 decode debug:msg: {{ YWJjZGVmZw | b64decode }}运行结果如下 msg: abcdefgUUID
to_uuid 创建UUID debug:msg: {{ abcdefg | to_uuid }}运行结果如下 msg: aeb26d4d-43ec-587e-b3a8-67b6ca88a4df参考
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_filters.htmlhttps://jinja.palletsprojects.com/en/latest/templates