ansible / awx

AWX provides a web-based user interface, REST API, and task engine built on top of Ansible. It is one of the upstream projects for Red Hat Ansible Automation Platform.
Other
13.97k stars 3.41k forks source link

Constructed inventory will fail if encrypted variables are used. #14680

Open janorn opened 10 months ago

janorn commented 10 months ago

Please confirm the following

Bug Summary

The following constructed inventory will fail if the tested variable is containing encrypted data.

---
plugin: constructed
strict: true
use_vars_plugins: true
groups:
  dict_group: test_dict is defined

If a host_vars contains this it will fail:

test_dict:
  name: host2
  password: '{{ test_secret }}'
test_secret: '{{ test_secret_vault }}'
test_secret_vault: !vault |
  $ANSIBLE_VAULT;1.2;AES256;all
  36343365643636653362623963373537393562663633333936323934333066653736373032616336
  6335363532663539333437393964663731336532383562340a633937393932626239363832383032
  38663333386665336337666563666264653334623138666165613030613132353366383965323864
  3038653332303664340a343636663030386362636138366431633462616663373933373834353765
  3136

AWX version

23.4.0

Select the relevant components

Installation method

kubernetes

Modifications

no

Ansible version

-

Operating system

-

Web browser

Edge

Steps to reproduce

You can find a complete test inventory here: https://github.com/janorn/awx_inventory.git

Us it and create a constructed inventory with the following config:

---
plugin: constructed
strict: true
use_vars_plugins: true
groups:
  dict_group: test_dict is defined

Hit sync and it will fail.

Expected results

A new inventory with only two hosts

Actual results

'{'name': 'host2', 'password': '{{ test_secret }}'}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ test_secret_vault }}'. Error was a <class 'ansible.parsing.vault.AnsibleVaultError'>, original message: Attempting to decrypt but no vault secrets found . Could not add host host2 to group dict_group: An unhandled exception occurred while templating '{'name': 'host2', 'password': '{{ test_secret }}'}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ test_secret_vault }}'. Error was a <class 'ansible.parsing.vault.AnsibleVaultError'>, original message: Attempting to decrypt but no vault secrets found [WARNING]: * Failed to parse /runner/inventory/constructed.yml with script plugin: problem running /runner/inventory/constructed.yml --list ([Errno 8] Exec format error: '/runner/inventory/constructed.yml') ERROR! Completely failed to parse inventory source /runner/inventory/constructed.yml

Additional information

'{'name': 'host2', 'password': '{{ test_secret }}'}'. Error was a <class
'ansible.errors.AnsibleError'>, original message: An unhandled exception
occurred while templating '{{ test_secret_vault }}'. Error was a <class
'ansible.parsing.vault.AnsibleVaultError'>, original message: Attempting to
decrypt but no vault secrets found . Could not add host host2 to group
dict_group: An unhandled exception occurred while templating '{'name': 'host2',
'password': '{{ test_secret }}'}'. Error was a <class
'ansible.errors.AnsibleError'>, original message: An unhandled exception
occurred while templating '{{ test_secret_vault }}'. Error was a <class
'ansible.parsing.vault.AnsibleVaultError'>, original message: Attempting to
decrypt but no vault secrets found
[WARNING]:  * Failed to parse /runner/inventory/constructed.yml with script
plugin: problem running /runner/inventory/constructed.yml --list ([Errno 8]
Exec format error: '/runner/inventory/constructed.yml')
ERROR! Completely failed to parse inventory source /runner/inventory/constructed.yml
gendergap commented 7 months ago

I ran into a similar situation (not using a constructed inventory, but one sources from a plugin dynamically). If the plugin requires credentials for, e.g., an external API, it will fail.

The UI even has an option to select secrets, but this does not offer to select Vault secrets. The API call seems to filter for credentials of kind "cloud". Also, the code building the ansible-inventory call does not have any logic to include a vault secret, as far as I can see anyway.