Tutorial: Uso de Azure Key Vault para almacenar secretos de máquinas virtuales con Ansible

En este inicio rápido, creará y recuperará secretos de Azure Key Vault con Ansible.

Importante

Para ejecutar los cuadernos de estrategias de ejemplo de este tutorial, se requiere Ansible 2.9 (o versiones posteriores).

En este artículo aprenderá a:

  • Creación de una instancia de Azure Key Vault
  • Creación de un almacén de secretos en Azure Key Vault
  • Obtención de secretos de Azure Key Vault con Ansible

Requisitos previos

  • Suscripción de Azure: si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.

Creación de una instancia de Azure Key Vault

Ansible necesita un grupo de recursos en el que implementar los recursos.

  1. Cree un cuaderno de estrategias de Ansible denominado create_kv.yml y agregue la siguiente tarea para crear un grupo de recursos:

    ---
    - 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. Defina las variables necesarias para el identificador de inquilino, el identificador de objeto de la entidad de servicio y el nombre del almacén.

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

    Reemplace <tenantId>, <servicePrincipalObjectId> y <vaultName> por los valores adecuados. objectId se utiliza para conceder acceso a los secretos dentro del almacén de claves.

    Punto clave:

    • Los nombres del almacén de claves de Azure deben ser únicos de forma universal. Se tiene acceso al almacén de claves y a las claves o secretos dentro de él a través del URI https://{vault-name}.vault.azure.net.
  3. Agregue la tarea create_kv.yml para configurar la instancia de Azure Key Vault.

    ---
    - 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. Ejecute el cuaderno de estrategias create_kv.yml.

    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
    

Completar el cuaderno de estrategias de creación de Azure Key Vault

En esta sección se muestra todo el cuaderno de estrategias de Ansible de ejemplo para crear un almacén de claves de Azure.

- 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

Creación de un secreto en un almacén de claves

Antes de poder crear el secreto, necesitará el URI del almacén de claves.

  1. Cree otro cuaderno de estrategias denominado create_kv_secret.yml. Copie el código siguiente en el cuaderno de estrategias:

    ---
    - 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 }}"
    

    Reemplace <vaultName> por el nombre del almacén de claves y <secretValue> por el valor del secreto.

    Punto clave:

    • Los módulos azure_rm_keyvault_info y set_facts registran el URI del almacén de claves como una variable. Después, esa variable se pasa al módulo azure_rm_keyvaultsecret para crear el secreto.
  2. Ejecute el cuaderno de estrategias create_kv_secret.yml.

    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
    

Recuperación de secretos del almacén de claves

Los secretos almacenados en Azure Key Vault se pueden utilizar para rellenar variables de Ansible.

  1. Cree un nuevo cuaderno de estrategias llamado get_kv_secrets.yml para recuperar los secretos del almacén de claves con Ansible.

    Ansible 2.9 con 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 }}"
    

    Reemplace <tenantId>, <vaultName>, <servicePrincipalApplicationId> y <servicePrincipalSecret> por los valores adecuados.

    Para más información sobre azure_preview_modules, consulte la página Ansible Galaxy.

    Ansible 2.10 con 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 }}"
    

    Reemplace <vaultName> por el valor adecuado.

    Para más información sobre azcollection, consulte Ansible collection for Azure (Colección de Ansible para Azure).

  2. Ejecute el cuaderno de estrategias get-secret-value.yml.

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

    Confirme que la salida <plainTextPassword> reemplazada sea el valor de texto sin formato del secreto creado anteriormente en Azure Key Vault.

Cuaderno de Ansible de ejemplo completo

En esta sección se muestra todo el cuaderno de estrategias de Ansible de ejemplo para configurar una máquina virtual de Azure Windows mediante un secreto del almacén de claves.

---
- 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

Reemplace <key_vault_uri> y <key_vault_secret_name> por los valores adecuados.

Limpieza de recursos

  1. Guarde el código siguiente como delete_rg.yml.

    ---
    - hosts: localhost
      tasks:
        - name: Deleting resource group - "{{ name }}"
          azure_rm_resourcegroup:
            name: "{{ name }}"
            state: absent
          register: rg
        - debug:
            var: rg
    
  2. Ejecute el cuaderno de estrategias mediante el comando ansible-playbook. Reemplace el marcador de posición por el nombre del grupo de recursos que se va a eliminar. Se eliminarán todos los recursos del grupo de recursos.

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

    Puntos clave:

    • Debido a la variable register y a la sección debug del cuaderno de estrategias, los resultados se muestran cuando finaliza el comando.

Pasos siguientes