循环
1
、
with_items
迭代列表
比如Linux中依次需要安装多个软件包时,我们可以使用with_items迭代功能进行实现
例如:
安装httpd、samba、samba-client软件包时
Vim b.yml
—
– name: install packages
hosts: node1
tasks:
– name: yum_repo1
yum_repository:
file: server
name: baseos
description: rhel8
baseurl: file:///mnt/BaseOS
enabled: yes
gpgcheck: no
– name: yum_repo2
yum_repository:
file: server
name: appstream
description: appstream
baseurl: file:///mnt/AppStream
enabled: yes
gpgcheck: no
– name: mount cdrom
mount:
src: /dev/cdrom
path: /mnt
fstype: iso9660
state: mounted
– name: install pks
yum:
name: “{
{item}}”
state: present
with_items:
– httpd
– samba
– samba-client
2
、
with_dict
迭代字典
item.key对应着是字典的键,item.value对应着字典的值
Vim c.yml
—
– name: test
hosts: node1
tasks:
– name: debug
debug:
msg: “{
{item.key}} & {
{item.value}}”
with_dict:
address: 1
netmask: 2
gateway: 3
3 with_fileglob
迭代文件
比如拷贝多个文件到受控主机上时,可以使用
Vim d.yml
—
– name: test
hosts: node1
tasks:
– name: cp file
copy:
src: “{
{item}}”
dest: /tmp/
with_fileglob:
– /tmp/*.sh
– /tmp/*.py
4 with_lines
迭代行
With_lines可以将命令行的输出结果按行迭代
Vim e.yml
—
– name: test
hosts: node1
tasks:
– name: cp file
copy:
src: “{
{item}}”
dest: /tmp/
with_lines:
– find /etc/ansible -name “*.yml”
5 w
i
t
h
_nested
嵌套迭代
a和b分别与1、2、3连接组合
Vim f.yml
—
– name: test
hosts: node1
tasks:
– name: debug
debug:
msg: “{
{item[0]}} & {
{item[1]}}”
with_nested:
– [a,b]
– [1,2,3]
6 with_sequence
排序列
(start
是从什么开始,
end
结束
stride
每隔多少
)
Vim g.yml
—
– name: test
hosts: node1
tasks:
– name: debug
debug:
msg: “{
{item}}”
with_sequence:
start=1
end=5
stride=1
7 with_random_choice
随机获得列表中的一个值
Vim h.yml
—
– name: test
hosts: node1
tasks:
– name: debug
debug:
msg: “{
{item}}”
with_random_choice:
– 1
– 2
– a
– b
– c
Loop:
现在loop已经替代了with,更多的是loop配合过滤器进行使用
过滤器:
常用字符串有关的过滤器
—
– name: test
hosts: node1
vars:
testvar: “abc123ABC 666”
testvar1: ” abc ”
tasks:
– name: debug1
debug:
#upper将字符串转换成纯大写
msg: “{
{testvar | upper}}”
– name: debug2
debug:
#lower将字符串转换成纯小写
msg: “{
{testvar | lower}}”
– name: debug3
debug:
#trim将字符串的首尾空格去掉
msg: “{
{testvar1 | trim}}”
– name: debug4
debug:
#length求字符串的长度
msg: “{
{testvar | length}}”
使用加密算法对字符串进行hash加密
创建一个用户chenyu,并且设置密码为redhat,密码采用SHA512哈希格式
—
– name: create user
hosts: node1
tasks:
– name: create chenyu
user:
name: chenyu
password: “{
{‘redhat’ | password_hash(‘sha512’)}}”
补充过滤器:
[root@foundation0 ansible]# cat filterstr.yml
—
– name: 过滤器
hosts: servera
vars:
testvar: “abc123ABC 666”
testvar1: ” abc ”
testvar2: “123456789”
testvar3: “1a2b,@#$%^&”
tasks:
– name: 将字符串转换成纯大写
debug:
#将字符串转换成纯大写
msg: “{
{ testvar | upper }}”
– name: 将字符串转换成纯小写
debug:
#将字符串转换成纯小写
msg: “{
{ testvar | lower }}”
– name: 将字符串首字母大写,之后的所有字母纯小写
debug:
#将字符串首字母大写,之后的所有字母纯小写
msg: “{
{ testvar | capitalize }}”
– name: 返回字符串的第一个字符
debug:
#返回字符串的第一个字符
msg: “{
{ testvar | first }}”
– name: 返回字符串的最后一个字符
debug:
#返回字符串的最后一个字符
msg: “{
{ testvar | last }}”
– name: 将字符串开头和结尾的空格去除
debug:
#将字符串开头和结尾的空格去除
msg: “{
{ testvar1 | trim }}”
– name: 将字符串放在中间,并且设置字符串的长度为30,字符串两边用空格补齐30位长
debug:
#将字符串放在中间,并且设置字符串的长度为30,字符串两边用空格补齐30位长
msg: “{
{ testvar1 | center(width=30) }}”
– name: 返回字符串长度,length与count等效,可以写为count
debug:
#返回字符串长度,length与count等效,可以写为count
msg: “{
{ testvar2 | length }}”
– name: 将字符串转换成列表,每个字符作为一个元素
debug:
#将字符串转换成列表,每个字符作为一个元素
msg: “{
{ testvar3 | list }}”
– name: 将字符串转换成列表,每个字符作为一个元素,并且随机打乱顺序
debug:
#将字符串转换成列表,每个字符作为一个元素,并且随机打乱顺序
#shuffle的字面意思为洗牌
msg: “{
{ testvar3 | shuffle }}”
[root@foundation0 ansible]# ansible-playbook filterstr.yml
和数字操作有关的过滤器
[root@foundation0 ansible]# cat filterdata.yml
—
– name: this playbook
hosts: servera
vars:
testvar4: -1
tasks:
– name: 将对应的值转换成int类型
debug:
#将对应的值转换成int类型
#ansible中,字符串和整形不能直接计算,比如{
{ 8+’8′ }}会报错
#所以,我们可以把一个值为数字的字符串转换成整形后再做计算
msg: “{
{ 8+(‘8’ | int) }}”
– name: 将对应的值转换成int类型,如果无法转换,默认返回0
debug:
#将对应的值转换成int类型,如果无法转换,默认返回0
#使用int(default=6)或者int(6)时,如果无法转换则返回指定值6
msg: “{
{ ‘a’ | int(default=6) }}”
– name: 将对应的值转换成浮点型,如果无法转换,默认返回’0.0′
debug:
#将对应的值转换成浮点型,如果无法转换,默认返回’0.0′
msg: “{
{ ‘8’ | float }}”
– name: 当对应的值无法被转换成浮点型时,则返回指定值’8.88‘
debug:
#当对应的值无法被转换成浮点型时,则返回指定值’8.88‘
msg: “{
{ ‘a’ | float(8.88) }}”
– name: 获取对应数值的绝对值
debug:
#获取对应数值的绝对值
msg: “{
{ testvar4 | abs }}”
– name: 四舍五入
debug:
#四舍五入
msg: “{
{ 12.5 | round }}”
– name: 取小数点后五位
debug:
#取小数点后五位
msg: “{
{ 3.1415926 | round(5) }}”
– name: 从0到100中随机返回一个随机数
debug:
#从0到100中随机返回一个随机数
msg: “{
{ 100 | random }}”
– name: 从5到10中随机返回一个随机数
debug:
#从5到10中随机返回一个随机数
msg: “{
{ 10 | random(start=5) }}”
– name: 从5到15中随机返回一个随机数,步长为3
debug:
#从5到15中随机返回一个随机数,步长为3
#步长为3的意思是返回的随机数只有可能是5、8、11、14中的一个
msg: “{
{ 15 | random(start=5,step=3) }}”
– name: 从0到15中随机返回一个随机数,这个随机数是5的倍数
debug:
#从0到15中随机返回一个随机数,这个随机数是5的倍数
msg: “{
{ 15 | random(step=5) }}”
文件或目录类过滤器
[root@foundation0 ansible]# cat filterfile.yml
—
– name: 文件或目录类的过滤器
hosts: servera
tasks:
– name: 使用sha1算法对字符串进行哈希
debug:
msg: “{
{ ‘123456’ | hash(‘sha1’) }}”
– name: 使用md5算法对字符串进行哈希
debug:
msg: “{
{ ‘123456’ | hash(‘md5’) }}”
– name: 获取到字符串的校验和,与md5哈希值一致
debug:
msg: “{
{ ‘123456’ | checksum }}”
– name: 使用sha256算法对字符串进行哈希,哈希过程中会生成随机”盐”,以便无法直接对比出原值
debug:
msg: “{
{ ‘123456’ | password_hash(‘sha256’) }}”
– name: 使用sha256算法对字符串进行哈希,并使用指定的字符串作为”盐”
debug:
msg: “{
{ ‘123456’ | password_hash(‘sha256′,’mysalt’) }}”
– name: 使用sha512算法对字符串进行哈希,哈希过程中会生成随机”盐”,以便无法直接对比出原值
debug:
msg: “{
{ ‘123123’ | password_hash(‘sha512’) }}”
– name: 使用sha512算法对字符串进行哈希,并使用指定的字符串作为”盐”
debug:
msg: “{
{ ‘123123’ | password_hash(‘sha512′,’ebzL.U5cjaHe55KK’) }}”
ansible
判断
When
判断运算符
“==” “!=” “>” “<” “>=” “<=” “and” “or” “not” is in
每次执行完一个任务,不管成功与失败,都会将执行的结果进行注册,可以使用这个注册的变量来when
判断变量的一些tests
Defined:判断变量是否已经定义,已定义则返真
Undefined:判断变量是否已经定义,未定义则返真
None:判断变量值是否为空,如果变量已经定义,但是变量值为空,则返真
Vim test.yml
—
– name: test
hosts: node1
vars:
aa: 11
cc:
tasks:
– name: create debug1
debug:
msg: a
when: aa is defined
– name: create debug2
debug:
msg: ab
when: bb is undefined
– name: create debug3
debug:
msg: abc
when: cc is none
判断执行结果的一些tests
Success/successed:通过任务的返回信息判断执行状态,任务执行成功返回真
Failure/failed:通过执行任务的返回信息判断执行状态,任务执行失败则返回真
Change/changed:通过任务的返回信息判断执行状态,任务返回状态为changed则返回真
Skip/skipped:通过任务的返回信息判断执行状态,当任务没有满足条件,而被跳过执行,则返回真。
Vim test2.yml
—
– name: test
hosts: node1
vars:
aa: 11
tasks:
– name: shell
shell:
cmd: ls /mnt
when: aa == 11
register: dd
– name: create debug1 success
debug:
msg: chenyu success
when: dd is success
– name: create debug2 fail
debug:
msg: chenyu failed
when: dd is failed
– name: create debug3 change
debug:
msg: chenyu changed
when: dd is changed
– name: create debug4 skip
debug:
msg: chenyu skip
when: dd is skip
判断路径的一些tests
注意:以下tests的判断均对ansible主机中的路径,与目标主机无关。
file:判断路径是否是一个文件
directory:判断路径是否是一个目录
link:判断路径是否是一个软连接
mount:判断路径是否是一个挂载点
exists:判断路径是否存在
vim test.yml
—
– name: test
hosts: node1
vars:
a1: /test/file1
a2: /test/
a3: /test/softlinka
a4: /test/hardlinka
a5: /boot/
tasks:
– name: debug1
debug:
msg: this is file
when: a1 is file
– name: debug2
debug:
msg: “this is directory”
when: a2 is directory
– name: debug3
debug:
msg: “this is softlink”
when: a3 is link
– name: debug4
debug:
msg: “this is hardlink”
when: a4 is link
– name: debug5
debug:
msg: “this is mount directory”
when: a5 is mount
– name: debug6
debug:
msg: “this is exists”
when: a1 is exists
判断字符串的一些tests
lower:判断包含字母的字符串中的字母是否纯小写
upper:判断包含字母的字符串中的字母是否纯大写
vim test.yml
—
– name: test
hosts: node1
vars:
a1: abc
a2: ABC
a3: a1b
tasks:
– name: debug1
debug:
msg: this string is all lower
when: a1 is lower
– name: debug2
debug:
msg: this string is all upper
when: a2 is upper
– name: debug3
debug:
msg: chenyu
when: a3 is lower
其他的一些tests
string:判断对象是否是一个字符串
number:判断对象是否一个数字
vim test.yml
—
– name: test
hosts: node1
vars:
a1: 1
a2: “1”
a3: a
tasks:
– name: debug1
debug:
msg: this is number
when: a1 is number
– name: debug2
debug:
msg: this is string
when: a2 is string
– name: debug3
debug:
msg: this is string
when: a3 is string
block/rescue/always: 限制性block,如果执行失败,则执行rescue,无论是block还是rescue执行失败还是成功,在最后都执行always
例题:
创建一个名为/etc/ansible/lv.yml 的playbook,它将在所有受管节点上运行以执行下列任务:
创建符合以下要求的逻辑卷:
逻辑卷创建在research卷组中
逻辑卷名称为data
逻辑卷大小为1500MiB
使用ext4文件系统格式化逻辑卷
如果无法创建请求的逻辑卷大小,应显示错误消息
Could not create logical volume of that size,并且应改为使用大小 800MiB。
如果卷组research 不存在 ,应显示错误消息
Volume group does not exist。
不要以任何方式挂载逻辑卷
前提:在node1、node2上添加一块硬盘,然后新建卷组
Node1的卷组大小为2G 卷组名为research
Node2的卷组大小为1G 卷组名为research
1、vim vg.yml
—
– name: create vg for node1
hosts: node1
tasks:
– name: create partition
parted:
device: /dev/sdb
number: 1
part_type: primary
part_start: 10MiB
part_end: 2058MiB
state: present
– name: create vg research
lvg:
vg: research
pvs: /dev/sdb1
– name: create vg for node2
hosts: node2
tasks:
– name: create partition for node2
parted:
device: /dev/sdb
number: 1
part_type: primary
part_start: 10MiB
part_end: 1034MiB
state: present
– name: create vg research for node2
lvg:
vg: research
pvs: /dev/sdb1
2、执行vg.yml来给node1、node2创建vg
Ansible-playbook vg.yml
3、新建lv.yml,满足题目需求
Vim lv.yml
—
– name: create lvm
hosts: node1,node2
tasks:
– name: create lv
block:
– name: create lvm 1500M
lvol:
vg: research
lv: data
size: 1500M
rescue:
– name: output fail message
debug:
msg: Could not create logical volume of that size
– name: create lvm 800M
lvol:
vg: research
lv: data
size: 800M
always:
– name: format lvm
filesystem:
fstype: ext4
dev: /dev/research/data
when: “‘research’ in ansible_facts.lvm.vgs”
#也可以用when: “‘research’ in ansible_lvm.vgs”
– name: serach not exists
debug:
msg: Volume group does not exist
when: “‘research’ not in ansible_facts.lvm.vgs”
#也可以用when: “‘research’ not in ansible_lvm.vgs”
判断与错误处理
fail模块可用于中断剧本,但我们一般是不会无故中断,除非在满足条件的情况下可以中断,经常和when一起用
Vim c.yml
—
– name: test
hosts: node1
tasks:
– name: shell
shell:
cmd: echo ‘this is a string for testing–error’
register: return_value
– name: fail
fail:
msg: Conditions established,Interrupt running playbook
when: “‘error’ in return_value.stdout”
– name: debug
debug:
msg: I never execute,because the playbook has stopped
或者使用failed_when
—
– name: test
hosts: node1
tasks:
– name: debug
debug:
msg: I execute normally
– name: shell
shell:
cmd: echo ‘this is a string testing–error’
register: return_value
failed_when: “‘error’ in return_value.stdout”
– name: debug2
debug:
msg: chenyu
ignore_errors: yes 跳过错误、忽略错误
例子:
—
– name: test
hosts: node1
tasks:
– name: debug1
debug:
msg: “{
{ansible_fqdn}}”
– name: debug2
debug:
msg: “{
{ansible_ip}}”
ignore_errors: yes
– name: create file
file:
path: /tmp/abc
state: touch
Changed_when:可以修改任务执行后的最终状态
—
– name: test
hosts: node1
tasks:
– name: debug1
debug:
msg: “{
{ansible_fqdn}}”
changed_when: true
或者可以让任务执行状态显示失败
—
– name: test
hosts: node1
tasks:
– name: shell
shell:
cmd: ls /tmp
changed_when: false