• ansible基础-task控制


    1. 前言

    很多情况下,一个play是否执行会依赖于某个(些)变量的值,这个变量可以来自自定义变量、facts,甚至是另一个task的执行结果。

    ansible通过变量判定task是否执行,我们称之为task控制。

    在我看来,ansible的控制语句带来的最大的好处就是使部署代码更加健壮,举几个例子:

    • 利用「ansible_os_family」变量使部署代码支持更多版本的操作系统
    • 避免很多冗余无用的代码执行,提高代码执行效率
    • 避免很多task意外的执行失败
    • 使playbook满足幂等性

    2. when语句

    ansible使用最频繁的task控制语句就是「when」语句。

    when语句可以在task中直接使用,也可以与include*、import*、roles、vars_files、incloud_vars等引入语句搭配使用。执行结果也比较通俗易懂,前者用来判断task是否执行,后者用来判断task是否引用。

    when语句引用变量时不用加「{{}}」。在when语句中,ansible将不带引号的字符串认定为变量,所以如果使用字符串记得加单(双)引号。

    对不同数据类型的判断可以使用不同的条件语句:

    使用「==」:

    tasks:
      - name: "shut down Debian flavored systems"
        command: /sbin/shutdown -t now
        when: ansible_facts['os_family'] == "Debian"

    使用「is」:

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

    使用「in」:

    when: "'reticulating splines' in output"

    使用运算符(记得使用「int」将参数转为整数类型):

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

    直接判断变量的True/False:

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

    多个条件判断语句结合:

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

    when语句的参数也支持列表,等价于「and」:

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

    3 与引用相关的控制语句

    3.1 条件导入play

    上面说到when语句可以控制task是否被引用,例如当变量「output」包含字符串「reticulating splines」时再导入playbook「sometasks.yml」:

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

    其他的导入语句import_playbook;include_tasks;import_role;include_role;roles等语句使用方法也类似上面的示例。

    3.2 条件导入变量文件

    同样,当task中使用「include_vars」语句导入变量文件时,也可以控制其导入,格式与导入play类似,这里就不举例了。

    4 与register相关的控制语句

    比较特殊的,我们可以基于一个task的执行结果来判断某个task是否执行,此时就用到了「register」语句。这里列举一个我在部署openshift时的例子:

    遇到的问题:

    部署harbor时,我想用「docker network connect」命令将harbor_harbor和ldapserver这两个容器网络打通,但是发现如果这两个容器是已经关联的状态,再次执行playbook时抛报错「Error response from daemon: service endpoint with name ldapserver already exists」这样就不满足ansible的幂等性。

    解决办法

    第一个task是查询harbor_harbor的网络连接信息,并将其注册为一个变量「harbor_conn_info」:

    - name: Get network harbor_harbor connection information
      shell: >
        /usr/bin/docker network inspect harbor_harbor
      register: harbor_conn_info

    上面示例中,变量「harbor_conn_info」是「/usr/bin/docker network inspect harbor_harbor」命令的执行结果,ansible从执行结果中查找「ldapserver」字符串,如果未查到(即find函数结果返回值为-1)则执行「docker network connect」命令。

    通过这个例子,说明ansible的控制语句能够使部署代码满足最基本幂等性要求,也能使代码更加健壮

    5 基于变量的控制语句

    基于变量的控制语句是另外一种task控制方式,不需要「when」语句,例如:

    ---
    - hosts: all
      remote_user: root
      vars_files:
        - "vars/common.yml"
        - [ "vars/{{ ansible_facts['os_family'] }}.yml", "vars/os_defaults.yml" ]
      tasks:
      - name: make sure apache is started
        service: name={{ apache }} state=started

    6 本节应该掌握的技能

    • 掌握task控制的作用以及带来的好处
    • 会在 playbook中使用when语句
    • 掌握register+when的配合使用

    7 参考链接

    • https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html

    欢迎大家关注我的公众号:

  • 相关阅读:
    HDU 1850 Being a Good Boy in Spring Festival
    UESTC 1080 空心矩阵
    HDU 2491 Priest John's Busiest Day
    UVALive 6181
    ZOJ 2674 Strange Limit
    UVA 12532 Interval Product
    UESTC 1237 质因子分解
    UESTC 1014 Shot
    xe5 android listbox的 TMetropolisUIListBoxItem
    xe5 android tts(Text To Speech)
  • 原文地址:https://www.cnblogs.com/mauricewei/p/10055677.html
Copyright © 2020-2023  润新知