3

I am writing a custom Action Plugin for Ansible which I use in my playbook and I am trying to set a variable that will be used in the next task, in the playbook, by a (custom) module.

Effectively, the playbook equivalent of what I am trying to mimic is a set_fact task like so:

- name: set_fact task
  set_fact: 
    ansible_python_interpreter: /path/to/python

In my custom Action Plugin, I have used self._execute_module before to execute other modules (such as slurp) within the plugin code. However, with the set_fact module it doesn't seem to be updating the ansible_python_interpreter variable, as expected.

I have tried the following:

self._execute_module(module_name='ansible.builtin.set_fact',
                     module_args=dict(ansible_python_interpreter=/path/to/python),
                     task_vars=task_vars)

And I have also tried different variations of module_args:

module_args=dict(key_value={ansible_python_interpreter=/path/to/python})
module_args=dict(key_value='ansible_python_interpreter:/path/to/python')

However, my ansible_python_interpreter does not seem to be changing.

Any help, please?

Zeitounator
  • 38,476
  • 7
  • 53
  • 66
hs14428
  • 109
  • 5
  • 2
    `set_fact` is actually an action plugin, itself, this is maybe why this is not working as you expect it. This is backed up by: 1/ the module being an empty Python file, except for its documentation and examples: https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/set_fact.py; 1/ the plugin action file: https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/action/set_fact.py – β.εηοιτ.βε Apr 12 '23 at 23:02
  • @β.εηοιτ.βε yeah thats a good caveat I didn't consider initially. I have posted an answer now. – hs14428 Apr 13 '23 at 15:36

1 Answers1

0

The closest I can get is to return a dict containing the Ansible facts that I want to be set for the playbook simply by following the dev guide for Action Plugins on the Ansible docs.

So, as I am returning an _execute_model() call in my plugin as well, my run() function in my plugin would look something like this:

def run(self, tmp=None, task_vars=None):
    # Plugin code here

    facts = dict()
    facts['ansible_python_interpreter'] = '/path/to/python'

    return dict(self._execute_module(module_name='my_custom_module',
                                     module_args=module_args,
                                     task_vars=task_vars),
                ansible_facts=dict(facts))

However, unfortunately this throws another warning/error of:

[WARNING]: Removed restricted key from module data: ansible_python_interpreter

And this seems to be due to a safety mechanism for overriding connection details, and so I have gone down a different route for my plugin.

In another use case, returning dict(ansible_facts=dict(facts)) (like in the docs) would work if it wasn't a connection var I was trying to override, I believe.

hs14428
  • 109
  • 5