I have a custom module for Ansible written in Python that I maintain, and I need to be able to pass in all detected Ansible facts as a dictionary into this module.
Currently, I'm attempting to do this like so:
- name: run tests
degoss:
# ...
facts: "{{ ansible_facts }}"
My module's argument spec looks like this:
AnsibleModule(argument_spec=dict(
# ...
facts=dict(required=False, default={}),
), ...)
My module documentation also specifies this:
DOCUMENTATION="""
# ...
options:
facts:
required: false
default: empty dictionary
description: A dictionary of Ansible facts.
"""
However, as I do input sanitization and validation, I receive a str
instead of a dictionary:
if not isinstance(self.facts, dict):
self.fail("The 'facts' parameter to this module must be a dictionary, not a {}".format(type(self.facts)))
This is thrown at runtime:
The 'facts' parameter to this module must be a dictionary, not a <type 'str'>
Is there a specific syntax I need to use to pass a value as a dictionary, or do I need to treat dictionary variables as JSON and attempt to deserialize them?
As described here , you can specify what type ansible can expect.
AnsibleModule(argument_spec=dict(
# ...
facts=dict(required=False, default={}, type=dict),
), ...)
Then 'facts' will be a dictionary
This works:
Pass ansible_facts piping it to to_json
filter in your play.
- name: run tests degoss: #... facts: "{{ ansible_facts | to_json }}"
In your python module decode the json using either json.loads
or ast.literal_eval
import json import ast... facts = json.loads(module.params.get('facts')) facts = ast.literal_eval(module.params.get('facts'))...
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.