tutoriales.com

Gestionando Configuración de Aplicaciones y Secrets con Terraform y AWS Parameter Store

Este tutorial te guiará paso a paso en cómo utilizar Terraform para aprovisionar y gestionar parámetros y secretos de aplicaciones en AWS Systems Manager Parameter Store. Descubre cómo mantener tu configuración organizada, segura y accesible para tus servicios en la nube.

Intermedio20 min de lectura15 views
Reportar error

🚀 Introducción a AWS Parameter Store y Terraform

En el mundo de la infraestructura como código (IaC), la gestión de la configuración y los secretos de las aplicaciones es un desafío común. Los valores codificados directamente en el código fuente o en los archivos de configuración de la infraestructura presentan riesgos de seguridad y dificultades de mantenimiento. Aquí es donde entra en juego AWS Systems Manager Parameter Store, un servicio que ofrece una forma segura y escalable de almacenar y gestionar datos de configuración y secretos.

¿Qué es AWS Systems Manager Parameter Store? 🤔

AWS Systems Manager Parameter Store es un almacén centralizado para tus datos de configuración, desde cadenas de texto simples hasta secretos sensibles como contraseñas de bases de datos o claves API. Ofrece varias ventajas clave:

  • Seguridad: Puedes almacenar parámetros como texto plano o como SecureString, que utiliza AWS Key Management Service (KMS) para cifrar los datos en reposo y en tránsito.
  • Centralización: Un único lugar para todas tus configuraciones, accesible por diferentes servicios y aplicaciones de AWS.
  • Control de Versiones: Mantiene un historial de todas las modificaciones a tus parámetros, permitiendo auditorías y reversiones.
  • Integración: Se integra fácilmente con otros servicios de AWS como Lambda, EC2, ECS, etc.

¿Por qué usar Terraform con Parameter Store? 🛠️

Combinar Terraform con AWS Parameter Store te permite gestionar programáticamente la creación, actualización y eliminación de tus parámetros. Esto significa que la configuración de tu aplicación y los secretos pueden ser una parte integral de tu infraestructura como código, beneficiándose de las mismas prácticas de control de versiones, revisión de código y despliegue automatizado.

💡 Consejo: Considera Parameter Store para configuraciones no sensibles y secretos que no requieren una rotación automática frecuente. Para secretos con alta rotación o integración avanzada, AWS Secrets Manager podría ser una alternativa mejor, aunque Parameter Store puede cubrir muchas necesidades básicas y avanzadas.

🎯 Requisitos Previos

Antes de sumergirnos en el código, asegúrate de tener lo siguiente configurado:

  • AWS CLI: Configurado con credenciales que tengan permisos para crear y gestionar parámetros en AWS Systems Manager (SSM) y, si usarás SecureString, para KMS.
  • Terraform: Instalado y configurado en tu máquina local. Puedes descargar la última versión desde el sitio web oficial de HashiCorp.
  • Un editor de texto o IDE: Como VS Code, para escribir tu código Terraform.
📌 Nota: Para este tutorial, asumiremos que ya tienes una configuración básica de AWS CLI. Si no, puedes consultar la documentación oficial de AWS para configurarla.

📝 Primeros Pasos: Configurando tu Proyecto Terraform

Comenzaremos configurando la estructura básica de nuestro proyecto Terraform.

Estructura de Directorios

Crea un nuevo directorio para tu proyecto y dentro de él, crea los siguientes archivos:

├── main.tf
├── variables.tf
├── outputs.tf
└── providers.tf

Configuración del Proveedor AWS (providers.tf)

En providers.tf, define el proveedor AWS y la región en la que deseas trabajar.

# providers.tf
provider "aws" {
  region = "us-east-1" # Cambia a tu región preferida
}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  required_version = ">= 1.0.0"
}
🔥 Importante: Siempre especifica las versiones del proveedor y de Terraform para garantizar la consistencia en tus despliegues.

🔑 Gestionando Parámetros No Sensibles con aws_ssm_parameter

Empecemos con un ejemplo sencillo: almacenar una cadena de texto simple, como el nombre de una aplicación o un nivel de logging.

Definiendo Variables (variables.tf)

En variables.tf, definiremos las variables para nuestro parámetro.

# variables.tf
variable "app_name" {
  description = "El nombre de la aplicación."
  type        = string
  default     = "MiAplicacionDemo"
}

variable "log_level" {
  description = "El nivel de logging para la aplicación."
  type        = string
  default     = "INFO"
}

Creando Parámetros en main.tf

Ahora, en main.tf, definiremos el recurso aws_ssm_parameter para crear estos parámetros.

# main.tf
resource "aws_ssm_parameter" "app_name_param" {
  name        = "/config/${var.app_name}/name"
  type        = "String"
  value       = var.app_name
  description = "Nombre de la aplicación demo"
  tags = {
    Project     = "ParameterStoreDemo"
    Environment = "Development"
  }
}

resource "aws_ssm_parameter" "log_level_param" {
  name        = "/config/${var.app_name}/log_level"
  type        = "String"
  value       = var.log_level
  description = "Nivel de logging para la aplicación demo"
  tags = {
    Project     = "ParameterStoreDemo"
    Environment = "Development"
  }
}
💡 Consejo: Utiliza una convención de nomenclatura jerárquica para tus parámetros (por ejemplo, `/aplicacion/entorno/configuracion`). Esto facilita la organización y el filtrado.

Definiendo Salidas (outputs.tf)

Para poder ver los valores de los parámetros que hemos creado, definiremos salidas en outputs.tf.

# outputs.tf
output "app_name_parameter_arn" {
  description = "El ARN del parámetro del nombre de la aplicación."
  value       = aws_ssm_parameter.app_name_param.arn
}

output "log_level_parameter_arn" {
  description = "El ARN del parámetro del nivel de logging."
  value       = aws_ssm_parameter.log_level_param.arn
}

Despliegue Inicial 🚀

Ejecuta los siguientes comandos en tu terminal desde el directorio raíz de tu proyecto Terraform:

  1. Inicializar Terraform:
terraform init
  1. Planificar el despliegue:
terraform plan
Revisa el plan para asegurarte de que se crearán los recursos esperados.

3. Aplicar el despliegue:

terraform apply
Escribe `yes` cuando se te solicite.

Una vez aplicado, podrás ver los parámetros en la consola de AWS Systems Manager, bajo "Parameter Store".


🔒 Gestionando Secretos con SecureString y KMS

Para datos sensibles, como contraseñas o claves API, debemos usar el tipo SecureString. Esto requiere una clave de AWS Key Management Service (KMS) para el cifrado.

Creando una Clave KMS (main.tf) 🔑

Primero, definiremos un recurso aws_kms_key en main.tf.

# main.tf (añadir a continuación de los parámetros anteriores)

resource "aws_kms_key" "app_secrets_key" {
  description             = "Clave KMS para cifrar secretos de la aplicación"
  deletion_window_in_days = 10
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "Enable IAM User Permissions"
        Effect    = "Allow"
        Principal = {
          AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
        }
        Action    = "kms:*"
        Resource  = "*"
      },
      {
        Sid       = "Allow SSM to use this key"
        Effect    = "Allow"
        Principal = {
          Service = "ssm.amazonaws.com"
        }
        Action = [
          "kms:Decrypt",
          "kms:GenerateDataKey"
        ]
        Resource = "*"
      }
    ]
  })
  tags = {
    Project     = "ParameterStoreDemo"
    Environment = "Development"
  }
}

data "aws_caller_identity" "current" {}
⚠️ Advertencia: La política de KMS es crucial. Asegúrate de que los principios correctos (por ejemplo, `ssm.amazonaws.com` y los roles de IAM de tus aplicaciones) tengan los permisos `kms:Decrypt` y `kms:GenerateDataKey` para usar la clave.

Definiendo Variables para el Secreto (variables.tf)

En variables.tf, añade una variable para tu secreto. Usaremos no_echo = true para que el valor no se muestre en la salida de Terraform si se solicita interactivamente.

# variables.tf (añadir a continuación de las variables anteriores)

variable "db_password" {
  description = "La contraseña de la base de datos (secreto)."
  type        = string
  sensitive   = true # Marca esta variable como sensible
}
🔥 Importante: Para pasar valores sensibles como la contraseña de la base de datos, NO los codifiques directamente en `terraform.tfvars`. Usa variables de entorno (`TF_VAR_db_password=miSuperSecreto`) o prompts interactivos. La opción `sensitive = true` es vital para evitar que el valor aparezca en los logs o en la salida de `terraform plan` o `apply`.

Creando el Parámetro SecureString (main.tf)

Ahora, definiremos el recurso para el secreto en main.tf.

# main.tf (añadir a continuación de la clave KMS)

resource "aws_ssm_parameter" "db_password_secret" {
  name        = "/secrets/${var.app_name}/db_password"
  type        = "SecureString"
  value       = var.db_password
  key_id      = aws_kms_key.app_secrets_key.arn # Referencia al ARN de nuestra clave KMS
  description = "Contraseña de la base de datos para la aplicación demo"
  tags = {
    Project     = "ParameterStoreDemo"
    Environment = "Development"
  }
}

Actualizando Salidas (outputs.tf)

# outputs.tf (añadir a continuación de las salidas anteriores)

output "kms_key_arn" {
  description = "El ARN de la clave KMS utilizada para cifrar secretos."
  value       = aws_kms_key.app_secrets_key.arn
}

output "db_password_parameter_arn" {
  description = "El ARN del parámetro de la contraseña de la base de datos."
  value       = aws_ssm_parameter.db_password_secret.arn
}

Despliegue del Secreto 🔐

  1. Planificar el despliegue (pasando el secreto):
terraform plan -var='db_password=TuSuperSecretoSeguro123!'
Sustituye `TuSuperSecretoSeguro123!` por tu contraseña real. En un entorno real, usarías un sistema de CI/CD para inyectar este valor de forma segura.

2. Aplicar el despliegue:

terraform apply -var='db_password=TuSuperSecretoSeguro123!'
Escribe `yes` cuando se te solicite.

Una vez aplicado, verás el parámetro /secrets/MiAplicacionDemo/db_password en Parameter Store, marcado como SecureString y cifrado por tu clave KMS.

💡 Consejo: Para evitar pasar secretos directamente en la línea de comandos (que podría quedar en el historial de comandos), puedes usar un archivo `terraform.tfvars` (pero NO lo subas a control de versiones para secretos) o, mejor aún, variables de entorno como `TF_VAR_db_password`.

🔄 Actualizando y Eliminando Parámetros

La belleza de Terraform es que gestionar los cambios es tan sencillo como modificar tu código.

Actualizando un Parámetro

Si decides cambiar el log_level de INFO a DEBUG, simplemente modifica variables.tf (o el valor en main.tf si no usaste variables).

# variables.tf
variable "log_level" {
  description = "El nivel de logging para la aplicación."
  type        = string
  default     = "DEBUG" # ¡Cambiado a DEBUG!
}

Ejecuta terraform plan y terraform apply de nuevo. Terraform detectará la diferencia y actualizará el valor del parámetro en Parameter Store sin eliminarlo y recrearlo.

Eliminando un Parámetro

Para eliminar un parámetro, simplemente elimina su bloque resource "aws_ssm_parameter" de main.tf.

Por ejemplo, si eliminas el recurso aws_ssm_parameter.log_level_param:

  1. Borra el bloque del recurso: Elimina el bloque resource "aws_ssm_parameter" "log_level_param" { ... } de main.tf.
  2. Planifica y aplica:
terraform plan
terraform apply
Terraform te mostrará que el recurso será destruido. Confirma con `yes`.
⚠️ Advertencia: Ten mucho cuidado al eliminar recursos. Siempre revisa el `terraform plan` antes de aplicar para evitar destrucciones accidentales.

🤝 Consumiendo Parámetros desde tus Aplicaciones

Una vez que tus parámetros están en Parameter Store, tus aplicaciones necesitan una forma de acceder a ellos. Aquí hay un breve resumen de cómo se haría esto, dependiendo del entorno:

🌐 Consola de AWS o AWS CLI

Puedes recuperar parámetros manualmente para depuración o tareas administrativas:

aws ssm get-parameter --name "/config/MiAplicacionDemo/name"
aws ssm get-parameter --name "/secrets/MiAplicacionDemo/db_password" --with-decryption

💻 SDKs de AWS para Aplicaciones

La forma más común es usar los SDKs de AWS en tu código. Aquí un ejemplo conceptual en Python:

import boto3

ssm = boto3.client('ssm', region_name='us-east-1')

def get_parameter(name, decrypt=False):
    response = ssm.get_parameter(
        Name=name,
        WithDecryption=decrypt
    )
    return response['Parameter']['Value']

app_name = get_parameter("/config/MiAplicacionDemo/name")
db_password = get_parameter("/secrets/MiAplicacionDemo/db_password", decrypt=True)

print(f"App Name: {app_name}")
print(f"DB Password: {db_password}") # ¡No imprimas secretos en producción!

📦 Integración con Otros Servicios de AWS

Servicios como AWS Lambda, ECS, EKS o EC2 pueden integrarse directamente con Parameter Store. Por ejemplo, en una definición de tarea de ECS, puedes referenciar parámetros para pasarlos como variables de entorno:

{
  "containerDefinitions": [
    {
      "name": "my-app-container",
      "image": "my-repo/my-app:latest",
      "environment": [
        {
          "name": "APP_NAME",
          "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/config/MiAplicacionDemo/name"
        },
        {
          "name": "DB_PASSWORD",
          "valueFrom": "arn:aws:ssm:us-east-1:123456789012:parameter/secrets/MiAplicacionDemo/db_password"
        }
      ]
    }
  ]
}
🔥 Importante: Para que tus aplicaciones o servicios de AWS puedan leer parámetros (especialmente `SecureString`), el rol de IAM asociado a ellos DEBE tener permisos para `ssm:GetParameter`, `ssm:GetParameters`, `ssm:GetParametersByPath` y, para `SecureString`, también `kms:Decrypt` sobre la clave KMS utilizada.

📊 Comparativa: Parameter Store vs. Secrets Manager

Es importante entender cuándo usar Parameter Store y cuándo considerar AWS Secrets Manager.

CaracterísticaAWS Systems Manager Parameter StoreAWS Secrets Manager
---------
CosteGratuito hasta 10,000 parámetros estándar. Precios por tipo Advanced y SecureString más altos.Se cobra por secreto almacenado y por llamadas a la API.
Rotación AutomáticaNo incorporado, requiere configuración manual o con Lambda.Integrado para bases de datos (RDS, Redshift) y otras credenciales.
---------
Granularidad de AccesoBasado en IAM, rutas de parámetros.Basado en IAM, por secreto.
IntegracionesAmplia con SSM, EC2, Lambda, ECS.Amplia con RDS, Lambda, otras API.
---------
Uso PrincipalDatos de configuración generales, flags, cadenas no sensibles.Credenciales de bases de datos, claves API, tokens OAuth.
Tipo de CifradoKMS (opcional para String, obligatorio para SecureString).KMS (obligatorio).
📌 Nota: Parameter Store es una excelente opción para la mayoría de las configuraciones de aplicaciones, incluyendo algunos secretos. Secrets Manager brilla cuando necesitas rotación automática de secretos, lo cual es crítico para una seguridad de alto nivel en credenciales de bases de datos.

🗑️ Limpieza de Recursos

Una vez que hayas terminado de experimentar, es una buena práctica destruir los recursos de AWS para evitar costes innecesarios.

  1. Destruir recursos:
terraform destroy -var='db_password=TuSuperSecretoSeguro123!' # Si el secreto aún existe
Si ya has eliminado el parámetro del secreto en un paso anterior, no necesitarás el `-var`.

2. Confirma la destrucción: Escribe yes cuando se te solicite.

Esto eliminará todos los parámetros SSM y la clave KMS que Terraform creó en este tutorial.


💡 Consideraciones Adicionales y Buenas Prácticas

  • Políticas de IAM: Siempre aplica el principio de mínimo privilegio. Otorga a tus servicios y usuarios solo los permisos necesarios para acceder a los parámetros específicos. Usa condiciones de IAM para restringir el acceso por ruta de parámetro.
  • Control de Versiones: Aprovecha el control de versiones de Parameter Store (aunque Terraform gestionará la última versión). Puedes usar la consola o la CLI para ver el historial.
  • Tipos de Parámetro: Además de String y SecureString, Parameter Store también soporta StringList para almacenar listas de cadenas separadas por comas.
  • Jerarquía de Nombres: Mantén una jerarquía de nombres clara y consistente (ej. /app-name/env/setting-name). Esto es fundamental para la organización a medida que crece el número de parámetros.
  • Integración CI/CD: Integra la gestión de tus parámetros Terraform en tu pipeline de CI/CD para automatizar los despliegues y asegurar que los secretos y configuraciones se manejen de forma segura.
Usuario / CI/CD Terraform Gestionar (CRUD) AWS Parameter Store (SecureString con KMS) Leer Configuración / Secretos Aplicación (Lambda / EC2 / ECS)

✅ Conclusión

AWS Systems Manager Parameter Store, cuando se combina con Terraform, ofrece una solución robusta y escalable para la gestión centralizada de la configuración de aplicaciones y secretos. Al integrar esta gestión en tu flujo de trabajo de infraestructura como código, mejoras la seguridad, la auditabilidad y la eficiencia de tus despliegues. Has aprendido a crear parámetros de tipo String y SecureString, a gestionarlos y a entender cómo tus aplicaciones pueden consumirlos, sentando una base sólida para arquitecturas en la nube bien organizadas y seguras.

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!