第 30 章 playbook的使用
ansible的许多模块都在命令行中执行,每次只能执行一个模块。如果要执行多个模块,且要写判断语句,这个时候就需要使用ansilbe中的playbook
了
详细参考 https://blog.csdn.net/u010230019/article/details/128530364
30.1 playbook 的写法
playbook
是以yaml
或yml
作为后缀的,每个play
都可以使用两种格式编写
- 参数写在模块后面,如
- name: play名称1
hosts: 主机组1, 主机组2,...
tasks:
- name: 提示信息1
模块1: arg1=vx1 arg2=vx2 #这种写法,=两边不用留空格
- name: 提示信息2
模块2: rg1=vx1 rg2=vx2
- name: play名称2
...
- 每个顶格
- name
都代表一个play - 一个play可以包含多个task,每个task调用一个模块
- 参数分行写,一行一个参数,如
- hosts: 主机组1, 主机组2,...
tasks:
- name: 描述语句1
模块1:
arg1: vx1
arg2: vx2
- name: 描述语句2
模块2:
arg1: vx1
arg2: vx2
- hosts: ...
...
- 每个顶格的
- hosts
代表一个play
注意,yaml文件对缩进有严格要求,每个缩进都是两个空格,详细参考 上文中提到的连接。
一个完整的playbook至少要包含要给play,写play一定要先写好框架,然后往框架中填写内容。如果在多个主机组上做的相同操作,可以把它们放在同一个play中。
在play中加上gather_facts: false
,表示在执行此play时不需要通过setup
获取主机组的信息。所以,如果在tasks中没有使用fact
变量,建议加上这句,可以提升执行速度。
写好playbook
后,使用ansible-playbook
执行该文件
示例1,打印主机名和IP
[root@node-137 ansible]# ansible-playbook test1.yml
PLAY [db1,db2] ************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]
ok: [node-140]
TASK [print hostname] *****************************************************************************************************************
ok: [node-138] => {
"msg": "node-138"
}
ok: [node-140] => {
"msg": "server.rhce.cc"
}
TASK [print IP] ***********************************************************************************************************************
ok: [node-138] => {
"msg": "192.168.81.138"
}
ok: [node-140] => {
"msg": "192.168.81.140"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node-140 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node-137 ansible]# cat test1.yml
---
- hosts: db1,db2
tasks:
- name: print hostname
debug: msg={{ansible_fqdn}}
- name: print IP
debug: msg={{ansible_default_ipv4.address}}
示例2,在db1上打印主机名,在db2上打印ip
[root@node-137 ansible]# ansible-playbook test2.yml
PLAY [print fqdn] *********************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]
TASK [fqdn] ***************************************************************************************************************************
ok: [node-138] => {
"msg": "node-138"
}
PLAY [print IP] ***********************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-140]
TASK [IP] *****************************************************************************************************************************
ok: [node-140] => {
"msg": "192.168.81.140"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node-140 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@node-137 ansible]# cat test2.yml
---
- name: print fqdn
hosts: db1
tasks:
- name: fqdn
debug: msg={{ansible_fqdn}}
- name: print IP
hosts: db2
tasks:
- name: IP
debug: msg={{ansible_default_ipv4.address}}
示例3,在db1组安装vsftp,开机自启,防火墙通行
在db2组安装http,开机自启,防火墙通行
[root@node-137 ansible]# cat test3.yml
---
- name: install vsftpd
hosts: db1
gather_facts: false
tasks:
- name: install vsftpd
yum: name=vsftpd state=present
- name: service
service: name=vsftpd enabled=yes state=started
- name: firewall
firewalld: service=ftp immediate=yes state=enabled permanent=yes
- name: install httpd
hosts: db2
tasks:
- name: install httpd
yum: name=httpd state=present
- name: service
service: name=httpd enabled=yes state=started
- name: firewall
firewalld: service=http immediate=yes state=enabled permanent=yes
30.2 错误处理
在写playbook时,会遇到各种各样的问题,例如命令出错,或引用变量不存在等。
30.2.1 ignore_errors
默认情况下,playbook的其中某个task出错,则后续的task不会继续执行,如,
[root@node-137 ansible]# cat test4.yml
---
- name: echo msg
hosts: db1
tasks:
- name: echo aa
debug: msg={{default_xx}}
- name: echo bb
debug: msg="123"
[root@node-137 ansible]# ansible-playbook test4.yml
PLAY [echo msg] ***********************************************************************************************************************
TASK [echo aa] ************************************************************************************************************************
fatal: [node-138]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was:
...
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
如果想要task aa出错后继续执行,可以在task aa中添加ignore_errors: true
来忽略这个错误继续执行,如
[root@node-137 ansible]# cat test4.yml
---
- name: echo msg
hosts: db1
tasks:
- name: echo aa
debug: msg={{default_xx}}
ignore_errors: true
- name: echo bb
debug: msg="123"
[root@node-137 ansible]# ansible-playbook test4.yml
PLAY [echo msg] ***********************************************************************************************************************
TASK [echo aa] ************************************************************************************************************************
fatal: [node-138]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was:
...
...ignoring
TASK [echo bb] ************************************************************************************************************************
ok: [node-138] => {
"msg": "123"
}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
30.2.2 fail 语句
fail模块和debug模块相似,都是打印信息,区别在于debug执行完成后会继续执行后续模块,而fail打印完报错信息后会退出整个playbook。
[root@node-137 ansible]# ansible-playbook test5.yml
PLAY [echo msg] ***********************************************************************************************************************
TASK [echo aa] ************************************************************************************************************************
ok: [node-138] => {
"msg": "321"
}
TASK [echo bb] ************************************************************************************************************************
fatal: [node-138]: FAILED! => {"changed": false, "msg": "123"}
PLAY RECAP ****************************************************************************************************************************
node-138 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
[root@node-137 ansible]# cat test5.yml
---
- name: echo msg
hosts: db1
gather_facts: false
tasks:
- name: echo aa
debug: msg="321"
ignore_errors: true
- name: echo bb
fail: msg="123"
- name: echo cc
debug: msg="456"
当执行完task echo bb
后,就推出了playbook,因为echo bb
是用fail
打印的信息