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.
🚀 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.
🎯 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.
📝 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"
}
🔑 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"
}
}
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:
- Inicializar Terraform:
terraform init
- 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" {}
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
}
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 🔐
- 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.
🔄 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:
- Borra el bloque del recurso: Elimina el bloque
resource "aws_ssm_parameter" "log_level_param" { ... }demain.tf. - Planifica y aplica:
terraform plan
terraform apply
Terraform te mostrará que el recurso será destruido. Confirma con `yes`.
🤝 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"
}
]
}
]
}
📊 Comparativa: Parameter Store vs. Secrets Manager
Es importante entender cuándo usar Parameter Store y cuándo considerar AWS Secrets Manager.
| Característica | AWS Systems Manager Parameter Store | AWS Secrets Manager |
|---|---|---|
| --- | --- | --- |
| Coste | Gratuito 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ática | No incorporado, requiere configuración manual o con Lambda. | Integrado para bases de datos (RDS, Redshift) y otras credenciales. |
| --- | --- | --- |
| Granularidad de Acceso | Basado en IAM, rutas de parámetros. | Basado en IAM, por secreto. |
| Integraciones | Amplia con SSM, EC2, Lambda, ECS. | Amplia con RDS, Lambda, otras API. |
| --- | --- | --- |
| Uso Principal | Datos de configuración generales, flags, cadenas no sensibles. | Credenciales de bases de datos, claves API, tokens OAuth. |
| Tipo de Cifrado | KMS (opcional para String, obligatorio para SecureString). | KMS (obligatorio). |
🗑️ Limpieza de Recursos
Una vez que hayas terminado de experimentar, es una buena práctica destruir los recursos de AWS para evitar costes innecesarios.
- 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
StringySecureString, Parameter Store también soportaStringListpara 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.
✅ 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
- Aprovisionando y Gestionando Redes de Contenido (CDN) con Terraform y AWS CloudFrontintermediate25 min
- Migrando Infraestructura Existente a Terraform: Guía Completa de Importaciónintermediate18 min
- Automatización de la Configuración de Kubernetes con Terraform: Un Enfoque Declarativointermediate15 min
- Gestionando Secretos Sensibles en Terraform con HashiCorp Vault: Un Enfoque Segurointermediate25 min
- Gestionando Estado Remoto con Terraform: S3 y DynamoDB para Colaboración y Resilienciaintermediate20 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!