zoukankan      html  css  js  c++  java
  • Ansible Playbook Conditionals

    通常,play的结果可能取决于变量的值,facts(有关远程系统的知识)或先前的任务结果。 在某些情况下,变量的值可能取决于其他变量。 此外,可以创建其他组,以根据主机是否与其他条件匹配来管理主机。 在Ansible中有许多控制执行流程的选项。 支持条件的更多示例可以在这里找到: http : //jinja.pocoo.org/docs/dev/templates/#comparisons

    When 语句

    有时您会想要跳过特定主机上的特定步骤。 如果操作系统是特定版本,这可能是一个简单的方法,如果没有安装某个包,或者如果文件系统正在充满,可能会执行一些清理步骤。

    这在使用when子句很容易做到,它包含一个没有双大括号的原始Jinja2表达式(见变量 )。 其实很简单:

    tasks:
      - name: "shut down Debian flavored systems"
        command: /sbin/shutdown -t now
        when: ansible_os_family == "Debian"
        # note that Ansible facts and vars like ansible_os_family can be used
        # directly in conditionals without double curly braces

    您也可以使用括号来分组条件:
    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")
    所有需要为真的多个条件(逻辑“和”)也可以指定为列表:
    asks:
      - name: "shut down CentOS 6 systems"
        command: /sbin/shutdown -t now
        when:
          - ansible_distribution == "CentOS"
          - ansible_distribution_major_version == "6"

    一些Jinja2“过滤器”也可以在语句中使用,其中一些是唯一的,由Ansible提供。 假设我们想忽略一个语句的错误,然后决定根据成功或失败有条件地做某些事情:
    tasks:
      - command: /bin/false
        register: result
        ignore_errors: True
    
      - command: /bin/something
        when: result|failed
    
      # In older versions of ansible use |success, now both are valid but succeeded uses the correct tense.
      - command: /bin/something_else
        when: result|succeeded
    
      - command: /bin/still/something_else
        when: result|skipped


    请注意,这是“register”声明的一点点预示。 我们稍后会在本章中讨论。

    提醒您,要查看特定系统上有哪些facts,您可以执行以下操作:

    ansible hostname.example.com -m setup

    提示:有时您会收到一个字符串的变量,您将需要对其进行数学运算比较。 你可以这样做:

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


    也可以使用在playbooks或inventory中定义的变量。 一个例子可能是基于一个变量的布尔值执行一个任务:
    vars:
      epic: true

    那么条件执行可能如下所示:
    tasks:
        - shell: echo "This certainly is epic!"
          when: epic
    要么:
    tasks:
        - shell: echo "This certainly isn't epic!"
          when: not epic

    如果未设置必需变量,则可以使用Jinja2 定义的测试来跳过或失败。 例如:
    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

    这与vars文件的条件导入(见下文)相结合特别有用。 如示例所示,您不需要使用{{}}在条件中使用变量,因为这些变量已经被隐含。

    Loops and Conditionals

    结合with_items (请参阅循环 ),请注意,每个项目分别处理when语句。 这是设计:

    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

    如果使用没有列表的with_dict
    - command: echo {{ item.key }}
      with_dict: "{{ mydict|default({}) }}"
      when: item.value > 5

    Loading in Custom Facts

    如果需要,提供自己的facts也很容易,这在开发模块中有所体现。 要运行它们,只需在您的任务列表顶部调用您自己的自定义facts收集模块,返回的变量将在以后的任务中访问:

    tasks:
        - name: gather site specific fact data
          action: site_facts
        - command: /usr/bin/thingy
          when: my_custom_fact_just_retrieved_from_the_remote_system == '1234'

    Applying ‘when’ to roles and includes

    请注意,如果您有多个任务共享相同的条件语句,则可以将条件附加到如下的任务include语句。 所有的任务得到评估,但条件应用于每个任务:

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

    - hosts: webservers
      roles:
         - { role: debian_stock_config, when: ansible_os_family == 'Debian' }

    在不符合条件的系统上使用此方法时,默认情况下,您将会注意到很多“跳过”输出。 在“ 关于模块”文档中的“group_by”模块上阅读,以获得更加精简的方式来完成相同的操作。

    Conditional Imports

    有时你会根据某些标准,在一个playbook里做一些不同的事情。 有一本适用于多个平台和操作系统版本的playbook就是一个很好的例子。

    例如,CentOS和Debian之间的Apache软件包的名称可能不同,但可以在一个可读的Playbook中使用最少的语法进行处理:

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


    作为提醒,各种YAML文件只包含键值和值:

    ---
    # for vars/CentOS.yml
    apache: httpd
    somethingelse: 42

    这个怎么用? 如果操作系统是“CentOS”,则第一个可以导入的文件是“vars / CentOS.yml”,如果该文件不存在,则为“/vars/os_defaults.yml”。
    如果列表中没有找到任何文件,则会出现错误。 在Debian上,它会首先查看'vars / Debian.yml'而不是'vars / CentOS.yml',然后再回到'vars / os_defaults.yml'。 很简单
    要使用这个条件导入功能,您需要在运行该playbook之前安装facter或ohai,但如果您喜欢,您可以将其与Ansible一起推出:
    # for facter
    ansible -m yum -a "pkg=facter state=present"
    ansible -m yum -a "pkg=ruby-json state=present"
    
    # for ohai
    ansible -m yum -a "pkg=ohai state=present"

    可配置的配置方法 - 将变量与任务分离,使您的剧本不会变成具有丑陋的嵌套ifs,条件等的任意代码,并导致更精简和可审计的配置规则,特别是因为至少有一个决策点要跟踪。

    Selecting Files And Templates Based On Variables

    有时您要复制的配置文件或您将使用的模板可能取决于变量。 以下构造选择适合于给定主机的变量的第一个可用文件,这通常比在模板中放入大量条件更为干净。

    以下示例显示如何模板化出与CentOS和Debian之间有很大不同的配置文件:

    - name: template a file
      template: src={{ item }} dest=/etc/myapp/foo.conf
      with_first_found:
        - files:
           - {{ ansible_distribution }}.conf
           - default.conf
          paths:
           - search_location_one/somedir/
           - /opt/other_location/somedir/

    Register Variables

    通常在playbook中,将给定命令的结果存储在变量中可能是有用的,然后再访问它。 以这种方式使用命令模块可以在很多方面消除编写站点特定事实的需要,例如,您可以测试特定程序的存在。

    'register'关键字决定将结果保存到哪个变量中。生成的变量可以在模板,动作行或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

    如前所示,注册变量的字符串内容可通过'stdout'值访问。 注册结果可以在任务的“with_item”中被使用,如果它被转换成列表(或已经是列表),如下所示。
    “stdout_lines”也可以在对象上使用,但是如果需要也可以调用“home_dirs.stdout.split()”,并且可以被其他字段分割:
    - 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() }}"

    如前所示,注册变量的字符串内容可通过'stdout'值访问。 您可以检查注册变量的字符串内容为空:
    - 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 == ""
     
     
     
     
     


     
     
  • 相关阅读:
    cocos2dx 2.0 学习笔记简单动画
    几种插入数据的方法
    c#中如何获取本机用户名、MAC地址、IP地址、硬盘ID、CPU序列号、系统名称、物理内存
    C#高效编程改进C#代码的50个行之有效的办法摘抄笔记
    获取两个日期之间的每一天
    取SQL中某个字段的后两位
    该行已经属于另一个表 的解决办法
    一个实体对象不能由多个 IEntityChangeTracker 实例引用
    MVC返回JSON,IE下无法接收JSON,IE下JSON提示另存为
    entity framework DbContext Attach判断
  • 原文地址:https://www.cnblogs.com/mhc-fly/p/7121149.html
Copyright © 2011-2022 走看看