Pass custom credential values to dynamic yaml inventory

I made a custom credential Vault-Token

For the Injector configuration it has

extra_vars:
  ansible_hashi_vault_url: '{{ vault_address }}'
  ansible_hashi_vault_token: '{{ secret_id }}'

Inside my inventory source i am trying to use a vault lookup

plugin: community.hrobot.robot
hetzner_user: …
hetzner_password: "{{ lookup('community.hashi_vault.hashi_vault', 'cloud/hetzner/hrobot/webservice_password) }}"

However it seems the execpted vars are not set (the vault lookup supports vars such as ansible_hashi_vault_url, but i don’t think these are set.

The error is Required option url was not set… Required option url was not set

i also tried "{{ lookup('community.hashi_vault.hashi_vault', 'cloud/hetzner/hrobot/webservice_password',url=extra_vars.ansible_hashi_vault_url, token=extra_vars.ansible_hashi_vault_token) }}", which also did not work.

Using env in the custom credential does not work either, because i am not allowed to use ANSIBLE_* env vars.

How does one use custom credentials in an inventory yaml file?

tx.,

something is happening, not sure what yet, but i a getting a " 401 UNAUTHORIZED (Unauthorized)"

EDIT: Please ignore, this was an unrelated syntax related error

no, because to test if the vars are passed on, i set the URL to a bogus one, and i still got a 401 and not a 404.

EDIT: Please ignore, this was an unrelated syntax related error

It looks like a bug in the inventory plugin. It does not use the extra vars. Changing this line from self.templar = Templar(loader=loader) to self.templar = Templar(loader=loader, variables=self._vars) may fix it (untested).

1 Like

Thanks for your reply.

We have been trying the patch you mentioned. However, the vars such as ansible_hashi_vault_addr are still not available in the yaml file. We tried prefixing with extra_vars. (such as extra_vars.ansible_hashi_vault_addr), but that also resulted in undefined-errors.

A colleague of mine found a workable solution using env vars.

The custom credential uses the following for its Injector configuration:

env:
  VAULT_URL: '{{ vault_address }}'
  VAULT_ADDR: '{{ vault_address }}'
  VAULT_ROLE_ID: '{{ role_id }}'
  VAULT_SECRET_ID: '{{ secret_id }}'
  VAULT_AUTH_METHOD: approle

The inventory file then uses nested lookups:

hetzner_password: |
  "{{ lookup('community.hashi_vault.hashi_vault',
       'cloud/hetzner/hrobot/webservice_password', 
       url=lookup('env', 'VAULT_URL'), 
       role_id=lookup('env', 'VAULT_ROLE_ID'), 
       secret_id=lookup('env', 'VAULT_SECRET_ID'), 
       auth_method=lookup('env', 'VAULT_AUTH_METHOD') ) }}"

Glad you found a solution. I’d still consider that the plugin doesn’t support extra vars a bug, here’s an example of how it should work (using a different inventory plugin, which has an option to enable --extra-vars).

# test_constructed.yml 
plugin: ansible.builtin.constructed
strict: true  # give an error for undefined variables
compose:
  test_var: extra_vars.foo
use_extra_vars: true
# extra_vars.yml 
extra_vars:
  foo: bar

File-based extra vars need to be passed to --extra-vars with a @ prefix:

$ ansible-inventory -i host1, -i test_constructed.yml --list --extra-vars @extra_vars.yml
{
    "_meta": {
        "hostvars": {
            "host1": {
                "extra_vars": {
                    "foo": "bar"
                },
                "test_var": "bar"
            }
        }
    },
    "all": {
        "children": [
            "ungrouped"
        ]
    },
    "ungrouped": {
        "hosts": [
            "host1"
        ]
    }
}

Another issue is that most configuration items in inventory do not support templating (constructed derivatives being the exception). config options templatable by bcoca · Pull Request #79244 · ansible/ansible · GitHub

1 Like