今天碰到一个需求,当使用ansible-playbook在执行一个脚本后,根据脚本返回的内容判断是否继续往下执行还是中断执行,查询官网发现使用register寄存器可以实现记录脚本输出,使用when+fail模块来判断是否往下继续执行或者中断,以下是一个简单例子:


ansible服务在172.16.206.128上,先执行一个脚本,脚本返回success时在172.16.206.129上创建一个目录/tmp/test,如果返回failed则中断执行。


在129服务器上配置一个脚本,内容如下:

#!/bin/bash
echo "failed"


在128上创建一个register.yml的yml文件

---
- hosts: 172.16.206.129
  remote_user: root
  tasks:
    - command: /tmp/test.sh
      register: result


执行register.yml这个playbook,看看输出的结果

root@host1:/etc/ansible/yml# ansible-playbook register.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [172.16.206.129]
TASK [command] *****************************************************************
changed: [172.16.206.129] => {"changed": true, "cmd": ["/tmp/test.sh"], "delta": "0:00:00.001628", "end": "2016-01-17 19:14:36.651356", "rc": 0, "start": "2016-01-17 19:14:36.649728", "stderr": "", "stdout": "failed", "stdout_lines": ["failed"], "warnings": []}
PLAY RECAP *********************************************************************
172.16.206.129             : ok=2    changed=1    unreachable=0    failed=0


register保存的信息就是“=>”后面的内容,这些信息保存到result这个变量中。stdout为标准输出,即/tmp/test.sh脚本输出的内容。我们就可以利用stdout的结果来结合when来做判断,是否执行后面的playbook。


现在我们修改register.yml文件,加一个任务。当脚本标准输出为failed时,创建/tmp/test目录,否则不执行

---
- hosts: 172.16.206.129
  remote_user: root
  tasks:
    - command: /tmp/test.sh
      register: result
    - file: path=/tmp/test  owner=root group=root mode=0755 state=directory
      when: result.stdout == 'failed'


运行修改后的playbook,看看结果:

root@host1:/etc/ansible/yml# ansible-playbook register.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [172.16.206.129]
TASK [command] *****************************************************************
changed: [172.16.206.129] => {"changed": true, "cmd": ["/tmp/test.sh"], "delta": "0:00:00.001865", "end": "2016-01-17 19:28:21.561565", "rc": 0, "start": "2016-01-17 19:28:21.559700", "stderr": "", "stdout": "failed", "stdout_lines": ["failed"], "warnings": []}
TASK [file] ********************************************************************
changed: [172.16.206.129] => {"changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/tmp/test", "size": 4096, "state": "directory", "uid": 0}
PLAY RECAP *********************************************************************
172.16.206.129             : ok=3    changed=2    unreachable=0    failed=0

playbook成功执行,可以看到129服务器上的test目录创建成功

[root@host2 tmp]# ls -l /tmp
总用量 24
srwxr-xr-x. 1 root root    0 1月   6 15:04 gnome-system-monitor.root.527586962
drwx------. 2 root root 4096 1月   6 14:02 keyring-bFV7zU
drwx------. 2 gdm  gdm  4096 1月   7 18:47 pulse-Kd6LKHrhRDP0
drwx------. 2 root root 4096 1月   7 18:47 pulse-Mkh5Mj3gpkBu
drwxr-xr-x  2 root root 4096 1月  17 19:28 test
-rwxr-xr-x  1 root root   26 1月  17 19:14 test.sh
drwx------. 2 root root 4096 1月   7 18:47 virtual-root.aNS2ix


现在我们把129服务器上的test.sh脚本中的echo输出改成success,并删除/tmp/test目录。再执行register.yml这个playbook,看看结果如何:

root@host1:/etc/ansible/yml# ansible-playbook register.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [172.16.206.129]
TASK [command] *****************************************************************
changed: [172.16.206.129] => {"changed": true, "cmd": ["/tmp/test.sh"], "delta": "0:00:00.001672", "end": "2016-01-17 19:34:11.407255", "rc": 0, "start": "2016-01-17 19:34:11.405583", "stderr": "", "stdout": "success", "stdout_lines": ["success"], "warnings": []}
TASK [file] ********************************************************************
skipping: [172.16.206.129] => {"changed": false, "skip_reason": "Conditional check failed", "skipped": true}
PLAY RECAP *********************************************************************
172.16.206.129             : ok=2    changed=1    unreachable=0    failed=0

可以看到创建/tmp/test目录这个task跳过了,原因是Condition check failed。

129服务器上也没有test目录

[root@host2 tmp]# ls -l
总用量 20
srwxr-xr-x. 1 root root    0 1月   6 15:04 gnome-system-monitor.root.527586962
drwx------. 2 root root 4096 1月   6 14:02 keyring-bFV7zU
drwx------. 2 gdm  gdm  4096 1月   7 18:47 pulse-Kd6LKHrhRDP0
drwx------. 2 root root 4096 1月   7 18:47 pulse-Mkh5Mj3gpkBu
-rwxr-xr-x  1 root root   27 1月  17 19:33 test.sh
drwx------. 2 root root 4096 1月   7 18:47 virtual-root.aNS2ix


这里存在一个问题,条件判断失败的任务被跳过了,那么后面的任务会成功执行吗?我们来测试下

修改register.yml文件,增加一个任务

---
- hosts: 172.16.206.129
  remote_user: root
  tasks:
    - command: /tmp/test.sh
      register: result
    - file: path=/tmp/test  owner=root group=root mode=0755 state=directory
      when: result.stdout == 'failed'
    - copy: src=/etc/fstab dest=/tmp/fstab owner=root group=root mode=0644


执行playbook,看看结果如果:

root@host1:/etc/ansible/yml# ansible-playbook register.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [172.16.206.129]
TASK [command] *****************************************************************
changed: [172.16.206.129] => {"changed": true, "cmd": ["/tmp/test.sh"], "delta": "0:00:00.001626", "end": "2016-01-17 19:57:38.439216", "rc": 0, "start": "2016-01-17 19:57:38.437590", "stderr": "", "stdout": "success", "stdout_lines": ["success"], "warnings": []}
TASK [file] ********************************************************************
skipping: [172.16.206.129] => {"changed": false, "skip_reason": "Conditional check failed", "skipped": true}
TASK [copy] ********************************************************************
changed: [172.16.206.129] => {"changed": true, "checksum": "9643ddd3b4c4c13dbbc511d00853a6c08354edc9", "dest": "/tmp/fstab", "gid": 0, "group": "root", "md5sum": "3b576bf27cf12c19374a4a3c48c65187", "mode": "0644", "owner": "root", "size": 779, "src": "/root/.ansible/tmp/ansible-tmp-1452880713.36-170231715664842/source", "state": "file", "uid": 0}
PLAY RECAP *********************************************************************
172.16.206.129             : ok=3    changed=2    unreachable=0    failed=0

 从结果可以看到,copy任务成功执行了。/tmp目录下也有fstab文件

[root@host2 ~]# ls -l /tmp
总用量 24
-rw-r--r--  1 root root  779 1月  17 19:57 fstab
srwxr-xr-x. 1 root root    0 1月   6 15:04 gnome-system-monitor.root.527586962
drwx------. 2 root root 4096 1月   6 14:02 keyring-bFV7zU
drwx------. 2 gdm  gdm  4096 1月   7 18:47 pulse-Kd6LKHrhRDP0
drwx------. 2 root root 4096 1月   7 18:47 pulse-Mkh5Mj3gpkBu
-rwxr-xr-x  1 root root   27 1月  17 19:33 test.sh
drwx------. 2 root root 4096 1月   7 18:47 virtual-root.aNS2ix


我们的需求是当某一个任务执行失败时,应该中断后面的任务,而不是跳过。这个需要结合fail模块来实现了。

我们将/tmp/test.sh脚本输出改回"failed"。删除/tmp下的fstab文件。修改register.yml文件

---
- hosts: 172.16.206.129
  remote_user: root
  tasks:
    - command: /tmp/test.sh
      register: result
    - name: if stdout chekck failed,interrupt execution
      fail: msg="check failed"
      when: result.stdout == "failed"
    - file: path=/tmp/test  owner=root group=root mode=0755 state=directory
    - copy: src=/etc/fstab dest=/tmp/fstab owner=root group=root mode=0644


执行register.yml文件,看看结果。

root@host1:/etc/ansible/yml# ansible-playbook register.yml -v
Using /etc/ansible/ansible.cfg as config file
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [172.16.206.129]
TASK [command] *****************************************************************
changed: [172.16.206.129] => {"changed": true, "cmd": ["/tmp/test.sh"], "delta": "0:00:00.001776", "end": "2016-01-17 20:18:19.567509", "rc": 0, "start": "2016-01-17 20:18:19.565733", "stderr": "", "stdout": "failed", "stdout_lines": ["failed"], "warnings": []}
TASK [if stdout chekck failed,interrupt execution] *****************************
fatal: [172.16.206.129]: FAILED! => {"changed": false, "failed": true, "msg": "check failed"}
PLAY RECAP *********************************************************************
172.16.206.129             : ok=2    changed=1    unreachable=0    failed=1

  当条件判断失败时,后面的任务都终止了,不再执行。/tmp目录下也没有test目录和fstab文件

[root@host2 tmp]# ls -l
总用量 20
srwxr-xr-x. 1 root root    0 1月   6 15:04 gnome-system-monitor.root.527586962
drwx------. 2 root root 4096 1月   6 14:02 keyring-bFV7zU
drwx------. 2 gdm  gdm  4096 1月   7 18:47 pulse-Kd6LKHrhRDP0
drwx------. 2 root root 4096 1月   7 18:47 pulse-Mkh5Mj3gpkBu
-rwxr-xr-x  1 root root   26 1月  17 20:11 test.sh
drwx------. 2 root root 4096 1月   7 18:47 virtual-root.aNS2ix

    


原文出处http://faded.blog.51cto.com/6375932/1762688