>Read Azure Key Vault secrets

Read Azure Key Vault secrets from a playbook

Read a secret during an Ansible job, verify it without printing its value, and make it available to later tasks. This example runs on the runner with hosts: localhost; your managed hosts do not need Azure credentials for the lookup.

Before you begin

You need an existing vault, an enabled secret and an Azure identity allowed to read it. The runner must reach the vault and Azure sign-in endpoints, including any private-endpoint DNS and network configuration your vault requires. Its execution environment needs azure.azcollection and the collection's Python dependencies.

Maintain thisIn this place
Secret retrieval and useYour repository's Ansible playbook YAML.
Collection versionYour repository's requirements.yml; Python dependencies belong in the runner image.
Stackweaver's organization identityThe UI or the Terraform/OpenTofu provider example below.
Azure trust and vault accessYour Azure identity and role configuration. Saving an identity in Stackweaver does not grant vault access.

The Galaxy collections guide explains repository dependency installation and runner image requirements.

1. Choose the runner's Azure identity

Stackweaver supplies credentials to the playbook's environment. An attached Azure credential takes precedence over organization federation; the runner's AKS identity is another option when neither supplies the job identity.

MethodConfigure this
Attached service principalAttach an Azure credential to the job template. Use the identity's vault permissions, not the permissions of the person launching the job.
Organization federationSave the organization's Azure application identifiers and configure the application's trust for Stackweaver's issuer, audience and job subject. Both platform and self-hosted runners receive a job token.
AKS Entra Workload IDConfigure the runner pod's workload identity and projected token. The playbook uses that pod identity, not a Stackweaver job federation subject.

If you already have a working attached credential or AKS identity, continue to grant vault access. Otherwise, configure organization federation through one of the following paths.

Configure organization federation in the UI

You need organization permission to manage OIDC settings. Open your organization's Settings > OIDC Configurations, choose Add OIDC, and select Azure OIDC. Enter the application's Client ID, Azure Subscription ID and Tenant ID, then choose Create. Confirm the saved Azure entry has the intended identifiers.

Azure OIDC form with the Client ID, Subscription ID and Tenant ID fields

Example Azure identifiers. Use your own application's values.

Configure the same identity with Terraform or OpenTofu

With the Stackweaver provider configured, add this resource to oidc.tf. Replace example-platform and the three example Azure identifiers. Use the existing identity configuration if one is already managed; do not create a second copy in the UI and your provider configuration.

resource "stackweaver_azure_oidc_configuration" "ansible" {
  organization    = "example-platform"
  client_id       = "11111111-1111-4111-8111-111111111111"
  subscription_id = "22222222-2222-4222-8222-222222222222"
  tenant_id       = "33333333-3333-4333-8333-333333333333"
}

Review the plan, apply it, and confirm the saved configuration has those identifiers. This resource configures Stackweaver's side of federation. It does not create the Azure application, its federated credential or its Key Vault role assignment.

For API integrations

Use the provider for maintained configuration. For an API integration, send a POST request to the path below, replacing <org> with your organization name. Authenticate with a Stackweaver API token allowed to manage its OIDC settings; see Using the API.

/api/v2/organizations/<org>/oidc-configurations

Use this body, replacing the Azure identifiers:

json
{
  "data": {
    "type": "azure-oidc-configurations",
    "attributes": {
      "client-id": "11111111-1111-4111-8111-111111111111",
      "subscription-id": "22222222-2222-4222-8222-222222222222",
      "tenant-id": "33333333-3333-4333-8333-333333333333"
    }
  }
}

A successful create returns HTTP 201 with the saved resource in data. Check its ID and attributes. This configures the same organization identity; it is not an API for retrieving vault secrets. Use the API explorer for operation schemas.

Complete the Azure trust

The application's federated credential must trust your Stackweaver issuer and audience api://AzureADTokenExchange. The subject has this format:

organization:<org>:project:<project>:job:<job-name>:run

Match the organization, project and job names in the job's token. This is the job subject, not an OpenTofu workspace or inventory-source subject. Follow OIDC configuration for issuer and Azure trust setup. Stackweaver supplies the token environment; do not paste token values into YAML.

2. Allow that identity to read the secret

On a vault using Azure RBAC, grant the chosen identity Key Vault Secrets User at the appropriate scope. A management-plane role such as Key Vault Contributor does not let it read secret values. For an access-policy vault, allow secret get for this named-secret example; listing secrets also needs list. See Azure's Key Vault access guide.

3. Declare the collection

If the repository installs its collection dependencies, add this to requirements.yml:

collections:
  - name: azure.azcollection
    version: ">=3.17.0"

OIDC token and token-file support require azure.azcollection 3.17.0 or later. Use a reviewed version compatible with your runner image's Python dependencies; installing the collection does not install those dependencies. The module authentication reference lists the supported environment variables. Collection dependencies belong in the repository, not a collection list on the job template.

4. Read and verify the secret

Save this as playbooks/read-key-vault.yml in your repository. Register the playbook and select it on a job template using the identity above. Replace the vault URI and secret name with your own.

- name: Read a Key Vault secret
  hosts: localhost
  connection: local
  gather_facts: false
  tasks:
    - name: Retrieve the database password
      azure.azcollection.azure_rm_keyvaultsecret_info:
        auth_source: env
        vault_uri: "https://my-vault.vault.azure.net"
        name: database-password
        version: current
      register: kv
      no_log: true

    - name: Confirm a non-empty secret was returned
      ansible.builtin.assert:
        that:
          - kv.secrets | length > 0
          - kv.secrets[0].secret is defined
          - kv.secrets[0].secret | length > 0
      no_log: true

    - name: Make the password available to later tasks
      ansible.builtin.set_fact:
        db_password: "{{ kv.secrets[0].secret }}"
      no_log: true

auth_source: env uses the runner's supplied identity environment instead of falling back to a local Azure CLI login or credentials file. version: current reads the current secret version; choose a specific version if the play must use a fixed value.

Launch the job. The three tasks should succeed, with their results hidden by no_log. The assertion confirms a non-empty value without displaying it. Use db_password in a later task in this play and keep no_log: true on tasks that read or use the secret. Do not print kv or db_password to check authentication. A secret read by this play is not automatically stored as a Stackweaver credential.

If the lookup fails

SymptomCheck
Module not found or a Python import errorCheck the installed collection and its Python dependencies in the runner's execution environment.
Authentication failsCheck the effective identity and collection version. For federation, compare issuer, audience and job subject with the Azure trust. For AKS, check the pod identity and projected token.
Access deniedCheck the effective identity's secret data-plane permission, secret enabled state and vault firewall rules. A management role alone is insufficient.
Connection timeout or DNS failureCheck connectivity and private-endpoint DNS from the runner, where the module executes.
The assertion failsCheck the vault URI, secret name and whether the current version contains a non-empty value. Keep secret output hidden while investigating.

Timeouts and long plays

Stackweaver's job federation token expires one hour after it is issued. Read secrets early; increasing the job timeout does not extend that token's lifetime. Do not assume a later lookup in a long-running play will receive a renewed job token. AKS pod identity follows its own token lifecycle.