简体   繁体   中英

Ansible set fact for a failure

I'm trying to create a custom fact in Ansible for when hosts are unreachable. If a host is unreachable or has another failure type I'd like to set a fact with a custom dict. I am able to assign the fact for the reachable hosts but not for the unreachable hosts using when statement. Is there way I can set a custom fact on failure?

Example Playbook:

---
  - hosts: myhosts
    gather_facts: False

    tasks:
    - name: Get Dict
      shell: "cat /path/dict_file"
      register: result
      ignore_errors: True

    - set_fact:
        result_dict={"cause": "connection timed out"}
      when: result is failed

    - set_fact:
       result_dict="{{ result.stdout }}"
      when: result is success

When I attempt set a fact and assign the result_dict var to a custom dict value I get the below syntax error.

Error:

ERROR! Syntax Error while loading YAML.
  expected <block end>, but found '}'

Desired Output for result_dict on unreachable host:

ok: [host-b] => {
    "result_dict": {"cause": "connection timed out"}
}

It's possible to use Blocks error handling "to handle errors in a way similar to exceptions in most programming languages" . For example

- hosts: myhosts
  gather_facts: false
  tasks:

    - block:
        - command: "head -1 /etc/motd"
          register: result
      rescue:
        - meta: clear_host_errors

    - set_fact:
        result_dict: "{{ result.failed|
                         ternary('cause: connection timed out',
                         result.stdout) }}"
    - debug:
        var: result_dict

gives

ok: [test_01] => {
    "result_dict": "FreeBSD 12.0-RELEASE r341666 GENERIC "
}
ok: [test_02] => {
    "result_dict": "FreeBSD 12.0-RELEASE r341666 GENERIC "
}
ok: [test_03] => {
    "result_dict": "FreeBSD 12.0-RELEASE r341666 GENERIC "
}
ok: [test_04] => {
    "result_dict": "cause: connection timed out"
}

I was able to accomplish this by setting playbook keyword ignore_unreachable to true to allow tasks to continue for unreachable hosts and then using a when statement to assign the timeout dict for unreachable hosts only. I also needed to correct the format of the timeout dict.

When Statements:

- name: FAILED
  set_fact:
    result_dict:
      cause: 'Timeout'
  when: "'unreachable' in result"

- name: PASSED
  set_fact:
   result_dict="{{ result.stdout | from_json }}"
  when: "'unreachable' not in result"
- debug: var=result_dict

Output:

ok: [localhost] => {
    "my_final_map": {
        "cause": "Timeout", 
        "host_a": [
            {
                "ip-1": {
                    "port": "22", 
                    "service": "ssh"
                }
            }, 
            {
                "ip-2": {
                    "port": "21", 
                    "service": "ftp"
                }
            }
        ]
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM