0

I have an Ansible collection for managing TrueNAS boxes. The core is a utility class that talks to the middleware daemon to check the configuration and make changes. There's a command-line utility to talk to the daemon, but there's also a Python module. I'd like to allow the Ansible user to choose which approach to use, just as they can choose how to ssh to a remote machine, or how to become root. In other words, somewhere in my plugin code I'll have

if method_to_use == 'First':
    method = FirstMethod()
else:
    method = SecondMethod()

But how do I set method_to_use in a playbook, then retrieve it in a plugin that's been called on the remote machine?

My understanding is that inventory variables aren't available inside plugins. But since all of my modules are part of a collection, maybe there's something like a collection-level variable or fact that could be set?

Obviously, I could just have a method: {first|second} option for each module, but I'd prefer not to make the user add that to every single play in their playbook.

I've seen one approach where the first play on any client is something like:

tasks:
  - set_config:
      method: first

where set_config is a plugin that takes its method option and stashes it in a file on the client. Then later plugins read that file to get the configuration. But that seems like a hack. I'm wondering whether there might be a more elegant solution.

Zeitounator
  • 38,476
  • 7
  • 53
  • 66
arensb
  • 159
  • 8

1 Answers1

3

There is nothing like a "collection level" setting that can be specified in your playbooks.

To avoid having to provide it on every task, you can (a) set things in ansible.cfg or (b) get your value from an environment variable.

The community.hashi_vault modules do exactly this, so see their source code for an example.

For example, the hashi_vault lookup module will read config settings from the [hashi_vault_collection] section of ansible.cfg, or it will read from specific ANSIBLE_HASHI_VAULT_* environment variables, or it will read explicit parameters.


If you write your plugin to get defaults from environment variables, you can take advantage of the fact that Ansible allows you to set these at the play level:

- hosts: all
  environment:
    MY_MODULE_DEFAULT_COLOR: blue
    MY_MODULE_FAILURE_ACTION: explode
  tasks:
    - my_module:
        use_method: first

    - my_module:
        use_method: second
larsks
  • 277,717
  • 41
  • 399
  • 399
  • You mean you can put config options in the config file? I wouldn't have thought of that! :-) Thanks! – arensb Jun 29 '23 at 01:08
  • I've been looking through the `hashi_vault` code for a while, but I don't think it does what I want: yes, they've set up a common interface (`class HashiVaultOptionAdapter`) to various options, but as far as I can tell, options from `ansible.cfg` are available only in lookup plugins, not in modules executed on the remote host. If I'm reading [their example](https://docs.ansible.com/ansible/latest/collections/community/hashi_vault/vault_ansible_settings_lookup.html) correctly, they use the kind of hack I mentioned earlier, smuggling global config options in as module options. – arensb Jun 29 '23 at 13:57
  • 1
    I guess that leaves you with option (b), get your common options from environment variables (which can be set per-play or per-task). – larsks Jun 29 '23 at 13:58
  • Looks like it. Unless maybe I can find something clever to do with `module_defaults`. – arensb Jun 29 '23 at 14:04