Terraform: ¿Cómo guardar contraseñas de forma segura?

Article available only in Spanish

1. Introducción

Un problema común cuando se trabaja en la creación de algunos recursos con Terraform es la asignación de contraseñas, secretos o cualquier otro tipo de información sensible. Esta información no debería asignarse nunca en formato plano ni guardarse en los repositorios de código fuente.

Por ejemplo, a la hora de crear máquinas virtuales con el proveedor de Azure para Terraform (azurerm), tanto si sólo usamos código HCL como si usamos módulos de Terraform Registry, tendremos que asignar valores de usuario y contraseña de la cuenta de administrador para configurar la máquina virtual. Podríamos asignar estos valores directamente en el código de configuración pero sería un grave riesgo de seguridad. También podríamos asignar valores a estos atributos mediante variables de Terraform cuyo valor sería cargado automáticamente desde variables de entorno (convención basada en el formato de nombres de variables de entorno TF_VAR_nombre_variable) pero no sería una solución demasiado elegante, mantenible o escalable.

La solución propuesta en este artículo es el uso de Azure Key Vault como plataforma de almacenamiento de nuestras contraseñas, secretos o claves.

2. Azure Key Vault

Azure Key Vault es una plataforma en cloud que ayuda a solucionar fundamentalmente los siguientes problemas:

  • Administración de secretos
  • Administración de claves
  • Administración de certificados

Ofrece los siguientes beneficios para considerar su integración en nuestras aplicaciones:

  • Centralización de secretos de aplicación
  • Almacenamiento seguro de secretos y claves
  • Supervisión de acceso y uso de secretos y claves
  • Fácil integración con otros servicios de Azure
  • Fácil integración con Terraform

No merece extenderse más en este artículo ya que tienes toda la documentación disponible en la web de Microsoft Azure Key Vault.

En este punto, lo primero a realizar sería crear nuestro Azure Key Vault. Es realmente sencillo. A continuación te adjunto el enlace para crearlo usando el portal de Azure: Crear un Azure Key Vault desde el portal de Azure. En mi caso he creado un Key Vault llamado jm-inn-main-kv que es el que usaré en los ejemplos posteriores.

Las opciones de menú más destacadas que usaremos en nuestro artículo son Secrets y Access policies en la sección de Settings.

El menú Secrets nos permite generar o importar secretos consistentes en un nombre y un valor. Cada secreto puede ser configurado con una serie de propiedades adicionales pero caen fuera del alcance de este artículo. En mi caso he creado dos secretos llamados vm-password-default y vm-username-default que serán los nombres (keys) para acceder a los valores (values) de los secretos:

El menú Access policies nos permite configurar los permisos necesarios para que un usuario, grupo o service principal pueda realizar una serie de operaciones (Get, List, Set, Delete, Recover, BackupRestore) sobre claves, secretos o certificados. 

Es necesario añadir una Access policy (+ Add Access Policy) para asignar permisos al usuario o service principal sobre el que se ejecuta nuestra instancia de Terraform. En mi caso había añadido dos secretos por lo que sólo necesito añadir Secret Permissions sobre el service principal jm-inn-terraform-sp usado en mi instancia de Terraform como puede verse en la imagen posterior:

Si no sabes cómo crear un service principal puedes echar un vistazo al artículo Terraform: Estructura de Ficheros, Estado Remoto y Autenticación en Azure de este blog.

Las acciones disponibles para gestionar secretos (Secret Management) puedes verlas en la imagen posterior. En nuestro caso, sólo necesitamos leer los valores de secretos por lo que solamente la operación Get es requerida. Siguiendo la regla de mínima asignación de permisos viable tan sólo he seleccionado la operación Get:

Con estos sencillos pasos ya tendríamos configurado nuestro Azure Key Vault para almacenar secretos y nuestro service principal creado para autenticar la instancia de Terraform en Azure con los permisos necesarios.

3. Acceso a Azure Key Vault desde Terraform

Lo que más me gusta de esta solución es lo sencillo que resulta configurar Terraform para acceder a Azure Key Vault. Los pasos necesarios para lograr nuestro objetivo son los siguientes:

 

1. En los ficheros de configuración de Terraform añadir código HCL para crear un data source que referencie nuestro Azure Key Vault:

# Data source to reference Azure Key Vault holding secrets
data "azurerm_key_vault" "kv" {
  name                = "jm-inn-main-kv"
  resource_group_name = "jm-inn-core-rg"
}
 
2. En los ficheros de configuración de Terraform añadir código HCL para referenciar las entradas que guardan los valores de nuestros secretos. En el capítulo anterior habíamos visto que en Azure Key Vault habíamos creado dos entradas secretas con nombre vm-username-default y vm-password-default para almacenar valores de nombre de usuario y contraseña por defecto para ser asignadas a máquinas virtuales. Esta sería la forma de acceder desde Terraform:
 
# Data Source to get username secret from Azure Key Vault previously defined
data "azurerm_key_vault_secret" "vm_username" {
  name         = "vm-username-default"
  key_vault_id = data.azurerm_key_vault.kv.id
}

# Data Source to get password secret from Azure Key Vault previously defined
data "azurerm_key_vault_secret" "vm_password" {
  name         = "vm-password-default"
  key_vault_id = data.azurerm_key_vault.kv.id
}
 
3. Una vez creadas todas las data sources anteriores, tan sólo nos queda acceder a los valores de los secretos. Supongamos que estamos creando una máquina virtual Windows con el código HCL mostrado abajo. Observa las líneas en negrita en el código siguiente para asignar los atributos de admin_username y admin_password:
 
# Create Virtual Machine
resource "azurerm_windows_virtual_machine" "vm1" {
  name                = "tf-vm-1"
  resource_group_name = "jm-inn-tf-vms-rg"
  location            = "westeurope"
  size                = "Standard_B2s"
  admin_username      = data.azurerm_key_vault_secret.vm_username.value
  admin_password      = data.azurerm_key_vault_secret.vm_password.value
  network_interface_ids = [
    azurerm_network_interface.nic1.id,
  ]
  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }
  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-Datacenter"
    version   = "latest"
  }
}
 
Tan sólo es necesario asignar los atributos admin_username y admin_password accediendo a la propiedad value de los data source azurerm_key_vault_secret.vm_usernameazurerm_key_vault_secret.vm_password respectivamente.
 
Realmente resulta muy sencillo utilizar está solución. Por ello, recomiendo valorar su integración en nuestras aplicaciones desde el primer momento que tengamos la necesidad de almacenar de forma segura información sensible de claves, secretos o certificados.

4. Referencias

Add comment