简体   繁体   中英

ansible set fact from another task output

I have trouble some ansible modules. I wrote the custom module and its output like this:

ok: [localhost] => {
    "msg": {
        "ansible_facts": {
            "device_id": "/dev/sdd"
        },
        "changed": true,
        "failed": false
    }
}

my custom module:

#!bin/env python
from ansible.module_utils.basic import *
import json
import array
import re

def find_uuid():
  with open("/etc/ansible/roles/addDisk/library/debug/disk_fact.json") as disk_fact_file, open("/etc/ansible/roles/addDisk/library/debug/device_links.json") as device_links_file:
    disk_fact_data = json.load(disk_fact_file)
    device_links_data = json.load(device_links_file)
    device = []
    for p in disk_fact_data['guest_disk_facts']:
      if disk_fact_data['guest_disk_facts'][p]['controller_key'] == 1000 :
        if disk_fact_data['guest_disk_facts'][p]['unit_number'] == 3:
           uuid = disk_fact_data['guest_disk_facts'][p]['backing_uuid'].split('-')[4]
           for key, value in device_links_data['ansible_facts']['ansible_device_links']['ids'].items():
              for d in device_links_data['ansible_facts']['ansible_device_links']['ids'][key]:
                  if uuid in d:
                     if key not in device:
                        device.append(key)
  if len(device) == 1:
     json_data={
         "device_id": "/dev/" + device[0]
     }
     return True, json_data
  else:
    return False

check, jsonData = find_uuid()

def main():
  module = AnsibleModule(argument_spec={})

  if check:
     module.exit_json(changed=True, ansible_facts=jsonData)
  else:
     module.fail_json(msg="error find device")
main()

I want to use device_id variable on the other tasks. I think handle with module.exit_json method but how can I do that?

I want to use device_id variable on the other tasks

The thing you are looking for is register: in order to make that value persist into the "host facts" for the hosts against which that task ran. Then, you can go with "push" model in which you set that fact upon every other host that interests you, or you can go with a "pull" model wherein interested hosts can reach out to get the value at the time they need it.

Let's look at both cases, for comparison.

First, capture that value, and I'll use a host named "alpha" for ease of discussion:

- hosts: alpha
  tasks:
  - name: find the uuid task
    # or whatever you have called your custom task
    find_uuid:
    register: the_uuid_result

Now the output is available is available on the host "alpha" as {{ vars["the_uuid_result"]["device_id"] }} which will be /dev/sdd in your example above. One can also abbreviate that as {{ the_uuid_result.device_id }}

In the "push" model, you can now iterate over all hosts, or just those in a specific group, that should also receive that device_id fact; for this example, let's target an existing group of hosts named "need_device_id":

- hosts: alpha  # just as before, but for context ...
  tasks:
  - find_uuid:
    register: the_uuid_result

  # now propagate out the value
  - name: declare device_id fact on other hosts
    set_fact:
       device_id: '{{ the_uuid_result.device_id }}'
    delegate_to: '{{ item }}'
    with_items: '{{ groups["need_device_id"] }}'

And, finally, in contrast, one can reach over and pull that fact if host "beta" needs to look up the device_id that host "alpha" discovered:

- hosts: alpha
  # as before
- hosts: beta
  tasks:
  - name: set the device_id fact on myself from alpha
    set_fact:
      device_id: '{{ hostvars["alpha"]["the_uuid_result"]["device_id"] }}'

You could also run that same set_fact: device_id: business on "alpha" in order to keep the "local" variable named the_uuid_result from leaking out of alpha's playbook. Up to you.

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