Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

Tutorial: Use Azure Key Vault to store VM secrets with Ansible

In this quickstart, you'll create and retrieve secrets from Azure key vault with Ansible.

Important

Ansible 2.9 (or later) is required to run the sample playbooks in this article.

In this article, you learn how to:

  • Create an Azure key vault instance
  • Create a secret store in Azure key vault
  • Get secrets from Azure key vault with Ansible

Prerequisites

  • Azure subscription: If you don't have an Azure subscription, create a free account before you begin.
  • Azure service principal: Create a service principal, making note of the following values: appId, displayName, password, and tenant.

Create an Azure key vault

Ansible needs a resource group to deploy your resources in.

  1. Create an Ansible playbook named create_kv.yml add the following task to create a resource group:

    ---
    - name: Create Azure key vault
     hosts: localhost
     connection: local
     tasks:
    
     - name: Create resource group
     azure_rm_resourcegroup:
     name: ansible-kv-test-rg
     location: eastus
    
  2. Define the required variables for the tenant ID, service principal object ID, and vault name.

    ---
    vars:
     tenant_id: <tenantId>
     object_id: <servicePrincipalObjectId>
     vault_name: <vaultName>
    

    Replace <tenantId>, <servicePrincipalObjectId>, and <vaultName> with the appropriate values. The objectId is used to grant access to secrets within the key vault.

    key point:

    • Azure key vault names must be globally universally unique. The key vault and keys/secrets inside it are accessed via https://{vault-name}.vault.azure.net URI.
  3. Configure the Azure key vault instance by adding the create_kv.yml task.

    ---
    - name: Create key vault instance
     azure_rm_keyvault:
     resource_group: ansible-kv-test-rg
     vault_name: "{{ vault_name }}"
     enabled_for_deployment: yes
     vault_tenant: "{{ tenant_id }}"
     sku:
     name: standard
     access_policies:
     - tenant_id: "{{ tenant_id }}"
     object_id: "{{ object_id }}"
     secrets:
     - get
     - list
     - set
     - delete
    
  4. Run the create_kv.yml playbook.

    ansible-playbook create_kv.yml
    
    PLAY [localhost] *******************************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************************************
    ok: [localhost]
    
    TASK [Create resource group] *******************************************************************************************
    ok: [localhost]
    
    TASK [Create key vault instance] ************************************************************************************
    ok: [localhost]
    
    PLAY RECAP *************************************************************************************************************
    localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
    

Complete create Azure key vault playbook

This section lists the entire sample Ansible playbook for creating an Azure key vault.

- hosts: localhost
 connection: local

 vars:
 tenant_id: <tenantId>
 object_id: <servicePrincipalObjectId>
 vault_name: <vaultName>

 tasks:
 - name: Create resource group 
 azure_rm_resourcegroup:
 name: ansible-kv-test-rg
 location: eastus

 - name: Create instance of Key Vault
 azure_rm_keyvault:
 resource_group: ansible-kv-test-rg
 vault_name: "{{ vault_name }}"
 enabled_for_deployment: yes
 vault_tenant: "{{ tenant_id }}"
 sku:
 name: standard
 access_policies:
 - tenant_id: "{{ tenant_id }}"
 object_id: "{{ object_id }}"
 secrets:
 - get
 - list
 - set
 - delete

Create a secret in key vault

Before the secret can be created, you'll need the keyvault URI.

  1. Create another playbook named create_kv_secret.yml. Copy the following code into the playbook:

    ---
    - hosts: localhost
     connection: local
    
     tasks:
    
     - name: Get Key Vault by name
     azure_rm_keyvault_info:
     resource_group: ansible-kv-test-rg
     name: <vaultName>
     register: keyvault
    
     - name: set KeyVault uri fact
     set_fact: keyvaulturi="{{ keyvault['keyvaults'][0]['vault_uri'] }}"
    
     - name: Create a secret
     azure_rm_keyvaultsecret:
     secret_name: adminPassword
     secret_value: <secretValue>
     keyvault_uri: "{{ keyvaulturi }}"
    

    Replace <vaultName> with the name of your key vault name and <secretValue> with the value for the secret.

    Key point:

    • The azure_rm_keyvault_info and set_facts modules registers the key vault URI as a variable. That variable is then passed to the azure_rm_keyvaultsecret module to create the secret.
  2. Run the create_kv_secret.yml playbook.

    ansible-playbook create_kv_secret.yml
    
    PLAY [localhost] *******************************************************************************************************
    
    TASK [Gathering Facts] *************************************************************************************************
    ok: [localhost]
    
    TASK [Get Key Vault by name] *******************************************************************************************
    ok: [localhost]
    
    TASK [set KeyVault uri fact] *******************************************************************************************
    ok: [localhost]
    
    TASK [Create a secret] *************************************************************************************************
    ok: [localhost]
    
    PLAY RECAP *************************************************************************************************************
    localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
    

Get secrets from key vault

Secrets stored in Azure key vault can be used to populate Ansible variables.

  1. Create a new playbook called get_kv_secrets.yml to retrieve key vault secrets with Ansible.

    Ansible 2.9 with azure_preview_modules

    ---
    - hosts: localhost
     connection: local
     roles: 
     - { role: azure.azure_preview_modules }
    
     vars:
     tenant_id: <tenantId>
     vault_name: <vaultName>
     secret_name: adminPassword
     client_id: <servicePrincipalApplicationId>
     client_secret: <servicePrincipalSecret>
    
     tasks:
     - name: Get Key Vault by name
     azure_rm_keyvault_info:
     resource_group: ansible-kv-test-rg
     name: "{{ vault_name }}"
     register: keyvault
    
     - name: Set key vault URI fact
     set_fact: keyvaulturi="{{ keyvault['keyvaults'][0]['vault_uri'] }}"
    
     - name: Set key vault secret fact
     set_fact: secretValue={{ lookup('azure_keyvault_secret',secret_name,vault_url=keyvaulturi, client_id=client_id, secret=client_secret, tenant_id=tenant_id) }}
    
     - name: Output key vault secret
     debug:
     msg: "{{ secretValue }}"
    

    Replace <tenantId>, <vaultName>, <servicePrincipalApplicationId>, and <servicePrincipalSecret> with the appropriate values.

    To learn more about azure_preview_modules, see the Ansible Galaxy page.

    Ansible 2.10 with azure.azcollection

    ---
    - hosts: localhost
     connection: local
     collections:
     - azure.azcollection
    
     vars:
     vault_name: ansible-kv-test-01
     secret_name: adminPassword
    
     tasks:
    
     - name: Get Key Vault by name
     azure_rm_keyvault_info:
     resource_group: ansible-kv-test-rg
     name: "{{ vault_name }}"
     register: keyvault
    
     - name: Set key vault URI fact
     set_fact: keyvaulturi="{{ keyvault['keyvaults'][0]['vault_uri'] }}"
    
     - name: Get secret value
     azure_rm_keyvaultsecret_info:
     vault_uri: "{{ keyvaulturi }}"
     name: "{{ secret_name }}"
     register: kvSecret
    
     - name: set secret fact
     set_fact: secretValue="{{ kvSecret['secrets'][0]['secret'] }}"
    
     - name: Output key vault secret
     debug: 
     msg="{{ secretValue }}"
    

    Replace <vaultName> with the appropriate value.

    To learn more about azcollection, see Ansible collection for Azure.

  2. Run the get-secret-value.yml playbook.

    ansible-playbook get-secret-value.yml
    
    TASK [Output key vault secret] *************************************************
    ok: [localhost] => {
     "msg": "<plainTextPassword>"
    }
    

    Confirm the output that replaced <plainTextPassword> is the plain text value of the secret previously created in Azure key vault.

Complete sample Ansible playbook

This section lists the entire sample Ansible playbook for configuring an Azure Windows VM using a key vault secret.

---
- name: Create Azure VM
 hosts: localhost
 connection: local
 gather_facts: false
 collections:
 - azure.azcollection

 vars:
 vault_uri: <key_vault_uri>
 secret_name: <key_vault_secret_name>

 tasks:

 - name: Get latest version of a secret
 azure_rm_keyvaultsecret_info:
 vault_uri: "{{ vault_uri }}"
 name: "{{ secret_name }}"
 register: kvSecret

 - name: Set secret fact
 set_fact: secret_value="{{ kvSecret['secrets'][0]['secret'] }}"

 - name: Create resource group
 azure_rm_resourcegroup:
 name: myResourceGroup
 location: eastus

 - name: Create virtual network
 azure_rm_virtualnetwork:
 resource_group: myResourceGroup
 name: vNet
 address_prefixes: "10.0.0.0/16"

 - name: Add subnet
 azure_rm_subnet:
 resource_group: myResourceGroup
 name: subnet
 address_prefix: "10.0.1.0/24"
 virtual_network: vNet

 - name: Create public IP address
 azure_rm_publicipaddress:
 resource_group: myResourceGroup
 allocation_method: Static
 name: pip
 register: output_ip_address

 - name: Output public IP
 debug:
 msg: "The public IP is {{ output_ip_address.state.ip_address }}"
 
 - name: Create Network Security Group
 azure_rm_securitygroup:
 resource_group: myResourceGroup
 name: networkSecurityGroup
 rules:
 - name: 'allow_rdp'
 protocol: Tcp
 destination_port_range: 3389
 access: Allow
 priority: 1001
 direction: Inbound

 - name: Create a network interface
 azure_rm_networkinterface:
 name: nic
 resource_group: myResourceGroup
 virtual_network: vNet
 subnet_name: subnet
 security_group: networkSecurityGroup
 ip_configurations:
 - name: default
 public_ip_address_name: pip
 primary: True

 - name: Create VM
 azure_rm_virtualmachine:
 resource_group: myResourceGroup
 name: win-vm
 vm_size: Standard_DS1_v2
 admin_username: azureuser
 admin_password: "{{ secret_value }}"
 network_interfaces: nic
 os_type: Windows
 image:
 offer: WindowsServer
 publisher: MicrosoftWindowsServer
 sku: 2019-Datacenter
 version: latest
 no_log: true

Replace <key_vault_uri> and <key_vault_secret_name> with the appropriate values.

Clean up resources

  1. Save the following code as delete_rg.yml.

    ---
    - hosts: localhost
     tasks:
     - name: Deleting resource group - "{{ name }}"
     azure_rm_resourcegroup:
     name: "{{ name }}"
     state: absent
     register: rg
     - debug:
     var: rg
    
  2. Run the playbook using the ansible-playbook command. Replace the placeholder with the name of the resource group to be deleted. All resources within the resource group will be deleted.

    ansible-playbook delete_rg.yml --extra-vars "name=<resource_group>"
    

    Key points:

    • Because of the register variable and debug section of the playbook, the results display when the command finishes.

Next steps


Feedback

Was this page helpful?

Additional resources