代码之家  ›  专栏  ›  技术社区  ›  George Shuklin

如果存在任何“已更改”的任务,则强制ansible失败(返回非零代码)

  •  1
  • George Shuklin  · 技术社区  · 6 年前

    我想为剧本做一个收敛测试。收敛测试检查同一剧本的第二次运行是否没有变化。

    有没有一种方法可以说Ansible“如果有一个任务处于‘已更改’状态,则使退出代码为非零?”。我能解析标准输出,但它很难看。

    set -e
    ansible-playbook -i inventory.yaml site.yaml  # normal run
    ansible-playbook --help-me-here -i inventory.yaml site.yaml  # should return non-zero if anything changed.
    
    
    0 回复  |  直到 6 年前
        1
  •  0
  •   Markus W Mahlberg    6 年前

    除了我在评论中加入的选项之外,还有一个选项是使用 molecule ansible-role-sssh ,尽管从那时起分子已经失去了流浪者的支持。

    $ python3 -m venv ./role-devel
    $ source ./role-devel/bin/activate
    $ pip install "molecule[lint,docker]"
    [...]
    $ molecule init role  yourrole
    --> Initializing new role yourrole...
    Initialized role in /path/to/yourrole successfully.
    

    现在编辑你的 tasks/main.yml

    ---
    # tasks file for yourrole
    - debug:
        var=ansible_date_time.iso8601
    - name: Update motd
      template:
        src: "motd.j2"
        dest: "/etc/motd"
    

    创造 templates/motd.j2 :

    THIS SYSTEM IS PROUDLY MANAGED BY ANSIBLE SINCE {{ ansible_date_time.iso8601 }}
    

    Update motd 在第一轮和第二轮都发生了变化。因此,幂等检验将失败:

    $ molecule test
    
    [...]
    
    --> Scenario: 'default'
    --> Action: 'converge'
    
        PLAY [Converge] ****************************************************************
    
        TASK [Gathering Facts] *********************************************************
        ok: [instance]
    
        TASK [Include yourrole] ********************************************************
    
        TASK [yourrole : debug] ********************************************************
        ok: [instance] => {
            "ansible_date_time.iso8601": "2020-03-21T11:31:05Z"
        }
    
        TASK [yourrole : Update motd] **************************************************
        changed: [instance]
    
        PLAY RECAP *********************************************************************
        instance                   : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    --> Scenario: 'default'
    --> Action: 'idempotence'
    ERROR: Idempotence test failed because of the following tasks:
    * [instance] => yourrole : Update motd
    An error occurred during the test sequence action: 'idempotence'. Cleaning up.
    
    [...]
    
    $ echo $?
    1
    
        2
  •  0
  •   Uttam    6 年前

    documentation 没有直接的选择,

    你可以这样做,

    创建一个布尔变量来跟踪 应该被视为失败。 评估剧本中的控制。

    - hosts: localhost
      gather_facts: no
      tasks:
      - debug:
          msg: "Test message"
    #   This task reports 'changed' always because we set changed_when to True
        changed_when: True
        register: result
    #   We can control whether or not to fail the task if task reports changed. 
    #   The task fails if 
    #     it actually fails or 
    #     when it changes and when we ask it to consider change as a failure
    #   Note: Defaults to understand changed just means changed and not failed
        failed_when:
          - result is failed or (result.changed and changed_means_failure|default(False)|bool)
    

    执行你的行动手册

    set -e
    
    ansible-playbook -i inventory.yaml site.yaml  # normal run
    ansible-playbook --extra-vars "changed_means_failure=True" -i inventory.yaml site.yaml  # should return non-zero if anything changed.