playbook的使用

本文详细介绍了如何在Ansible中编写playbook,包括playbook的语法、任务组织、错误处理(如ignore_errors和fail模块)以及实际操作示例,如打印主机信息、安装服务和防火墙配置。
摘要由CSDN通过智能技术生成

        本章会介绍如何在ansible中写脚本。

           1.playbook的语法

           2.在写playbook时如何进行错误处理

        ansible的许多模块都是在命令行中执行的,每次只能执行一个模块。如果需要执行多个模块,且要写判断语句,判断模块是否执行成功了,如果没成功会怎么处理等。这时就需要写脚本了,ansible中的脚本叫做 playbook,每个 playbook中可以包含多个 play。

一、playbook的写法

        playbook是以yaml或yml作为后缀的,每个play都可以使用两种格式来写。

        (1)参数卸载模块后面,命令如下。

1 - name: play的名称
2  hosts:z主机组1,主机组2,... #--列出主机组
3  tasks:
4  - name: 提示信息1
5  模块1: argx1=vx1 argz2=vx2 #这种写法,“=”两边不要有空格
6  - name: 提示信息x
7  模块x: rgxl=vxl argx2=vx2

        一个 play中可以包含多个tasks,每个 task调用一个模块。

        (2) 参数分行写,一行一个参数,命令如下。

1 - hosts: 主机组1,主机组2,... #--列出主机组
2  tasks:
3  - name:描述语句1
4  模块1:
5  argxl: vx1 #这里指定模块的参数,注意冒号后面的空格
6  argx2: vx2
7  - name:描述语句2
8  模块x:
9  argxl:vx1
10  argx2:vx2

         需要注意的是,YAML文件对缩进有极严格的要求,每个缩进都是两个空格,不要按【Tab】键。

        一个完整的playbook中至少要包含一个 play,下面是一个包含两个play的playbook,命令如下。

1 ---
2 - name: 第一个play的名称
3  hosts: 主机组1, 主机组2, ...#--列出主机组
4  tasks:
5  - name:提示信息1
6  模块1:argxl-vxl argx2=vx2
7  - name:提示信息x
8  模块x:rgxl=vxl argx2=vx2
9 - name: 第二个play的名称
10  hosts: 主机组3,主机组4,...#--列出主机组
11  gather faces: false
12  tasks:
13  - name: 提示信息1
14  模块1: argxl=vxl argx2=vx2
15  - name: 提示信息x
16  模块x: rgxl=vxl argx2=Vx2

        在写playbook时,一定要先写好框架,然后往框架中写内容。如果在多个主机组上做的是相同的操作,可以把它们放在同一个play中。如果在不同的主机组上做的是不同的操作,可以通过不同的play分别来实现。

        这里第二个play中加了一句gather_facts:false,意思是执行此play时不需要通过setup获取主机组的信息。所以,如果在tasks中没有视同到fact变量,建议加上这句,可以提升执行的速度。

写好之后运行playbook的方法是ansible playbook文件。

        本章实验都在/home/lduan/demol下操作,先把demo1目录创建出来并把ansible.cfg和hosts拷贝进去,命令如下。

1 [blab@server ~]$ mkdir demo1
2 [blab@server ~]$ cp ansible.cfg hosts demo1/
3 [blab@server ~]$ cd demo1/
4 [blab@server demo1]$

        联系1:写一个playbook文件test1.yaml,在server2和server3上打印主机名和IP。

        分析:因为在server2和server3上做的是相同的操作,所以只要一个play即可。这个play中包含两个task:一个用于打印主机名,另一个用于打印IP,命令如下。

1 [blab@server demo1]$ cat test1.yaml
2 ---
3 - hosts: server2,server3
4  tasks:
5  - name: 打印主机名
6   debug: msg={{ansible_fqdn}}
7  - name: 打印IP
8  debug: msg={{ansible_default_ipv4.address}}
9 [blab@server demo1]$
10

        运行此playbook,命令如下。

1 [blab@server demo1]$ ansible-playbook test1.yaml
2 ...输出...
3 TASK [打印主机名]
4 ok: [server2] => {
5  "msg": "server2.rhce.cc"
6 }
7 ok: [server3] => {
8  "msg": "server3.rhce.cc"
9 }
10
11 TASK [打印IP]
12 ok: [server2] => {
13  "msg": "192.168.8.12"
14 }
15 ok: [server3] => {
16  "msg": "192.168.8.13"
17 }
18 ...输出...
19 [blab@server demo1]$

        练习2:写一个playbook文件test2.yaml,在server2上打印主机名,在server3上打印IP。分析:因为在server2和server3上做的是不同的操作,所以这里写两个play,一个play在server2上执行,另一个play在server3上执行。每个play中只要包含一个task即可,命令如下。

1 [blab@server demo1]$ cat test2.yaml
2 ---
3 - name: 在server2上的操作
4  hosts: server2
5  tasks:
6  - name: 这是第一个操作,打印主机名
7  debug: msg={{ansible_fqdn}}
8
9 - name: 在server3上的操作
10  hosts:server3
11  tasks:
12  - name: 打印 IP
13  debug: msg={{ansible_default_ipv4.address}}
14 [blab@server demo1]$

        运行此playbook,命令如下。

1 [blab@server demo1]$ ansible‐playbook test2.yaml
2
3 PLAY [在server2上的操作] ***********************************************
**************************************************************************
****
4
5 TASK [Gathering Facts] ***********************************************
**************************************************************************
*
6 ok: [server2]
7
8 TASK [这是第一个操作,打印主机名]
*************************************************************************
***************************************************
9 ok: [server2] => {
10 "msg": "server2.rhce.cc"
11 }
12
13 PLAY [在server3上的操作]
*************************************************************************
****************************************************
14
15 TASK [Gathering Facts] ***********************************************
**************************************************************************
*
16 ok: [server3]
17
18 TASK [打印 IP] *******************************************************
**************************************************************************
***
19 ok: [server3] => {
20 "msg": "192.168.8.13"
21 }
22
23 PLAY RECAP ***********************************************************
**************************************************************************
*
24 server2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ig
nored=0
25 server3 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ig
nored=0
26
27 [blab@server demo1]$

        练习3:写一个playbook 文件 test3.yaml,要求如下。

        (1) 在server2上安装vsftpd,启动并开机自动启动vsftpd,设置防火墙开放ftp服务。

        (2) 在server3上安装 httpd,启动并开机自动启动httpd,设置防火墙开放http服务。

        分析:因为在server2和server3上做的是不同的操作,所以这里写两个play。

        第一个play在server2上执行,包含3个task,分别用于安装、服务管理、防火墙设置。

        第二个play在server3上执行,包含3个task,分别用于安装、服务管理、防火墙设置。

1 [blab@server demo1]$ cat test3.yaml
2 ‐‐‐
3 ‐ name: 第一个play在server2上要做的操作‐‐‐安装vsftpd,启动服务,开启防火墙
4 hosts: server2
5 tasks:
6 ‐ name: 第一个操作安装vsftpd
7 yum: name=vsftpd state=installed
8 ‐ name: 第二个操作启动服务
9 service: name=vsftpd state=started enabled=yes
10 ‐ name: 第三个操作开启防火墙
11 firewalld: service=ftp state=enabled immediate=yes permanent=yes
12
13 ‐ name: 第二个play在server3上要做的操作‐‐安装httpd,启动服务,开启防火墙
14 hosts: server3
15 tasks:
16 ‐ name: 第一个操作安装httpd
17 yum: name=httpd state=installed
18 ‐ name: 第二个操作启动服务
19 service: name=httpd state=started enabled=yes
20 ‐ name: 第三个操作开启防火墙
21 firewalld: service=http state=enabled immediate=yes permanent=yes
22 [blab@server demo1]$

        运行此playbook,命令如下。

1 [blab@server demo1]$ ansible‐playbook test3.yaml
2
3 PLAY [第一个play在server2上要做的操作‐‐‐安装vsftpd,启动服务,开启防火墙]
*************************************************************************
*********************
4
5 TASK [Gathering Facts] ***********************************************
**************************************************************************
*
6 ok: [server2]
7
8 TASK [第一个操作安装vsftpd]
*************************************************************************
***************************************************
9 changed: [server2]
10
11 TASK [第二个操作启动服务]
*************************************************************************
*******************************************************
12 changed: [server2]
13
14 TASK [第三个操作开启防火墙]
*************************************************************************
******************************************************
15 ok: [server2]
16
17 PLAY [第二个play在server3上要做的操作‐‐安装httpd,启动服务,开启防火墙] *****
**************************************************************************
*****************
18
19 TASK [Gathering Facts] ***********************************************
**************************************************************************
*
20 ok: [server3]
21
22 TASK [第一个操作安装httpd]
*************************************************************************
****************************************************
23 changed: [server3]
24
25 TASK [第二个操作启动服务]
*************************************************************************
*******************************************************
26 changed: [server3]
27
28 TASK [第三个操作开启防火墙]
*************************************************************************
******************************************************
29 changed: [server3]
30
31 PLAY RECAP ***********************************************************
**************************************************************************
*
32 server2 : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ig
nored=0
33 server3 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ig
nored=0
34
35 [blab@server demo1]$

二、错误处理

        在写playbook时,会遇到各种各样的问题,例如,命令出错了,或者引用的变量不存在等。playbook具备一定的错误处理能力。

   1.ignore_errors

        执行一个playbook时,如果其中的某个task出错,则后续的task就不再继续执行了。看下面的例子,编写test4.yaml的内容如下。

1 [blab@server demo1]$ cat test4.yaml
2 ‐‐‐
3 ‐ hosts: server2
4 gather_facts: false
5 tasks:
6 ‐ name: aa
7 debug: msg={{default_xxx}}
8 ‐ name: bb
9 debug: msg="22222"
10 [blab@server demo1]$

        这里写了两个task,一个时aa,另一个是bb,aa这个task中引用了一个不存在的变量default_xxx,所以导致aa这个task报错。如果某个task出错,则后续的task就不再继续执行了,所以bb这个task不会继续执行了。

1 [blab@server demo1]$ ansible‐playbook test4.yaml
2
3 PLAY [server2] *******************************************************
**************************************************************************
*
4
5 TASK [aa]
*************************************************************************
**************************************************************
6 fatal: [server2]: FAILED! => {"msg": "The task includes an option with
an undefined variable. The error was: 'default_xxx' is undefined\n\nThe e
rror appears to be in '/home/blab/demo1/test4.yaml': line 5, column 5, bu
t may\nbe elsewhere in the file depending on the exact syntax problem.\n
\nThe offending line appears to be:\n\n tasks:\n ‐ name: aa\n ^ here\n"}
7
8 PLAY RECAP ***********************************************************
**************************************************************************
*
9 server2 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ig
nored=0
10
11 [blab@server demo1]$

        如果想让task aa出错时不影响后续task的执行,那么可以在task aa中添加ignore_errors:true来忽略这个报错继续往下执行,命令如下。

1 [blab@server demo1]$ cat test4.yaml
2 ‐‐‐
3 ‐ hosts: server2
4 gather_facts: false
5 tasks:
6 ‐ name: aa
7 debug: msg={{default_xxx}}
8 ignore_errors: true
9 ‐ name: bb
10 debug: msg="22222"
11 [blab@server demo1]$

        这里添加了ignore_errors: true忽略报错信息。下面运行test4.yaml查看结果,如下所示。

1 [blab@server demo1]$ ansible‐playbook test4.yaml
2
3 PLAY [server2] *******************************************************
**************************************************************************
*
4
5 TASK [aa]
*************************************************************************
**************************************************************
6 fatal: [server2]: FAILED! => {"msg": "The task includes an option with
an undefined variable. The error was: 'default_xxx' is undefined\n\nThe e
rror appears to be in '/home/blab/demo1/test4.yaml': line 5, column 5, bu
t may\nbe elsewhere in the file depending on the exact syntax problem.\n
t may\nbe elsewhere in the file depending on the exact syntax problem.\n
\nThe offending line appears to be:\n\n tasks:\n ‐ name: aa\n ^ here\n"}
7 ...ignoring
8
9 TASK [bb]
*************************************************************************
**************************************************************
10 ok: [server2] => {
11 "msg": "22222"
12 }
13
14 PLAY RECAP ***********************************************************
**************************************************************************
*
15 server2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ig
nored=1
16
17 [blab@server demo1]$

        可以看到,及时task aa出错了,但是后续的 task bb仍然继续执行。

   2.fail语句

        fail模块和debug模块一样,都是用来打印信息的,区别在于debug执行完成之后会继续进行后续模块的操作,而fail打印完报错信息之后会退出整个playbook。编写test5.yaml的内容如下。

1 [blab@server demo1]$ cat test5.yaml
2 ‐‐‐
3 ‐ hosts: server2
4 gather_facts: false
5 tasks:
6 ‐ name: aa
7 debug: msg="111"
8 ‐ name: bb
9 fail: msg="222"
10 ‐ name: cc
11 debug: msg="333"
12 [blab@server demo1]$

        这里写了3个task,其中task aa和task cc使用debug打印信息,task bb只有fail打印信息。下面运行此playbook查看结果,如下所示。

1 [blab@server demo1]$ ansible‐playbook test5.yaml
2
3 PLAY [server2] *******************************************************
**************************************************************************
*
4
5 TASK [aa]
*************************************************************************
**************************************************************
6 ok: [server2] => {
7 "msg": "111"
8 }
9
10 TASK [bb]
*************************************************************************
**************************************************************
11 fatal: [server2]: FAILED! => {"changed": false, "msg": "222"}
12
13 PLAY RECAP ***********************************************************
**************************************************************************
*
14 server2 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ig
nored=0
15
16 [blab@server demo1]$

        可以看到,task aa正确执行之后,继续执行task bb。因为 task bb用的是fail来打印信,所以执行完成之后就退出 playbook了,task cc并没有执行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值