文章目录
Ansible------lookup,过滤器
Ansible Playbook允许用户使用自定义变量,不过当变量过大,或者太复杂时,无论是在Playbook中通过vars定义,还是在单独的变量文件中定义,可读性都比较差
lookup能够读取Ansible管理节点上文件系统的文件内容到Ansible变量中,也可以读取配置的数据库中的内容
lookup读取文件
下面是lookup基本使用方法,将Ansible管理节点上的文件data/plain.txt的内容读取出来,并赋值给变量"contents"。"file"告诉lookup读取对象的类型是File,直接读取文件内容,无须做特别的处理
shell
[root@csq ~]# mkdir data
[root@csq ~]# echo "csqcsqcsq" > data/plain.txt
[root@csq ~]# vim test.yml
- hosts: all
remote_user: root
gather_facts: false
vars:
contents: "{{ lookup('file','/root/data/plain.txt') }}"
tasks:
- debug: msg="the value of /root/data/plain.txt is {{ contents }}"
# 执行结果
TASK [debug] **********************************************************************************
ok: [192.168.200.20] => {
"msg": "the value of /root/data/plain.txt is csqcsqcsq"
}
ok: [192.168.200.30] => {
"msg": "the value of /root/data/plain.txt is csqcsqcsq"
}
lookup生成随机密码
如果密码文件/tmp/password/kitty不存在,lookup会生成长度为5的随机密码,存储在文件中。如果密码文件存在,那么直接读取该文件中的内容作为密码
shell
[root@csq ~]# vim a.yml
- hosts: all
remote_user: root
vars:
password: "{{ lookup('password','/tmp/password/kitty length=5') }}"
tasks:
- debug: var=password
# 执行结果
TASK [debug] **********************************************************************************
ok: [192.168.200.20] => {
"password": "TWLDK"
}
ok: [192.168.200.30] => {
"password": "TWLDK"
}
lookup读取环境变量
env类型的lookup可以读取Linux上的环境变量
shell
[root@csq ~]# vim c.yml
tasks:
- hosts: test
remote_user: root
tasks:
- name: env
debug: msg=" {{lookup('env','HOME') }} 是一个环境变量"
# 执行结果
[root@csq ~]# ansible-playbook c.yml
PLAY [test] *************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.20]
TASK [env] **************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": " /root 是一个环境变量"
}
PLAY RECAP **************************************************************************************************************************
192.168.200.20 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
lookup读取Linux命令的执行结果
pipe类型的lookup可以将Linux上命令的执行结果读取到Ansible中
shell
[root@csq ~]# vim d.yml
- hosts: all
remote_user: root
tasks:
- name: 读取管理节点的Linux命令执行结果
debug: msg="{{ lookup('pipe','date') }} 这是该命令执行的结果"
# 执行结果
[root@csq ~]# ansible-playbook d.yml
PLAY [all] **************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.30]
ok: [192.168.200.20]
TASK [读取管理节点的Linux命令执行结果] **********************************************************************************************
ok: [192.168.200.20] => {
"msg": "2024年 05月 02日 星期四 11:42:35 CST 这是该命令执行的结果"
}
ok: [192.168.200.30] => {
"msg": "2024年 05月 02日 星期四 11:42:35 CST 这是该命令执行的结果"
}
PLAY RECAP **************************************************************************************************************************
192.168.200.20 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.200.30 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
lookup读取template变量替换后的文件
template类型的lookup可以将一个template文件经过变量替换后的内容读取到Ansible中。如果在template文件中有未定义的变量,则会报错
shell
# template文件
[root@csq ~]# vim template1.j2
hostname: {{ansible_hostname}}
# playbook文件
[root@csq ~]# vim e.yml
- hosts: all
remote_user: root
tasks:
- name: 读取template
debug: msg="{{ lookup('template','/root/template1.j2') }} 这是template.j2的变量"
# 执行结果
[root@csq ~]# ansible-playbook e.yml
PLAY [all] **************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.30]
ok: [192.168.200.20]
TASK [读取template] *****************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "hostname: podman\n 这是template.j2的变量"
}
ok: [192.168.200.30] => {
"msg": "hostname: localhost\n 这是template.j2的变量"
}
PLAY RECAP **************************************************************************************************************************
192.168.200.20 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.200.30 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
lookup读取配置文件
lookup支持读取两种类型的配置文件;ini和java的properties
ini类型的lookup默认读取配置文件类型是ini
shell
# ini文件
[root@csq ~]# vim data/users.ini
[test1]
user=csq
password=111
[test2]
user=zhw
password=000
# playbook文件
[root@csq ~]# vim f.yml
- name:
- hosts: test
remote_user: root
tasks:
- debug:
msg: "test1 user = {{ lookup('ini','user section=test1 file=/root/data/users.ini') }}"
- debug:
msg: "test2 user = {{ lookup('ini','user section=test2 file=/root/data/users.ini') }}"
# 执行结果
[root@csq ~]# ansible-playbook f.yml
PLAY [test] *************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.20]
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "test1 user = csq"
}
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "test2 user = zhw"
}
PLAY RECAP **************************************************************************************************************************
192.168.200.20 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
读取properties类型文件时,需要加一个额外的参数来告诉lookup,这是properties类型的文件
shell
# user.properties文件
[root@csq ~]# vim data/user.properties
user.name=csq
user.pass=111
# playbook文件
[root@csq ~]# vim g.yml
- name: dd
- hosts: test
remote_user: root
tasks:
- debug:
msg: "user.name is {{ lookup('ini','user.name type=properties file=/root/data/user.properties') }}"
# 执行结果
[root@csq ~]# ansible-playbook g.yml
PLAY [test] *************************************************************************************************************************
TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.200.20]
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "user.name is csq"
}
PLAY RECAP **************************************************************************************************************************
192.168.200.20 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ini类型参数格式:
shell
lookup('ini','key [type=<properties|ini>] [section=section] [file=file.ini] [re=true] [default=<defaultvalue>]')
# 每个参数都是可选的,没有传入的参数会使用默认值
参数名 | 默认值 | 参数含义 |
---|---|---|
type | ini | 文件的类型 |
file | ansible.ini | 加载文件的名字 |
section | global | 默认的在哪个section里面查找key |
re | False | key的正则表达式 |
default | empty string | key不存在时的返回值 |
lookup读取DNS解析的值
dig类型的lookup可以向DNS服务器查询指定域名的DNS记录。它可以查询任何DNS记录,包括正向反向查询
使用dig类型的lookup查询DNS,使用正向反向查询DNS解析,还可以指定查询的DNS服务器
shell
# 首先安装dnspython因为需要用到这个Python库
[root@localhost ansible]# pip3.11 install dnspython
# 剧本文件
[root@localhost ansible]# vim test7.yml
- hosts: test
remote_user: root
gather_facts: false
tasks:
- debug: msg="这是baidu.com的ipv4地址:{{lookup('dig','baidu.com')}}"
- debug: msg="这是baidu.com的TXT记录:{{lookup('dig','baidu.com','qtype=TXT')}}"
- debug: msg="这是baidu.com的TXT记录:{{lookup('dig','baidu.com./TXT')}}"
- debug: msg="163.com的mx记录之一是:{{item}}"
with_items: "{{lookup('dig','163.com./MX','wantlist=True')}}"
# 执行剧本
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "这是baidu.com的ipv4地址:110.242.68.66,39.156.66.10"
}
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "这是baidu.com的TXT记录:9279nznttl321bxp1j464rd9vpps246v,v=spf1 include:spf1.baidu.com include:spf2.baidu.com include:spf3.baidu.com include:spf4.baidu.com mx ptr -all,google-site-verification=GHb98-6msqyx_qqjGl5eRatD3QTHyVB6-xQ3gJB5UwM,_globalsign-domain-verification=qjb28W2jJSrWj04NHpB0CvgK9tle5JkOq-EcyWBgnE"
}
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "这是baidu.com的TXT记录:9279nznttl321bxp1j464rd9vpps246v,v=spf1 include:spf1.baidu.com include:spf2.baidu.com include:spf3.baidu.com include:spf4.baidu.com mx ptr -all,google-site-verification=GHb98-6msqyx_qqjGl5eRatD3QTHyVB6-xQ3gJB5UwM,_globalsign-domain-verification=qjb28W2jJSrWj04NHpB0CvgK9tle5JkOq-EcyWBgnE"
}
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => (item=10 163mx02.mxmail.netease.com.,10 163mx03.mxmail.netease.com.,50 163mx00.mxmail.netease.com.,10 163mx01.mxmail.netease.com.) => {
"msg": "163.com的mx记录之一是:10 163mx02.mxmail.netease.com.,10 163mx03.mxmail.netease.com.,50 163mx00.mxmail.netease.com.,10 163mx01.mxmail.netease.com."
}
反向查询DNS
shell
# 剧本文件
[root@localhost ansible]# vim test8.yml
- hosts: test
remote_user: root
gather_facts: false
tasks:
- debug: msg="114.114.114.114反向查询DNS是:{{lookup('dig','114.114.114.114/PTR')}}"
# 执行结果
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "114.114.114.114反向查询DNS是:public1.114dns.com."
}
指定查询的DNS服务器
shell
- debug: msg="使用8.8.8.8查询baidu.com的ipv4地址:{{lookup('dig','baidu.com','@8.8.8.8')}}"
# 执行结果
TASK [debug] ************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "使用8.8.8.8查询baidu.com的ipv4地址:39.156.66.10,110.242.68.66"
}
过滤器
在 Ansible 中,过滤器(Filters)是一种功能强大的工具,用于在模板中处理变量的值。过滤器可以对变量进行转换、格式化、筛选和操作
过滤器使用的位置
quote过滤器的功能是给字符串加引号
shell
[root@csq ~]# vim b.yml
- hosts: test2
remote_user: root
gather_facts: false
vars:
my_test_string: "This is the test string"
tasks:
- name: "quote {{ my_test_string }}"
debug: msg="echo {{ my_test_string | quote }}"
# 执行结果
TASK [quote This is the test string] **********************************************************
ok: [192.168.200.30] => {
"msg": "echo 'This is the test string'"
}
过滤器对普通变量的操作
default:为没有定义的变量提供默认值
因为变量some_undefined_varible表示没有定义,所以下面的任务会输出NONE
shell
[root@csq ~]# vim c.yml
- hosts: test
remote_user: root
gather_facts: false
tasks:
- name: output1
debug: msg="{{ some_undefined_varible | default('NONE') }}"
# 执行结果
TASK [output1] ********************************************************************************
ok: [192.168.200.20] => {
"msg": "NONE"
}
如果是远程主机fact里面的变量,当远程主机的fact变量为空一般都是显示的[]或者"",那么我不想让他显示这个空的
true
:这是 default
过滤器的第二个参数,用于指示 Ansible 在判断变量是否为空时将空字符串、空列表、空字典等视为真实的空值。如果设置为 true
,则 Ansible 会将这些空值视为真实的空值,否则会将其视为非空值。
shell
[root@csq ~]# vim c.yml
- hosts: test
remote_user: root
tasks:
- name: output1
debug: msg="{{ ansible_fibre_channel_wwn | default('NONE',true) }}"
# 执行结果
TASK [output1] ********************************************************************************
ok: [192.168.200.20] => {
"msg": "NONE"
}
omit:忽略变量的占位符
与default一起使用时,如果某个变量没有定义,那么使用omit占位符,Ansible就会把这个对应的参数按照没用传这个参数的值来处理
shell
[root@csq ~]# vim r.yml
- hosts: test
remote_user: root
tasks:
- name: touch file
file: dest={{item.path}} state=touch mode={{item.mode|default(omit)}}
with_items:
- path: /tmp/csq1
- path: /tmp/csq2
mode: "0444"
[root@csq ~]# ansible test -m shell -a "ls /tmp/csq* -la"
192.168.200.20 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 5月 2 13:58 /tmp/csq1
-r--r--r--. 1 root root 0 5月 2 13:58 /tmp/csq2
# 文件/tmp/csq1没用定义参数mode,所以default(omit)会在没有定义mode时忽略mode变量
# ansible的file模块会按照没有传入mode这个参数来创建文件/tmp/csq1,/tmp/csq2定义了mode为0444
# 所以文件的权限为0444
mandatory:强制变量必须定义,否则报错
在ansible默认的配置中,如果变量没有定义,那么直接使用未定义的变量{{aaa-bbb-ccc}}会报错
如果ansible配置文件中使用了下面的配置,那么遇到未定义的变量时,ansible就不会报错
shell
error_on_undefined_vars=False
如果你想要某一个变量必须定义,就可使用mandatory
shell
[root@csq ~]# vim l.yml
- hosts: test
remote_user: root
vars:
aaabbbccc: abc
gather_facts: false
tasks:
- name: 定义了变量
debug:
msg: "{{aaabbbccc}}"
- name: 未定义变量报错
debug:
msg: "{{aaa-bbb-ccc | mandatory}}"
# 执行结果
[root@csq ~]# ansible-playbook l.yml
PLAY [test] *************************************************************************************************************************
TASK [定义了变量] *******************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "abc"
}
TASK [未定义变量报错] ***************************************************************************************************************
fatal: [192.168.200.20]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'aaa' is undefined. 'aaa' is undefined\n\nThe error appears to be in '/root/l.yml': line 10, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n msg: \"{{aaabbbccc}}\"\n - name: 未定义变量报错\n ^ here\n"}
PLAY RECAP **************************************************************************************************************************
192.168.200.20 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
bool:判断变量是否为布尔类型
bool的过滤器是playbook中判断条件bool类型的过滤器,其中bool类型的过滤器用来判断变量是否为布尔类型
shell
[root@csq ~]# vim i.yml
- hosts: test
remote_user: root
gather_facts: false
vars:
var1: "Test"
var2: True
var3: "True"
tasks:
- debug: msg=test
when: var1 | bool
- debug: msg=test
when: var2 | bool
- debug: msg=test
when: var3 | bool
# 执行结果
TASK [debug] **************************************************************************************************************************
skipping: [192.168.200.20]
TASK [debug] **************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "test"
}
TASK [debug] **************************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "test"
}
ternary:Playbook的条件表达式
ternary类似于编程语言中的类型表达式,("A?B:C")当条件为真时,返回一个值;当条件为假时,返回另一个值
shell
[root@csq ~]# vim j.yml
- hosts: test
remote_user: root
gather_facts: false
vars:
hostname: "csq"
tasks:
- name: if hostname = csq Yes if hostname = other No
debug: msg="{{ (hostname == "csq") | ternary('Yes','No') }}"
# 执行结果
TASK [if hostname = csq Yes if hostname = other No] ***********************************************************************************
ok: [192.168.200.20] => {
"msg": "Yes"
}
过滤器对文件路径的操作
Ansible为了方便文件及其路径进行操作,提供了一系列关于文件目录的操作,包括获取文件名,路径名,等等。
Linux文件路径的操作的过滤器如下:
- basename:获取路径中的文件名
- dirname:获取文件的目录
- expanduser:扩展~为实际的目录
- realpath:获取链接文件所指文件的真实路径
- relpath:获得相对某一根目录的相对路径
- splitext:把文件名用点号(.)分割成多个部分
shell
[root@csq ~]# vim test1.yml
- hosts: test
remote_user: root
gather_facts: false
vars:
linux_path: "/etc/csq/a.txt"
linux_user_path: "~/data/my_test/file.txt"
link_to_ansible_cfg: "/bin"
tasks:
- name: "获取Linux路径的文件名 {{linux_path}}"
debug: msg="{{linux_path | basename}}"
- name: "获取Linux路径的目录名 {{linux_path}}"
debug: msg="{{linux_path | dirname}}"
- name: "获取展开文件路径中的用户目录 {{linux_user_path}}"
debug: msg="{{linux_user_path | expanduser}}"
- name: "获取文件路径的真实路径 {{link_to_ansible_cfg}}"
debug: msg="{{link_to_ansible_cfg | realpath}}"
- name: "获取相对某一根目录的相对路径 {{linux_path}}"
debug: msg="{{linux_path | relpath('/etc')}}"
- name: "把文件名用点号(.)分隔成多个部分{{linux_path}}"
debug: msg="{{linux_path | splitext}}"
# 执行结果
TASK [获取Linux路径的文件名 /etc/csq/a.txt] *******************************************************************************************
ok: [192.168.200.20] => {
"msg": "a.txt"
}
TASK [获取Linux路径的目录名 /etc/csq/a.txt] *******************************************************************************************
ok: [192.168.200.20] => {
"msg": "/etc/csq"
}
TASK [获取展开文件路径中的用户目录 ~/data/my_test/file.txt] ***************************************************************************
ok: [192.168.200.20] => {
"msg": "/root/data/my_test/file.txt"
}
TASK [获取文件路径的真实路径 /bin] ****************************************************************************************************
ok: [192.168.200.20] => {
"msg": "/usr/bin"
}
TASK [获取相对某一根目录的相对路径 /etc/csq/a.txt] ************************************************************************************
ok: [192.168.200.20] => {
"msg": "csq/a.txt"
}
TASK [把文件名用点号(.)分隔成多个部分/etc/csq/a.txt] **********************************************************************************
ok: [192.168.200.20] => {
"msg": "('/etc/csq/a', '.txt')"
}
过滤器对字符串变量的操作
quote:给字符串加引号
shell
[root@csq ~]# vim b.yml
- hosts: test2
remote_user: root
gather_facts: false
vars:
my_test_string: "This is the test string"
tasks:
- name: "quote {{ my_test_string }}"
debug: msg="echo {{ my_test_string | quote }}"
# 执行结果
TASK [quote This is the test string] **********************************************************
ok: [192.168.200.30] => {
"msg": "echo 'This is the test string'"
}
base64:得到字符串Base64编码
shell
[root@csq ~]# vim test2.yml
- hosts: test
remote_user: root
gather_facts: false
vars:
my_comment: "hello world"
my_comment_base64: "aGVsbG8gd29ybGQ="
tasks:
- name: "获取base64编码{{my_comment}}"
debug: msg="{{my_comment | b64encode}}"
- name: "解码base64 {{my_comment_base64}}"
debug: msg="{{my_comment_base64 | b64decode}}"
- name: "获取uuid {{my_comment}}"
debug: msg="{{my_comment | to_uuid}}"
# 执行结果
TASK [获取base64编码hello world] ******************************************************************************************************
ok: [192.168.200.20] => {
"msg": "aGVsbG8gd29ybGQ="
}
TASK [解码base64 aGVsbG8gd29ybGQ=] ****************************************************************************************************
ok: [192.168.200.20] => {
"msg": "hello world"
}
TASK [获取uuid hello world] ***********************************************************************************************************
ok: [192.168.200.20] => {
"msg": "9a129f19-657c-5ca0-80f4-31b29d10569c"
}
hash:获取字符串的哈希值
计算哈希值的算法有很多,如果sha1、md5、checksum等
shell
[root@csq ~]# vim test3.yml
- hosts: test
remote_user: root
gather_facts: false
vars:
my_password: "mypassword"
tasks:
- name: "获取字符串{{my_password}}的sha1 hash"
debug: msg="{{my_password | hash('sha1')}}"
- name: "获取字符串{{my_password}}的MD5 hash"
debug: msg="{{my_password | hash('md5')}}"
- name: "获取字符串{{my_password}}的checksum"
debug: msg="{{my_password | checksum}}"
- name: "获取字符串{{my_password}}的sha512 hash"
debug: msg="{{my_password | password_hash('sha512')}}"
- name: "获取字符串{{my_password}}的sha256 hash带有特定字符串"
debug: msg="{{my_password | password_hash('sha256','mysecretsalt')}}"
# 执行结果
TASK [获取字符串mypassword的sha1 hash] ************************************************************************************************
ok: [192.168.200.20] => {
"msg": "91dfd9ddb4198affc5c194cd8ce6d338fde470e2"
}
TASK [获取字符串mypassword的MD5 hash] *************************************************************************************************
ok: [192.168.200.20] => {
"msg": "34819d7beeabb9260a5c854bc85b3e44"
}
TASK [获取字符串mypassword的checksum] *************************************************************************************************
ok: [192.168.200.20] => {
"msg": "91dfd9ddb4198affc5c194cd8ce6d338fde470e2"
}
TASK [获取字符串mypassword的sha512 hash] **********************************************************************************************
ok: [192.168.200.20] => {
"msg": "$6$kM35/CEoWTM1xoIX$0HjNRHNwS01H2uH4Rik7h06E3DzDZpI9uHvg0NN0QE2kQOMKYwkN28kPKOuB9.0aShHv6CsFJAbAPnOCv1PZO0"
}
TASK [获取字符串mypassword的sha256 hash带有特定字符串] ********************************************************************************
ok: [192.168.200.20] => {
"msg": "$5$mysecretsalt$HhobCuvPwbLCsdua9UNYk8C.EPib1CkzWvN23KBHYV2"
}
comment:把字符串变成代码注释的一部分
comment展示了将字符串转化为不同风格和格式注释的使用方法,最后一个是用户自定义的注释风格
shell
[root@csq ~]# vim test4.yml
- name: "erlang
- hosts: test
remote_user: root
gather_facts: false
vars:
my_comment: "hello world"
tasks:
- name: "Simple comment"
debug: msg="{{my_comment | comment}}"
- name: "C comment"
debug: msg="{{my_comment | comment('c')}}"
- name: "cblock comment"
debug: msg="{{my_comment | comment('cblock')}}"
- name: "erlang comment"
debug: msg="{{my_comment | comment('erlang')}}"
- name: "xml comment"
debug: msg="{{my_comment | comment('xml')}}"
- name: "customize comment"
debug: msg="{{my_comment | comment('plain',prefix='######\n#',postfix='#\n######\n###\n#')}}"
# 执行结果
TASK [Simple comment] *****************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "#\n# hello world\n#"
}
TASK [C comment] *********************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "//\n// hello world\n//"
}
TASK [cblock comment] ****************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "/*\n *\n * hello world\n *\n */"
}
TASK [erlang comment] ****************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "%\n% hello world\n%"
}
TASK [xml comment] *******************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "<!--\n -\n - hello world\n -\n-->"
}
TASK [customize comment] **************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "######\n#\n# hello world\n#\n######\n###\n#"
}
regex:利用正则表达式对字符串进行替换
shell
[root@csq ~]# vim test5.yml
- hosts: test
remote_user: root
vars:
my_comment: "hello world"
gather_facts: false
tasks:
- name: "转换 ansible 为 able"
debug: msg="{{'ansible' | regex_replace('^a.*i(.*)$','a\\1')}}"
- name: "转换 foobar 为 bar"
debug: msg="{{'foobar' | regex_replace('^f.*o(.*)$','\\1')}}"
- name: "转换 localhost:80 为 localhost,80"
debug: msg="{{'localhost:80' | regex_replace('^(?P<host>.+):(?P<port>\\d+)$','\\g<host>,\\g<port>') }}"
# 执行结果
TASK [转换 ansible 为 able] ***********************************************************************************************************
ok: [192.168.200.20] => {
"msg": "able"
}
TASK [转换 foobar 为 bar] *************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "bar"
}
TASK [转换 localhost:80 为 localhost,80] **********************************************************************************************
ok: [192.168.200.20] => {
"msg": "localhost,80"
}
ip:判断字符串是否是合法的IP地址
shell
[root@localhost ansible]# vim test6.yml
- hosts: test
remote_user: root
gather_facts: false
vars:
ip_address1: "192.168.2455.1"
ip_address2: "192.168.200.20"
ip_addr_ipv6: "fe80::20c:29ff:fe4e:d6a9"
tasks:
- name: "判断{{ip_address1}}是否为合法ip"
debug: msg="{{ ip_address1 | ipaddr}}"
- name: "判断{{ip_address2}}是否为合法ip"
debug: msg="{{ ip_address2 | ipaddr}}"
- name: "判断{{ip_address2}}是否为ipv4地址"
debug: msg="{{ ip_address2 | ipv4}}"
- name: "判断{{ip_addr_ipv6}}是否为ipv6地址"
debug: msg="{{ ip_addr_ipv6 | ipv6}}"
- name: "判断{{'192.0.2.1/24' | ipaddr('address')}}是否为合法IP"
debug: msg="{{'192.0.2.1/24' | ipaddr('address')}}"
# 执行结果
[root@localhost ansible]# ansible-playbook test6.yml
TASK [判断192.168.2455.1是否为合法ip] ***********************************************************************************************
ok: [192.168.200.20] => {
"msg": false
}
TASK [判断192.168.200.20是否为合法ip] ***********************************************************************************************
ok: [192.168.200.20] => {
"msg": "192.168.200.20"
}
TASK [判断192.168.200.20是否为ipv4地址] *********************************************************************************************
ok: [192.168.200.20] => {
"msg": "192.168.200.20"
}
TASK [判断fe80::20c:29ff:fe4e:d6a9是否为ipv6地址] ***********************************************************************************
ok: [192.168.200.20] => {
"msg": "fe80::20c:29ff:fe4e:d6a9"
}
TASK [判断192.0.2.1是否为合法IP] ****************************************************************************************************
ok: [192.168.200.20] => {
"msg": "192.0.2.1"
}
过滤器对JSON的操作
format:将变量的值按照JSON/YAML格式输出
shell
# 剧本文件
[root@localhost ansible]# vim test1.yml
- hosts: test
gather_facts: false
vars:
my_variable:
key1: value1
key2: value2
tasks:
- name: Print variable as JSON
debug:
msg: "{{ my_variable | to_json }}"
- name: Print variable as YAML
debug:
msg: "{{ my_variable | to_yaml }}"
- name: Print variable as Nice JSON
debug:
msg: "{{ my_variable | to_nice_json }}"
- name: Print variable as Nice YAML
debug:
msg: "{{ my_variable | to_nice_yaml }}"
# 执行结果
TASK [Print variable as JSON] *******************************************************************************************************
ok: [192.168.200.20] => {
"msg": "{\"key1\": \"value1\", \"key2\": \"value2\"}"
}
TASK [Print variable as YAML] *******************************************************************************************************
ok: [192.168.200.20] => {
"msg": "{key1: value1, key2: value2}\n"
}
TASK [Print variable as Nice JSON] **************************************************************************************************
ok: [192.168.200.20] => {
"msg": "{\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n}"
}
TASK [Print variable as Nice YAML] **************************************************************************************************
ok: [192.168.200.20] => {
"msg": "key1: value1\nkey2: value2\n"
}
query:在一个JSON对象里,搜索符合条件的属性,返回符合条件的属性数组
shell
[root@localhost ansible]# vim test2.yml
- name: Search for properties matching a condition in a JSON object
hosts: localhost
gather_facts: false
vars:
my_json:
users:
- name: John
age: 30
- name: Alice
age: 25
- name: Bob
age: 35
tasks:
- name: Query JSON object
debug:
msg: "{{ my_json.users | json_query('[].name') }}"
# 执行结果
ok: [localhost] => {
"msg": [
"John",
"Alice",
"Bob"
]
}
过滤器对数据结构的操作
Ansible中的过滤器支持以下几种数据结构的操作
random:取随机数
shell
[root@localhost ansible]# vim test3.yml
- hosts: test
remote_user: root
gather_facts: false
tasks:
- name: 列表随机
debug: msg="{{ ['a','b','c'] | random}}"
- name: 随机数
debug: msg="{{ 59 | random}} * * * * echo hello world"
- name: random with step
debug: msg="{{ 100 | random(step=10)}}"
- name: random with start and step
debug: msg="{{ 100 | random(2,10)}}"
- name: random with start and step
debug: msg="{{ 100|random(start=2,step=10)}}"
# 执行结果
TASK [列表随机] *********************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "b"
}
TASK [随机数] ***********************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "33 * * * * echo hello world"
}
TASK [random with step] *************************************************************************************************************
ok: [192.168.200.20] => {
"msg": "10"
}
TASK [random with start and step] ***************************************************************************************************
ok: [192.168.200.20] => {
"msg": "32"
}
TASK [random with start and step] ***************************************************************************************************
ok: [192.168.200.20] => {
"msg": "72"
}
过滤器的链式/连续使用
ansible的过滤器是支持链式使用的,就是在一个{{}}中使用多个过滤器
shell
[root@localhost ansible]# vim test4.yml
- hosts: test
remote_user: root
vars:
aaabbbccc: abc
gather_facts: false
tasks:
- name: 判断变量是否存在,存在就使用base64加密该变量
debug:
msg: "{{aaabbbccc | mandatory | b64encode}}"
# 执行结果
TASK [判断变量是否存在,存在就使用base64加密该变量] *********************************************************************************
ok: [192.168.200.20] => {
"msg": "YWJj"
}
常见插件类型
modules插件
模块插件是Ansible的核心成分,用于执行具体的任务。它们可以通过在任务中调用来提供丰富的功能,例如文件操作、软件包管理、配置管理等。
Inventory插件
主机清单插件用于动态生成Ansible的主机清单。它们可以从各种源(如INI文件、YAML文件、云服务提供商)读取主机信息,并动态生成可供Ansible使用的清单。
Action插件
和模块使用方法类似,只不过执行目标不是远程主机,而是在Ansible的控制节点(管理节点)本机上
Cache插件
为Facts(主机变量)提供缓存,以避免多次执行Playbook时搜集Facts
Callback插件
Ansible执行Playbook后,提供额外的行为,例如,将执行结果发送到E-mail中,或者将执行结果写入log中等等
connection插件
用于在Ansible连接远程主机时进行身份验证。认证插件允许使用不同的认证机制,如用户名/密码、私钥等
filters插件
过滤器插件用于对变量进行转换、过滤和操作。
lookup插件
文件查找插件用于在Ansible中查找文件和数据。它们可以从文件系统、远程主机或其它的数据源中查找所需的文件或数据
test插件
ansible Jinja2 test提供更多功能