ansible-collections / azure

Development area for Azure Collections
https://galaxy.ansible.com/azure/azcollection
GNU General Public License v3.0
248 stars 332 forks source link

Literal value of ansible variable returned by keyvaultsecret_info "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" #1155

Closed Klaas- closed 1 year ago

Klaas- commented 1 year ago
SUMMARY

Hi, I am trying to use ansible to rotate secrets for service principals. During this I noticed that I can not retrieve a secret from a keyvault that equals the secret of the service principal currently in use (ie rotating it's own secret).

I am unsure if this is a problem in the module or a more general issue with ansible-core.

References: https://github.com/ansible/awx/issues/13912

ISSUE TYPE
COMPONENT NAME

azure.azcollection.azure_rm_keyvaultsecret_info

ANSIBLE VERSION
$ ansible --version
ansible [core 2.13.3]
  config file = /home/username/awx_ansible/ansible.cfg
  configured module search path = ['/home/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/username/awx_ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.13 (main, Nov  9 2022, 13:16:24) [GCC 8.5.0 20210514 (Red Hat 8.5.0-15)]
  jinja version = 3.1.2
  libyaml = True

I also verified it with a current ansible-core in a venv and in awx-ee

COLLECTION VERSION
Collection                     Version
------------------------------ -------
ansible.posix                  1.5.1
awx.awx                        22.0.0
azure.azcollection             1.15.0
community.crypto               2.11.1
community.general              6.5.0
containers.podman              1.10.1
fedora.linux_system_roles      1.35.2
infra.controller_configuration 2.3.1
kubernetes.core                2.4.0
ovirt.ovirt                    3.1.2
servicenow.itsm                2.1.0
CONFIGURATION
$ ansible-config dump --only-changed
COLLECTIONS_PATHS(/home/username/awx_ansible/ansible.cfg) = ['/home/username/awx_ansible/collections']
DEFAULT_ROLES_PATH(/home/username/awx_ansible/ansible.cfg) = ['/home/username/awx_ansible/roles']
OS / ENVIRONMENT

RHEL 8.7

STEPS TO REPRODUCE

You need to load the variables via --extra-vars or add them in playbook

cat playbooks/minimal_reproducer.yml
- hosts: localhost
  connection: local

  tasks:
  - name: set service principal client secret in key vault
    azure.azcollection.azure_rm_keyvaultsecret:
      keyvault_uri: "{{ key_vault_uri }}"
      client_id: "{{ service_principal_application_id }}"
      secret: "{{ service_principal_client_secret }}"
      tenant: "{{ service_principal_tenant }}"
      subscription_id: "{{ key_vault_subscription_id }}"
      secret_name: "service-principal-client-secret"
      secret_value: "{{ service_principal_client_secret }}"

  - name: get service principal client secret from key vault
    azure.azcollection.azure_rm_keyvaultsecret_info:
      vault_uri: "{{ key_vault_uri }}"
      client_id: "{{ service_principal_application_id }}"
      secret: "{{ service_principal_client_secret }}"
      tenant: "{{ service_principal_tenant }}"
      subscription_id: "{{ key_vault_subscription_id }}"
      name:  "service-principal-client-secret"
    register: azure_rm_keyvaultsecret_info_controller_service_principal_client_secret

  - ansible.builtin.fail:
      msg: Secrets literal value is VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
    when: azure_rm_keyvaultsecret_info_controller_service_principal_client_secret.secrets[0].secret == "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
EXPECTED RESULTS

playbook does not fail

ACTUAL RESULTS

Playbook fails

fatal: [localhost]: FAILED! => {"changed": false, "msg": "Secrets literal value is VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"}
Klaas- commented 1 year ago

I can work around this by using the lookup plugin:

{{ lookup('azure.azcollection.azure_keyvault_secret', 'service-principal-client-secret', vault_url=key_vault_uri, client_id=service_principal_application_id, secret=service_principal_client_secret, tenant_id=service_principal_tenant) }}
Fred-sun commented 1 year ago

@Klaas- I tested it locally, and I didn't get any exceptions. You use the return value of azure_rm_keyvaultsecret task. Because secret_value cannot exist in the log, the value returned is "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER". So you should use the return value of azure_rm_keyvaultsecret_info。 The results are as follows: Thanks!

Get seceret info by azure_rm_keyvaultsecret_info:
        "secrets": [
            {
                "attributes": {
                    "created": "2023-05-10T11:10:01+00:00",
                    "enabled": true,
                    "expires": "2030-03-04T04:05:06+00:00",
                    "not_before": "2000-01-02T01:02:03+00:00",
                    "recovery_level": "Recoverable+Purgeable",
                    "updated": "2023-05-10T11:10:01+00:00"
                },
                "content_type": "Content Type Secret",
                "secret": "mysecret",
                "sid": "https://vaultfred003.vault.azure.net/secrets/testsecret/5e10374e21f54cbcbb71592492eb40a0",
                "tags": {
                    "delete": "on-exit",
                    "testing": "test"
                },
                "version": "5e10374e21f54cbcbb71592492eb40a0"
            }
        ]
    }

Get secret by azure.azcollection.azure_keyvault_secret:
TASK [Look up secret] ****************************************************************************************************************
ok: [localhost] => {
    "msg": "mysecret"
}
Klaas- commented 1 year ago

Hi Fred-sun,

Because secret_value cannot exist in the log, the value returned is "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"

I understand that, but what I am saying is that it is not just replaced in the log, but also in the actual data, in this case in the variable used with register.

If you run the playbook I provided it will create a secret in your keyvault using the current service principal secret and then try to retrieve that same secret. Instead of getting the actual secret it returns "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER" not just in log, but also as actual data.

Use case is the following: I have all my infrastructre and configuration as code. The software I use is checking that the service principal secret it's using is the same as in the key vault, if not it will update it's own service principal secret. Right now this does not work with azure_rm_keyvaultsecret_info because of this bug, workaround is using the lookup plugin.

Fred-sun commented 1 year ago

@Klaas- I understand your question and thank you for your feedback! But when we configure secret_value in the module, it is hidden, so it is not shown on the output or parameter configuration. If you want it to show, you can only configure it not to hide. I don't think this is good advice, because we can get it from the azure_keyvaultsecret_info module if we need to. Thanks!