ansible-playbook的when条件语句

  |   0 评论   |   0 浏览

ansible-playbook的when条件语句

参考官方文档:链接

一、简单例子

This is easy to do in Ansible with the when clause, which contains a raw Jinja2 expression without double curly braces (see group_by – Create Ansible groups based on facts). It’s actually pretty simple:

tasks:
  - name: "shut down Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_facts['os_family'] == "Debian"
    # note that all variables can be used directly in conditionals without double curly braces

You can also use parentheses to group conditions:

tasks:
  - name: "shut down CentOS 6 and Debian 7 systems"
    command: /sbin/shutdown -t now
    when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or
          (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7")

Multiple conditions that all need to be true (a logical ‘and’) can also be specified as a list:

tasks:
  - name: "shut down CentOS 6 systems"
    command: /sbin/shutdown -t now
    when:
      - ansible_facts['distribution'] == "CentOS"
      - ansible_facts['distribution_major_version'] == "6"

二、根据上一步执行的结果来决定下一步的操作

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

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

  # In older versions of ansible use ``success``, now both are valid but succeeded uses the correct tense.
  - command: /bin/something_else
    when: result is succeeded

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

三、将string类型转为int类型,再比较

tasks:
  - shell: echo "only on Red Hat 6, derivatives, and later"
    when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6

四、string类型的变量(如: 变量内容为 ‘yes’, ‘on’, ‘1’, ‘true)的判断:加上 |bool 过滤器

# 变量定义如下
vars:
  epic: true
  monumental: "yes"

例子如下:

tasks:
    - shell: echo "This certainly is epic!"
      when: epic or monumental|bool
    - shell: echo "This certainly isn't epic!"
      when: not epic

判断变量是否定义:

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

五、Loops and Conditionals

Combining when with loops (see Loops), be aware that the when statement is processed separately for each item. This is by design:

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

If you need to skip the whole task depending on the loop variable being defined, used the |default filter to provide an empty iterator:

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

If using a dict in a loop:

- command: echo {{ item.key }}
  loop: "{{ query('dict', mydict|default({})) }}"

六、Applying ‘when’ to roles, imports, and includes

Note that if you have several tasks that all share the same conditional statement, you can affix the conditional to a task include statement as below. All the tasks get evaluated, but the conditional is applied to each and every task:

- import_tasks: tasks/sometasks.yml
  when: "'reticulating splines' in output"

Or with a role:

- hosts: webservers
  roles:
     - role: debian_stock_config
       when: ansible_facts['os_family'] == 'Debian'
     - role: redhat_stock_config
       when: ansible_facts['os_family'] == 'RedHat'

七、Selecting Files And Templates Based On Variables

Note

This is an advanced topic that is infrequently used. You can probably skip this section.

Sometimes a configuration file you want to copy, or a template you will use may depend on a variable. The following construct selects the first available file appropriate for the variables of a given host, which is often much cleaner than putting a lot of if conditionals in a template.

The following example shows how to template out a configuration file that was very different between, say, CentOS and Debian:

- name: template a file
  template:
      src: "{{ item }}"
      dest: /etc/myapp/foo.conf
  loop: "{{ query('first_found', { 'files': myfiles, 'paths': mypaths}) }}"
  vars:
    myfiles:
      - "{{ansible_facts['distribution']}}.conf"
      -  default.conf
    mypaths: ['search_location_one/somedir/', '/opt/other_location/somedir/']

八、Register Variables

Often in a playbook it may be useful to store the result of a given command in a variable and access it later. Use of the command module in this way can in many ways eliminate the need to write site specific facts, for instance, you could test for the existence of a particular program.

Note

Registration happens even when a task is skipped due to the conditional. This way you can query the variable for is skipped to know if task was attempted or not.

The ‘register’ keyword decides what variable to save a result in. The resulting variables can be used in templates, action lines, or when statements. It looks like this (in an obviously trivial example):

- 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

As shown previously, the registered variable’s string contents are accessible with the ‘stdout’ value. The registered result can be used in the loop of a task if it is converted into a list (or already is a list) as shown below. “stdout_lines” is already available on the object as well though you could also call “home_dirs.stdout.split()” if you wanted, and could split by other fields:

- name: registered variable usage as a loop 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
      loop: "{{ home_dirs.stdout_lines }}"
      # same as loop: "{{ home_dirs.stdout.split() }}"

As shown previously, the registered variable’s string contents are accessible with the ‘stdout’ value. You may check the registered variable’s string contents for emptiness:

- 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 == ""

## 九、变量取值列表

[ansible_facts[‘distribution’]

Possible values (sample, not complete list):

Alpine
Altlinux
Amazon
Archlinux
ClearLinux
Coreos
CentOS
Debian
Fedora
Gentoo
Mandriva
NA
OpenWrt
OracleLinux
RedHat
Slackware
SMGL
SUSE
Ubuntu
VMwareESX

[ansible_facts‘distribution_major_version’]

This will be the major version of the operating system. For example, the value will be 16 for Ubuntu 16.04.

[ansible_facts[‘os_family’]

Possible values (sample, not complete list):

AIX
Alpine
Altlinux
Archlinux
Darwin
Debian
FreeBSD
Gentoo
HP-UX
Mandrake
RedHat
SGML
Slackware
Solaris
Suse
Windows

标题:ansible-playbook的when条件语句
作者:SmiteLi
地址:https://smite.site/articles/2020/03/28/1585373545256.html