Módulo 3: Secrets Management
6. Rotación de secretos: el mecanismo real, nombrado
Descripción
La lección 5 mostró, de pasada, VersionStages: ["AWSCURRENT"] en la salida representativa de get-secret-value. Esta lección desarrolla, con precisión completa, qué significa esa etiqueta y las otras dos que la acompañan durante una rotación real: AWSPENDING y AWSPREVIOUS. Es la lección más técnica de este módulo, y también la más honesta sobre su propio límite: vas a entender el mecanismo exacto que usa Secrets Manager en producción, sin fingir haberlo ejecutado de punta a punta.
Por qué esta lección es representativa, la razón exacta. Rotar un secreto de verdad exige tres piezas que no caben en el formato de una lección escrita: una función Lambda de rotación desplegada, con permiso de hablar tanto con Secrets Manager como con el sistema externo real; un schedule de rotación que dispara esa Lambda automáticamente, con un ciclo de tiempo medido en horas o días, no en segundos; y, para confirmar que funcionó, esperar a que ese ciclo corra al menos una vez completo. Ninguna de las tres es imposible de construir —de hecho, esta lección te muestra exactamente cómo se vería el HCL que la desplegaría—, pero encadenarlas de punta a punta y verificar el resultado no es algo que puedas confirmar leyendo esta lección en los próximos minutos, a diferencia de las piezas sueltas de las lecciones 4 y 5, que sí corrieron de verdad.
Conexión con el módulo
Las lecciones 4 y 5 construyeron las piezas que la rotación necesita como base: un secreto ya versionado en Secrets Manager (aws_secretsmanager_secret_version). Esta lección explica qué le falta a esa base para rotar sola, y por qué esa pieza faltante queda fuera del alcance ejecutable de este módulo. La lección 7 vuelve a terreno completamente ejecutable: escaneo real de secretos filtrados.
Analogía: cambiar la cerradura sin dejar a nadie afuera
Imagina que tienes que cambiar la cerradura de una oficina que nunca cierra —hay gente entrando y saliendo constantemente— sin que, en ningún momento del proceso, alguien con la llave vieja se quede literalmente afuera. La solución no es "cambiar la cerradura y avisarle a todo el mundo la nueva combinación al mismo tiempo" —siempre hay alguien que se entera un segundo tarde—. La solución real es: instalar una cerradura nueva que, por un rato, acepta las dos llaves —la vieja y la nueva—, dar tiempo a que todo el mundo actualice su copia, y solo entonces desactivar la llave vieja. Ese período de transición, donde ambas llaves funcionan, es exactamente lo que las tres etiquetas de esta lección coordinan.
Las tres etiquetas de staging, con precisión
Cada versión de un secreto en Secrets Manager lleva una o más etiquetas de staging (staging labels), y son esas etiquetas —no un número de versión simple— las que determinan qué versión es "la activa" en cualquier momento:
AWSCURRENT— la versión activa. Cualquier llamada aget-secret-valuesin especificar una versión explícita devuelve, siempre, la que tiene esta etiqueta.AWSPENDING— la versión nueva, en construcción, todavía no confirmada como funcional. Existe en paralelo aAWSCURRENT, sin reemplazarla todavía.AWSPREVIOUS— la versión que fueAWSCURRENThasta la rotación más reciente. Se conserva, no se borra, precisamente para poder revertir si algo sale mal con la versión nueva.
En cualquier momento fuera de una rotación en curso, un secreto tiene exactamente una versión con AWSCURRENT y, si ya rotó al menos una vez, exactamente una con AWSPREVIOUS. El secreto que creaste en la lección 5 —su primera versión, recién aplicada— tiene solo AWSCURRENT; todavía no existe ninguna versión AWSPREVIOUS porque nunca rotó.
El ciclo completo, las cuatro fases de la función de rotación
Secrets Manager no rota un secreto por sí mismo — necesita una función Lambda de rotación, que tú (o AWS, para ciertos servicios administrados como RDS) provees, y que Secrets Manager invoca automáticamente en cuatro fases distintas, cada una con un nombre fijo que la propia API de Secrets Manager espera:
EL CICLO DE ROTACIÓN — CUATRO INVOCACIONES DE LA MISMA LAMBDA
1. createSecret → genera un valor nuevo, lo guarda con la etiqueta AWSPENDING
(AWSCURRENT sigue siendo la versión vieja, sin tocar)
│
2. setSecret → usa el valor AWSPENDING para actualizar el sistema EXTERNO
(la API de aduanas, en el caso de esta guía) con la
credencial nueva — el sistema externo ahora acepta AMBAS
│
3. testSecret → confirma que el valor AWSPENDING funciona de verdad contra
el sistema externo, antes de comprometerse a nada
│
4. finishSecret → mueve la etiqueta AWSCURRENT a la versión que era AWSPENDING;
la versión que era AWSCURRENT pasa a ser AWSPREVIOUS
Fíjate en el orden exacto de las fases 2 y 4: el sistema externo se actualiza antes de que Secrets Manager reasigne cuál versión es la activa. Esto es, precisamente, la ventana de "las dos llaves funcionan a la vez" de la analogía — durante el tiempo entre setSecret y finishSecret, el sistema de aduanas acepta tanto la credencial vieja (todavía AWSCURRENT en Secrets Manager) como la nueva (ya activa en el sistema externo, todavía AWSPENDING en Secrets Manager). Ningún cliente que esté a mitad de una llamada, usando la credencial que leyó un segundo antes de la rotación, se queda con una credencial rechazada.
Si testSecret (fase 3) falla —el valor nuevo, por la razón que sea, no funciona contra el sistema externo—, finishSecret (fase 4) nunca corre: AWSCURRENT sigue apuntando a la versión vieja, que nunca dejó de funcionar. Ese es el mecanismo de reversión implícito del diseño: no hace falta un "rollback" explícito porque la versión vieja nunca se desactivó hasta que la nueva demostró funcionar.
Qué esperar (literal — el orden de las cuatro fases y sus nombres son parte fija de la API de Secrets Manager, documentados oficialmente, no dependen de ninguna ejecución particular):
def lambda_handler(event, context):
step = event["Step"]
if step == "createSecret":
... # generate a new value, store it with AWSPENDING
elif step == "setSecret":
... # push the AWSPENDING value to the external system
elif step == "testSecret":
... # confirm the AWSPENDING value authenticates successfully
elif step == "finishSecret":
... # move AWSCURRENT to the version that was AWSPENDING
Esta firma —event["Step"] con los cuatro valores exactos de arriba— es la que Secrets Manager espera de cualquier función Lambda de rotación, sin importar contra qué sistema externo esté rotando.
El HCL que declararía la rotación (mostrado, no aplicado)
Así se vería, en secrets.tf, la declaración de un schedule de rotación automática sobre el secreto de la lección 5 — mostrado en su forma completa para que reconozcas el patrón, no como un paso que vas a ejecutar en esta lección:
resource "aws_secretsmanager_secret_rotation" "customs_api_credentials" {
secret_id = aws_secretsmanager_secret.customs_api_credentials.id
rotation_lambda_arn = aws_lambda_function.customs_api_rotation.arn
rotation_rules {
automatically_after_days = 30
}
}
rotation_lambda_arn apunta a una función Lambda —con las cuatro fases de arriba implementadas— que este módulo no declara: escribir esa función exige conocer el protocolo de autenticación específico de un sistema externo real (¿la API de aduanas rota credenciales cambiando una contraseña en un endpoint propio? ¿emitiendo una API key nueva?), un detalle que varía sistema por sistema y que esta guía, deliberadamente, no inventa sin una integración real detrás. rotation_rules { automatically_after_days = 30 } es el schedule: cada 30 días, Secrets Manager invoca las cuatro fases automáticamente, sin que ningún humano dispare el ciclo a mano.
Por qué SSM Parameter Store no tiene un equivalente
Vale la pena cerrar el círculo con la lección 3: el parámetro de la lección 4 —la firma HMAC del webhook— no tiene ningún mecanismo equivalente a aws_secretsmanager_secret_rotation. Si esa firma necesitara rotar, la única forma sería: generar un valor nuevo, actualizarlo manualmente con aws_ssm_parameter (una nueva versión del mismo parámetro, vía overwrite = true), y coordinar manualmente que el sistema que verifica esa firma se entere del cambio antes de que alguien empiece a enviar webhooks firmados con el valor nuevo. Ninguna Lambda, ningún schedule, ningún ciclo de cuatro fases — exactamente la Razón 2 de la lección 3, ahora vista en todo su detalle técnico.
Errores comunes
Asumir que AWSPENDING reemplaza inmediatamente a AWSCURRENT (de secuencia). Qué pasa: alguien, leyendo sobre rotación por primera vez, asume que en el momento en que existe una versión AWSPENDING, esa es ya la versión "actual". Cómo detectarlo: si tu mental model de rotación no incluye un período donde ambas versiones coexisten y funcionan. Cómo corregirlo: AWSPENDING es, por definición, la versión que todavía no es AWSCURRENT — existen en paralelo, deliberadamente, hasta que finishSecret (fase 4) hace el cambio. Confundir esto lleva a pensar, incorrectamente, que una rotación es instantánea y arriesgada, cuando el diseño completo existe justamente para que no lo sea.
Creer que la separación contenedor/contenido de la lección 5 es "solo para organización" (de conexión entre lecciones). Qué pasa: alguien, después de la lección 5, entiende que aws_secretsmanager_secret y aws_secretsmanager_secret_version son dos recursos distintos, pero no conecta por qué esa separación es un prerequisito técnico de esta lección. Cómo detectarlo: si no puedes explicar qué pasaría si Secrets Manager mezclara contenedor y contenido en un solo recurso, durante una rotación. Cómo corregirlo: cada fase del ciclo de rotación crea o promueve una versión del secreto —nunca recrea el contenedor—; sin esa separación, cada rotación destruiría y recrearía el secreto entero, invalidando cualquier ARN o política que apuntara a él en el medio.
Tratar esta lección como si hubiera ejecutado una rotación real (de honestidad de ejecución, el punto central de esta lección). Qué pasa: alguien, después de leer el HCL del aws_secretsmanager_secret_rotation, cree que Andes Cargo ya tiene rotación automática funcionando. Cómo detectarlo: si buscas, en algún lado de este módulo, la salida real de un finishSecret completado. Cómo corregirlo: esta lección declaró explícitamente, desde su descripción, que el HCL de arriba está mostrado, no aplicado — la razón exacta está en la introducción de esta lección: un ciclo de rotación real necesita una Lambda funcional contra un sistema externo real y un schedule medido en días, ninguno de los dos cabe en el formato ejecutable de esta guía.
Ejercicios
Ejercicio 1 — Ordena las cuatro fases desde una descripción desordenada. Un compañero te describe, en desorden, lo que hace cada fase: (a) "confirma que la credencial nueva funciona contra el sistema externo, antes de comprometerse"; (b) "mueve la etiqueta AWSCURRENT a la versión nueva"; (c) "genera el valor nuevo y lo guarda como AWSPENDING"; (d) "actualiza el sistema externo con el valor AWSPENDING". Ponlas en el orden correcto, con su nombre de fase.
Ver solución
1. createSecret — (c) genera el valor nuevo y lo guarda como AWSPENDING. 2. setSecret — (d) actualiza el sistema externo con el valor AWSPENDING. 3. testSecret — (a) confirma que la credencial nueva funciona, antes de comprometerse. 4. finishSecret — (b) mueve la etiqueta AWSCURRENT a la versión nueva. El orden importa porque cada fase depende de que la anterior haya tenido éxito — si testSecret fallara, finishSecret nunca correría, y AWSCURRENT seguiría apuntando a la versión vieja, todavía funcional.
Ejercicio 2 — Explica la ventana de "las dos llaves" con tus propias palabras. Un colega pregunta por qué Secrets Manager no simplemente reemplaza el valor viejo por el nuevo en un solo paso atómico, en vez de este proceso de cuatro fases. Responde usando la analogía de la cerradura de esta lección.
Ver solución
Una respuesta completa suena, más o menos, así: "Un reemplazo atómico asume que todo el mundo que usa la credencial se entera del cambio exactamente al mismo instante — en la práctica, nunca pasa así: siempre hay un cliente a mitad de una llamada, o un proceso que todavía tiene la credencial vieja en memoria. El proceso de cuatro fases crea deliberadamente una ventana donde ambas credenciales funcionan contra el sistema externo — la vieja porque nunca se desactivó, la nueva porque ya se activó — y solo después de confirmar que la nueva funciona (testSecret) se promueve como la única activa. Es exactamente como cambiar la cerradura de una oficina que nunca cierra sin dejar a nadie con la llave vieja afuera a mitad del cambio."
Ejercicio 3 — Explica por qué SSM Parameter Store no necesita este mecanismo para todos sus valores. Un compañero pregunta si es una limitación grave que SSM Parameter Store no tenga un equivalente a aws_secretsmanager_secret_rotation. ¿Estás de acuerdo? Justifica con el criterio de la lección 3.
Ver solución
No, no es una limitación grave — es coherente con lo que SSM Parameter Store fue diseñado para guardar. La mayoría de los valores que van ahí, según el criterio de la lección 3, son configuración: un feature flag, una URL, un nombre de ambiente — valores que no representan una credencial de autenticación frente a otro sistema, y que por lo tanto no tienen ningún concepto de "rotación" que tenga sentido aplicarles. El propio caso de la lección 4 —la firma HMAC del webhook— es la excepción parcial: sí podría beneficiarse de rotación, pero al no ser Secrets Manager, esa rotación queda como trabajo manual, exactamente la Razón 2 de la lección 3, aplicada ahora con todo el detalle técnico de esta lección.
Resumen y siguiente paso
En esta lección entendiste el mecanismo real de rotación de Secrets Manager: las tres etiquetas de staging (AWSCURRENT, AWSPENDING, AWSPREVIOUS) y las cuatro fases (createSecret, setSecret, testSecret, finishSecret) que una función Lambda de rotación implementa, en el orden exacto que Secrets Manager invoca. Viste el HCL que declararía ese mecanismo sobre el secreto de la lección 5, con la razón técnica exacta de por qué esta lección lo explica sin ejecutarlo de punta a punta —una Lambda funcional y un ciclo de tiempo real que no caben en el formato de esta guía—. Cerraste el círculo con la lección 3: por qué SSM Parameter Store nunca tuvo este problema para resolver, dado el tipo de valor que típicamente guarda.
Antes de avanzar deberías poder: nombrar las tres etiquetas de staging y qué representa cada una en cualquier momento del ciclo; ordenar las cuatro fases de una función de rotación de memoria; y explicar, sin dudar, por qué esta lección es representativa y qué la distingue de las lecciones 4 y 5, que sí corrieron de verdad.
La lección 7 vuelve a terreno completamente ejecutable: vas a correr Trivy de verdad, con un hallazgo real, sobre un secreto insertado a propósito en un commit.
Recursos
- AWS Docs — Rotate AWS Secrets Manager secrets — introducción oficial a la rotación, punto de partida de esta lección.
- AWS Docs — How rotation works — la fuente oficial de las tres etiquetas de staging y las cuatro fases de la función Lambda de rotación, desarrolladas en detalle en esta lección.
- Terraform Registry —
aws_secretsmanager_secret_rotation— documentación oficial del recurso mostrado en el HCL de esta lección. - Este módulo, lección 3 — el criterio de decisión (rotación nativa frente a manual) que esta lección desarrolla con todo el detalle técnico.