ansible之条件语句

有时候我们希望在某些情况对特定主机执行、不执行一些操作。例如给某主机安装特定的软件,或者在磁盘快满时执行清理工作。

when

when语句就是用来实现这个功能的,它是一个jinja2的语法,但是不需要双大括号,他真的很简单:

tasks:
  - name: "shut down Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_os_family == "Redhat"
    # 注意 Ansible facts和vars 比如 ansible_os_family 应能被引用
    # 直接写,不带双大括号。
  • 可以用小括号来组织一组条件:
tasks:
  - name: "shut down CentOS 6 and Debian 7 systems"
    command: /sbin/shutdown -t now
    when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") or
          (ansible_distribution == "Debian" and ansible_distribution_major_version == "7")
  • 多重条件需要同时生效才为真(逻辑与),用一个list来写:
tasks:
  - name: "shut down CentOS 7 systems"
    command: /sbin/shutdown -t now
    when:
      - ansible_distribution == "CentOS"
      - ansible_distribution_major_version == "7"

一些jinja2的“filter”可以在条件语句里使用,其中部分filter由ansible提供。这里假设我们需要忽略错误返回信息,然后基于success和failure来决定执行一些动作。

tasks:
  - command: /bin/false
    register: result
    ignore_errors: True

  - command: /bin/something
    when: result|failed

  - command: /bin/something_else
    when: result|succeeded

  - command: /bin/still/something_else
    when: result|skipped

register在后面会说

有时候想对字符串类型的返回变量中使用数学运算符,可以这样做:

tasks:
  - shell: echo "only on Red Hat 6, derivatives, and later"
    when: ansible_os_family == "RedHat" and ansible_lsb.major_release|int >= 6

还可以使用在playbook或者inventory中定义的变量的布尔值来判断。

vars:
  epic: true

然后在task中这样引用判断:

tasks:
    - shell: echo "This certainly is epic!"
      when: epic

或者:

tasks:
    - shell: echo "This certainly isn't epic!"
      when: not epic

如果需要的变量还没有定义,则可以使用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 undefined

这特别适用于var导入的情况,同时在when语句中,变量依然不用{{ }}来表示。(已经隐含了)

循环与条件

把when和with_item结合起来,when语句将会多次在with_item中被执行。

tasks:
    - command: echo {{ item }}
      with_items: [ 0, 2, 4, 6, 8, 10 ]
      when: item > 5

如果需要根据定义的循环变量跳过整个任务,则使用| default过滤器来提供一个空的迭代器:

- command: echo {{ item }}
  with_items: "{{ mylist|default([]) }}"
  when: item > 5

字典型也可以:

- command: echo {{ item.key }}
  with_dict: "{{ mydict|default({}) }}"
  when: item.value > 5

这部分在loop中会学到。

register

在playbook中,把一个命令的结果存在一个变量中并提供后续调用,以这种方式使用命令模块可以在很多方面消除编写site specific facts的需要,例如你可以检测一个特定的程序是否存在。

register关键字决定哪个变量的结果去存入。可以在template,cation line,when语句中使用:

- name: test play
  hosts: all

  tasks:

      - shell: cat /etc/motd
        register: motd_contents

      - shell: echo "motd contains the word hi"
        when: motd_contents.stdout.find('hi') != -1

在上面的例子中,register变量名为motd_contents,它可以使用stdout方法调用,这里调用的是/etc/motd中的返回结果,如果结果中有'hi'字符,第二个cation就会被执行。

with_item

- name: registered variable usage as a with_items list
  hosts: all

  tasks:

      - name: retrieve the list of home directories
        command: ls /home
        register: home_dirs

      - name: add home dirs to the backup spooler
        file: path=/mnt/bkspool/{{ item }} src=/home/{{ item }} state=link
        with_items: "{{ home_dirs.stdout_lines }}"
        # same as with_items: "{{ home_dirs.stdout.split() }}"

上面的例子中,把第一个cation的结果保存在了register变量home_dirs中,在第二个action的item位置,使用with_item的输出语句来作为结果写入。

还可以用一个空字符来检查registered变量中的内容:

- name: check registered variable for emptiness
  hosts: all

  tasks:

      - name: list contents of directory
        command: ls mydir
        register: contents

      - name: check contents for emptiness
        debug: msg="Directory is empty"
        when: contents.stdout == ""
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值