Ansible 自动化运维工具之when条件语句

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ansible 自动化运维工具之when条件语句相关的知识,希望对你有一定的参考价值。

1、When语句

有时候用户有可能需要某一个主机越过某一个特定的步骤.这个过程就可以简单的像在某一个特定版本的系统上少装了一个包一样或者像在一个满了的文件系统上执行清理操作一样.

这些操作在Ansible上,若使用`when`语句都异常简单.When语句也含Jinja2表达式,

第一个例子:

tasks:
  - name: "shutdown Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_os_family == "Debian"
如果你在RedHat系列linux系统执行,就不会被执行

第二个例子:

#cat copyfile.yml 
---
- hosts: "{{host}}"
  user: "{{user}}"
  gather_facts: True
  tasks:
    - name: Copy file to client
      copy: src=/etc/ansible/test.txt dest=/usr/local/src
      when: ansible_os_family == "Debian"
    - include: add_user.yml
      when: ansible_os_family == "Debian"
执行: 
#ansible-playbook copyfile.yml -e "host=web user=root"     --可以看到下面都skipping掉了
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [10.0.90.26]
ok: [10.0.90.25]
TASK [Copy file to client] *****************************************************
skipping: [10.0.90.25]
skipping: [10.0.90.26]
TASK [include] *****************************************************************
skipping: [10.0.90.25]
skipping: [10.0.90.26]
PLAY RECAP *********************************************************************
10.0.90.25                 : ok=1    changed=0    unreachable=0    failed=0   
10.0.90.26                 : ok=1    changed=0    unreachable=0    failed=0   
以上yml中的任务都没有执行,因为我测试机器是CentOS系统!而条件是只有当系统是Debian类型的时候执行!

PS:文件中的include模块后续会介绍。

第三个例子:

tasks:
  - shell: echo "only on Red Hat 6, derivatives, and later"
    when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int  >= 6
意思是只有当系统是RedHat并且版本大于等于6的时候执行

第三个例子:只有在server组或者名为server的这台服务器才执行

- name: Copy file to client
      copy: src=/etc/ansible/test.txt dest=/usr/local/src
      when: "host==‘server‘"

带管道的when语句

tasks:
  - command: /bin/false
    register: result
    ignore_errors: True
  - command: /bin/something
    when: result|failed
  - command: /bin/something_else
    when: result|success
  - command: /bin/still/something_else
    when: result|skipped

判断变量是否已经定义:

如果一个变量不存在,你可以使用Jinja2的`defined`命令跳过或略过.例如:

tasks:
    - shell: echo "I‘ve got ‘{{ foo }}‘ and am not afraid to use it!"
      when: foo is defined
    - fail: msg="Bailing out. this play requires ‘bar‘"
      when: bar is not defined

2、debug模块

Print statements during execution 

打印执行过程中的语句,通常用来调试编写好的playbook语句,

Examples
# Example that prints the loopback address and gateway for each host
- debug: msg="System {{ inventory_hostname }} has uuid {{ ansible_product_uuid }}"
- debug: msg="System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}"
  when: ansible_default_ipv4.gateway is defined
- shell: /usr/bin/uptime
  register: result
- debug: var=result verbosity=2
- name: Display all variables/facts known for a host
  debug: var=hostvars[inventory_hostname] verbosity=4

生产环境遇到的一个案例:

有2台server:

第一台:10.0.90.25安装了nginx

第二台:10.0.90.26没有安装nginx

现在我只想在没有安装nginx的server上做操作,需要通过when条件语句实现,如下:

#cat test1.yml
---
- hosts: web
  remote_user: root
  tasks:
    - name: ps
      shell: ps -ef | grep nginx | grep -v grep|wc -l
      register: nginx_num
    - debug: var=nginx_num
    - name: command 
      copy: src=/etc/ansible/server.xml dest=/root
      when: nginx_num.stdout == "0"

PS:刚开始的时候,没有添加- debug: var=nginx_num这一项,结果执行的时候,总是skipping跳过,说明条件错误后来才使用debug模块调试

执行结果:

#ansible-playbook  test1.yml 
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [10.0.90.25]
ok: [10.0.90.26]
TASK [ps] **********************************************************************
changed: [10.0.90.25]
changed: [10.0.90.26]
TASK [debug] *******************************************************************
ok: [10.0.90.25] => {
    "nginx_num": {
        "changed": true, 
        "cmd": "ps -ef | grep nginx | grep -v grep|wc -l", 
        "delta": "0:00:00.008476", 
        "end": "2016-05-19 20:40:51.742088", 
        "rc": 0, 
        "start": "2016-05-19 20:40:51.733612", 
        "stderr": "", 
        "stdout": "3", 
        "stdout_lines": [
            "3"
        ], 
        "warnings": []
    }
}
ok: [10.0.90.26] => {
    "nginx_num": {
        "changed": true, 
        "cmd": "ps -ef | grep nginx | grep -v grep|wc -l", 
        "delta": "0:00:00.009458", 
        "end": "2016-05-19 20:40:51.754993", 
        "rc": 0, 
        "start": "2016-05-19 20:40:51.745535", 
        "stderr": "", 
        "stdout": "0", 
        "stdout_lines": [
            "0"
        ], 
        "warnings": []
    }
}
TASK [command] *****************************************************************
skipping: [10.0.90.25]
changed: [10.0.90.26]
PLAY RECAP *********************************************************************
10.0.90.25                 : ok=3    changed=1    unreachable=0    failed=0   
10.0.90.26                 : ok=4    changed=2    unreachable=0    failed=0

可以看到跳过了10.0.90.25,只在10.0.90.26上执行了命令。


本文出自 “知识体系” 博客,请务必保留此出处http://linuxg.blog.51cto.com/4410110/1775166

以上是关于Ansible 自动化运维工具之when条件语句的主要内容,如果未能解决你的问题,请参考以下文章

自动化运维管理工具 Ansible之playbook剧本的详细解读

Ansible 日常使用技巧 (下)

自动化运维工具Ansible之Playbooks循环语句

ansible条件判断when

自动化运维工具Ansible实战playbook循环

自动化运维工具之ansible