首页 > 解决方案 > ansible:根据布尔主机变量跳转到块的救援部分

问题描述

我想根据清单中主变量的内容执行任务。当布尔变量“云”为真时,我希望我的任务失败并执行救援部分。对于我的测试系统,“云”是“假的”。我添加了调试任务以显示“云”的类型和值:

- name: Print value of var "cloud"
  ansible.builtin.debug:
    var: cloud

- name: Print value of var with filter type_debug
  ansible.builtin.debug:
    var: cloud| type_debug

- name: check if target host is cloud system
  set_fact:
    dummy: true
  failed_when: cloud == "true"

  

TASK [Print value of var "cloud"] **********************************************
ok: [host.domain.com] => {
    "changed": false, 
    "cloud": false
}
TASK [Print value of var with filter type_debug] *******************************
ok: [uhost.domain.com] => {
    "changed": false, 
    "cloud| type_debug": "bool"
}
  
TASK [check if target host is cloud system] ************************************
ok: [host.domain.com]

到目前为止,一切都很好。出于测试目的,我希望通过否定检查来看到任务故意失败。我试过了

  failed_when: not cloud

  failed_when: cloud == "false"

但它总是以“ok”结尾:

TASK [check if target host is cloud system] ************************************
ok: [host.domain.com]

为什么检查没有失败?

标签: ansible

解决方案


您说“到目前为止一切顺利”,但您的检查完全不正确。

  failed_when: cloud == "true"

cloud是一个布尔值,所以它永远不会等于字符串"true"

当您尝试与"false";进行比较时,您会犯同样的错误 failed_when: not cloud在 ansible-core 2.11.5 下使用时,我无法重现您的问题。

- hosts: localhost
  gather_facts: false
  vars:
    cloud: false
  tasks:
    - block:
        - name: Debug cloud
          ansible.builtin.debug:
            msg: "{{ cloud }} / {{ cloud | type_debug }}"

        - name: check if target host is cloud system
          set_fact:
            dummy: true
          failed_when: not cloud

      rescue:
        - debug:
TASK [Debug cloud] *************************************************************
ok: [localhost] => {
    "msg": "False / bool"
}

TASK [check if target host is cloud system] ************************************
fatal: [localhost]: FAILED! => {"ansible_facts": {"dummy": true}, "changed": false, "failed_when_result": true}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Hello world!"
}

但是,这不是您应该创建失败的方式。您有两个不错的选择,失败操作和断言操作。我倾向于选择assert.

- hosts: localhost
  gather_facts: false
  vars:
    cloud: true
  tasks:
    - block:
        - name: Debug cloud
          ansible.builtin.debug:
            msg: "{{ cloud }} / {{ cloud | type_debug }}"

        - name: check if target host is cloud system
          assert:
            # There are other ways to check this, but Jinja's built-in false test reads nicely 
            that: cloud is false

      rescue:
        - debug:
TASK [Debug cloud] *************************************************************
ok: [localhost] => {
    "msg": "True / bool"
}

TASK [check if target host is cloud system] ************************************
fatal: [localhost]: FAILED! => {
    "assertion": "cloud is false",
    "changed": false,
    "evaluated_to": false,
    "msg": "Assertion failed"
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Hello world!"
}

推荐阅读