Variables de Entorno en Lambda: Configuración y Cifrado con KMS

Hardcodear un endpoint de base de datos dentro del código de una función Lambda es uno de esos errores que parecen inofensivos hasta que necesitas rotar credenciales en producción a las 2 AM. Las variables de entorno de Lambda resuelven exactamente este problema: separan la configuración del código, y cuando se combinan con AWS KMS, también protegen valores sensibles en reposo.

TL;DR: Variables de Entorno en Lambda

Aspecto Detalle
¿Dónde se definen? En la configuración de la función Lambda, sección 'Environment variables'
¿Cómo se leen en código? A través de las variables de entorno del proceso (por ejemplo, os.environ en Python)
Cifrado por defecto Lambda cifra las variables en reposo usando una clave KMS gestionada por AWS
Cifrado con CMK propio Puedes especificar tu propia Customer Managed Key (CMK) de KMS
Cifrado en tránsito Lambda cifra las variables durante el despliegue usando TLS
Tamaño máximo total 4 KB para todas las variables de entorno combinadas

Cómo Funcionan las Variables de Entorno en Lambda

Cuando defines variables de entorno en una función Lambda, AWS las almacena cifradas junto con la configuración de la función. En el momento del arranque del entorno de ejecución, Lambda inyecta esas variables en el proceso antes de que tu código de inicialización se ejecute. Esto significa que el valor de DB_ENDPOINT ya está disponible cuando el módulo se carga por primera vez, no solo cuando el handler es invocado.

El cifrado en reposo es automático. Por defecto, Lambda usa una clave KMS gestionada por AWS (aws/lambda). Si necesitas control de auditoría sobre quién usa la clave, rotación personalizada, o separación de permisos entre equipos, sustituyes esa clave por una CMK propia. El comportamiento funcional es idéntico — la diferencia está en quién controla el material criptográfico.

graph TD A["Definición Variables en consola/CLI"] --> B["Lambda cifra valores usando KMS"] B --> C["Almacenamiento cifrado en configuración de función"] C --> D["Arranque del entorno de ejecución"] D --> E["Lambda llama a KMS para descifrar"] E --> F["Valores inyectados como env vars del proceso"] F --> G["Tu código lee os.environ / process.env"] style A fill:#f0f4ff,stroke:#4a6cf7 style G fill:#f0fff4,stroke:#38a169
  1. Definición: Las variables se configuran en la función Lambda junto con la referencia a la CMK de KMS.
  2. Almacenamiento: Lambda cifra los valores usando KMS antes de persistirlos en su plano de control.
  3. Arranque del entorno: Al inicializar una instancia de ejecución, Lambda descifra las variables e inyecta los valores en el proceso.
  4. Acceso en código: Tu función lee los valores ya descifrados desde las variables de entorno del proceso — sin llamadas adicionales a KMS en tiempo de ejecución.
Piensa en las variables de entorno de Lambda como un sobre sellado que se abre justo antes de que tu función empiece a trabajar. El sobre viaja cifrado; el contenido llega limpio al proceso.

Paso 1: Definir Variables de Entorno con la AWS CLI

La forma más directa de configurar variables de entorno es mediante update-function-configuration. Este comando reemplaza el bloque completo de variables de entorno, así que siempre incluye todos los pares clave-valor que necesitas mantener, no solo los nuevos.

aws lambda update-function-configuration \
  --function-name mi-funcion \
  --environment 'Variables={DB_ENDPOINT=mydb.cluster-xyz.us-east-1.rds.amazonaws.com,DB_PORT=5432,APP_ENV=production}' \
  --region us-east-1

Para verificar que las variables quedaron registradas correctamente:

aws lambda get-function-configuration \
  --function-name mi-funcion \
  --region us-east-1 \
  --query 'Environment'

La respuesta mostrará las claves pero los valores aparecerán tal como los definiste — Lambda no enmascara los valores en la API de configuración. Esto es relevante para decidir qué va como variable de entorno simple y qué debería pasar por Secrets Manager.

Paso 2: Leer Variables de Entorno en el Código de la Función

El acceso es estándar para cada runtime — Lambda simplemente expone los valores como variables de entorno del proceso del sistema operativo.

Python:

import os

DB_ENDPOINT = os.environ['DB_ENDPOINT']
DB_PORT = os.environ.get('DB_PORT', '5432')

def handler(event, context):
    # DB_ENDPOINT ya está disponible aquí
    print(f'Conectando a {DB_ENDPOINT}:{DB_PORT}')
    return {'statusCode': 200}

Node.js:

const DB_ENDPOINT = process.env.DB_ENDPOINT;
const DB_PORT = process.env.DB_PORT || '5432';

exports.handler = async (event) => {
    console.log(`Conectando a ${DB_ENDPOINT}:${DB_PORT}`);
    return { statusCode: 200 };
};

Inicializar estas variables fuera del handler es deliberado. El entorno de ejecución de Lambda reutiliza el contexto entre invocaciones — leer os.environ una sola vez durante la inicialización del módulo evita la lectura repetida en cada invocación.

Paso 3: Cifrar Variables de Entorno con una CMK de KMS

Si el valor que estás pasando es sensible — una cadena de conexión con credenciales, una API key, un token de servicio — el cifrado con tu propia CMK te da control de auditoría completo a través de CloudTrail y la capacidad de revocar acceso deshabilitando la clave.

Primero, crea o identifica la CMK que usarás:

aws kms create-key \
  --description 'CMK para variables de entorno Lambda' \
  --region us-east-1

El comando devuelve el ARN de la clave. Úsalo en el siguiente paso:

aws lambda update-function-configuration \
  --function-name mi-funcion \
  --environment 'Variables={DB_ENDPOINT=mydb.cluster-xyz.us-east-1.rds.amazonaws.com,DB_PORT=5432}' \
  --kms-key-arn arn:aws:kms:us-east-1:123456789012:key/tu-key-id \
  --region us-east-1

Una vez configurada la CMK, Lambda la usa automáticamente para cifrar y descifrar las variables. Tu código no cambia — el descifrado ocurre antes de que el proceso arranque.

Paso 4: Configurar los Permisos IAM Necesarios

Aquí es donde la mayoría de los despliegues fallan silenciosamente. El rol de ejecución de la función Lambda necesita permisos para usar la CMK. Sin ellos, el entorno de ejecución no puede descifrar las variables y la función falla al arrancar.

Política IAM mínima para el rol de ejecución de Lambda:

🔽 Ver política IAM completa
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowLambdaKMSDecrypt",
      "Effect": "Allow",
      "Action": [
        "kms:Decrypt"
      ],
      "Resource": "arn:aws:kms:us-east-1:123456789012:key/tu-key-id"
    }
  ]
}

Aplica la política al rol de ejecución:

aws iam put-role-policy \
  --role-name mi-funcion-execution-role \
  --policy-name LambdaKMSDecryptPolicy \
  --policy-document file://lambda-kms-policy.json

Además, la política de recursos de la CMK debe permitir que el rol de ejecución use la clave. Verifica la política de la clave:

aws kms get-key-policy \
  --key-id arn:aws:kms:us-east-1:123456789012:key/tu-key-id \
  --policy-name default \
  --region us-east-1

Si el rol de ejecución no aparece como principal autorizado en la política de la clave, el permiso IAM solo no es suficiente — KMS evalúa ambas políticas.

graph LR LambdaRole["Rol de Ejecución Lambda"] -->|"kms:Decrypt en política IAM"| KMSEval["Evaluación KMS"] CMKPolicy["Política de Recursos de la CMK"] -->|"Principal autorizado"| KMSEval KMSEval -->|"Ambas permiten"| Allow["Descifrado Autorizado"] KMSEval -->|"Alguna deniega"| Deny["AccessDeniedException Cold Start falla"] style Allow fill:#f0fff4,stroke:#38a169 style Deny fill:#fff0f0,stroke:#e53e3e
  1. Política IAM del rol: Permite la acción kms:Decrypt sobre el ARN de la CMK.
  2. Política de recursos de KMS: Lista el rol de ejecución como principal autorizado.
  3. Evaluación combinada: KMS requiere que ambas políticas permitan la operación. Si alguna falla, el descifrado es denegado.
  4. Resultado: Lambda puede descifrar las variables al arrancar el entorno de ejecución.

El Error Que Más Se Repite con Variables de Entorno y KMS

El patrón que aparece con más frecuencia en producción: la función se despliega sin errores, pero falla en la primera invocación con un error críptico de inicialización. El log en CloudWatch muestra algo relacionado con permisos KMS, pero el equipo asume que es un problema de red porque la función 'siempre funcionó antes'.

La causa real casi siempre es esta: la CMK existía y tenía permisos correctos en el entorno de desarrollo, pero al desplegar en producción se usó una CMK diferente (o la misma clave en una región diferente) sin actualizar la política del rol de ejecución. Lambda no valida los permisos KMS en el momento del despliegue — solo cuando intenta arrancar el entorno de ejecución.

El síntoma observable: AccessDeniedException en los logs de CloudWatch durante el cold start, con el ARN de la clave en el mensaje de error. La función nunca llega a ejecutar el handler.

La verificación correcta antes de desplegar:

aws kms describe-key \
  --key-id arn:aws:kms:us-east-1:123456789012:key/tu-key-id \
  --region us-east-1 \
  --query 'KeyMetadata.{Estado:KeyState,Region:AWSAccountId}'
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:role/mi-funcion-execution-role \
  --action-names kms:Decrypt \
  --resource-arns arn:aws:kms:us-east-1:123456789012:key/tu-key-id

Si simulate-principal-policy devuelve implicitDeny o explicitDeny, el problema está en la política IAM o en la política de recursos de la CMK — no en el código de la función.

Variables de Entorno vs. Secrets Manager: Cuándo Usar Cada Uno

Las variables de entorno de Lambda con CMK son adecuadas para configuración sensible que no cambia frecuentemente: endpoints, nombres de recursos, flags de configuración. Para credenciales que rotan automáticamente, tokens OAuth, o secretos que múltiples servicios necesitan leer de forma centralizada, Secrets Manager es la herramienta correcta.

La diferencia operacional clave: actualizar una variable de entorno requiere un nuevo despliegue de la configuración de la función (lo que puede generar un cold start). Secrets Manager permite actualizar el valor sin tocar la función — el código simplemente llama a la API en cada ejecución o cachea el valor con un TTL.

Usando Variables de Entorno Lambda con KMS: Próximos Pasos

Con las variables de entorno configuradas y cifradas, el siguiente nivel de madurez operacional es centralizar los secretos en AWS Secrets Manager e integrarlos con Lambda usando el Lambda Extensions para Secrets Manager, que cachea los valores localmente y reduce las llamadas a la API. Para configuración no sensible a gran escala, AWS AppConfig ofrece capacidades de despliegue controlado y rollback que las variables de entorno simples no tienen.

Consulta la documentación oficial de AWS para los límites actualizados de tamaño y las regiones donde KMS está disponible: Documentación de Variables de Entorno de Lambda.

Glosario de Términos Clave

Término Definición
CMK (Customer Managed Key) Clave KMS creada y gestionada por el cliente, con control total sobre políticas, rotación y auditoría
Entorno de ejecución (Execution Environment) El contexto de proceso aislado donde Lambda ejecuta tu función; puede reutilizarse entre invocaciones
Cold Start El proceso de inicialización de un nuevo entorno de ejecución, incluyendo el descifrado de variables de entorno
Política de recursos KMS Política adjunta directamente a una clave KMS que controla qué principales pueden usarla, independientemente de las políticas IAM
Rol de ejecución Lambda El rol IAM que Lambda asume para ejecutar la función y acceder a otros servicios AWS

Comentarios

Entradas populares de este blog

EC2 sin acceso a Internet en VPC personalizada: Internet Gateway y Route Table

Actualizar Contenido en CloudFront: Cómo Crear una Invalidación para Limpiar el Caché del Edge

Aumentar el Timeout de Lambda: Configuración, Límites y Diagnóstico en Producción