# [Interno] Publicación de Authorizers en Producción
## Descripción del problema
Actualmente, el proyecto *serverless* `plus-back-authorizer` gestiona los *Authorizers* utilizados por diversas *APIs* de **AFEX+**, entre ellas:
| Proyecto | Célula |
|-----------------|-------------------------|
| afex-services | Giros |
| agent-api | Giros |
| payments-api | Giros |
| remittance-api | Cambios |
| transfer-api | Giros |
| plus-services | Giros |
| clients-api | Clientes & Cumplimiento |
| pulpoplus | Giros |
| exchange-api | Cambios |
Este proyecto centraliza la lógica de autorización, exportando sus recursos como *Outputs* en *CloudFormation*, lo que permite a los proyectos mencionados importarlos para gestionar el acceso a sus recursos.
Además de los *Authorizers*, el *stack* de `plus-back-authorizer` incluye recursos esenciales para el uso de `cache` mediante *Redis*, como *Security Groups* y *Subnets* dedicadas al manejo de sesión.
### Problema con la integración a la VPC estándar
Como parte de la normalización de *VPCs*, el equipo de infraestructura ha solicitado que todas las *Lambdas* utilicen una misma *VPC* por ambiente. Sin embargo, `plus-back-authorizer` no cumple actualmente con este estándar.
Se implementó una solución para integrarlo a la *VPC* solicitada, pero durante la publicación del *stack* para su actualización es necesario eliminar los *Security Groups* y *Subnets* previamente creados y asociados a la *VPC* incorrecta, para luego crear los nuevos recursos en la *VPC* correcta.
### Actualización del stack
Aunque idealmente esta actualización debería realizarse sin inconvenientes, en despliegues previos se han observado conflictos debido a la interdependencia entre recursos, funciones *Lambda* y las interfaces de red creadas automáticamente por AWS. Esto ha impedido la eliminación de los recursos antiguos y, por lo tanto, la actualización del proyecto. Casos similares ya ocurrieron en los despliegues de `staging` y `cert`.
Si bien el equipo de infraestructura podría intentar desvincular manualmente los recursos bloqueados, en algunos casos AWS impide incluso la eliminación manual, dejando como única alternativa forzar la eliminación del *stack* y recrearlo desde cero, y es por esto que considero necesario tener un plan de resguardo para no exponer la operación productiva.
Este escenario es el más crítico, ya que implica:
1. Volver a desplegar todos los proyectos que dependen del *Authorizer*, asegurándose de no perder configuraciones.
2. Eliminar y recrear el *stack* de `plus-back-authorizer`.
3. Volver a desplegar los proyectos dependientes con la nueva integración.
Este proceso no solo impacta a las células responsables de los proyectos dependientes, sino también a la célula de Connect, que utiliza el *Authorizer* referenciándolo por su ID, el cual cambiaría al crear un nuevo *stack*.
## Alternativas de despliegue
Dado el impacto potencial y previo a una revisión con infraestructura es que la publicación en `prod` se considera de alto riesgo, incluso en horario inhábil, ya que durante la ejecución se detendría temporalmente la operación del ambiente incluyendo "clientes" como la aplicación de Connect en producción. Desde aquí es que planteamos 2 posibles maneras para realizar la tarea.
### Opción 1: Despliegue tradicional con cambio temporal de ambiente
La primera opción consiste en intentar la actualización del *stack* de manera tradicional, desvinculando los recursos bloqueados (si llega a ocurrir) para actualizar la configuración, sin eliminar el *stack*.
Si esto resulta exitoso, la actualización sería rápida y efectiva tomando solo un par de horas. Sin embargo, si nos encontramos con el peor escenario donde es imposible actualizar sin eliminar el *stack*, deberíamos realizar una serie de pasos adicionales:
- Volver a desplegar todos los proyectos afectados sin depender del Authorizer para mantener su configuración.
- Eliminar y volver a publicar el Authorizer con la nueva configuración
- Volver a desplegar los proyectos que dependen del Authorizer, esta vez integrando nuevamente la dependencia del Authorizer actualizado.
- Idealmente coordinar con cada célula el despliegue de sus respectivos proyectos.
- Actualizar la configuración de Connect con el nuevo ID del *stack*.
Para mitigar el impacto en producción, se propone trasladar temporalmente la operación a `cert` mientras se ejecuta la actualización en `prod`. Esto permitiría:
1. Intentar realizar la publicación de manera tradicional.
4. Si falla, eliminar el *stack*, crearlo nuevamente y desplegar los proyectos dependientes.
5. Validar la estabilidad del nuevo despliegue antes de restablecer la operación en producción. En el peor de los casos esto podría estar restablecido durante el día siguiente.
Esta alternativa minimiza el impacto en producción y permite ejecutar el despliegue de manera controlada.
### Opción 2: Creación de un nuevo stack para authorizer en paralelo
Esta opción, aunque más segura, es también la más compleja y prolongada. Consiste en desplegar un nuevo *stack* en paralelo con una nueva instancia del *Authorizer* utilizando la misma configuración de *Cognito* para la validación de sesiones, que convivirá con la instancia del *Authorizer* actual.
Este enfoque permitiría:
- Crear un nuevo *stack* limpio en la *VPC* correcta.
- Mantener la operación de los proyectos en producción sin interrupciones.
- Evitar conflictos con recursos bloqueados en AWS.
Sin embargo, presenta varios desafíos:
1. Sería necesario desplegar el nuevo *Authorizer* en todos los ambientes siguiendo el flujo de publicación.
2. La referencia al *Authorizer* en *CloudFormation* debería exportarse con un nombre diferente para evitar conflictos.
3. Una vez desplegado, cada célula debería actualizar sus proyectos uno por uno para integrar el nuevo *Authorizer*, lo que podría tomar un tiempo indefinido.
4. Finalmente, una vez que todos los proyectos migren al nuevo *Authorizer*, se eliminaría el antiguo.
Además, este enfoque requiere que previo a la eliminación del Authorizer actual se desvinculen cuidadosamente las tablas de *DynamoDB* creadas por él, para preservarlas e importarlas al nuevo *stack*.
Aunque esta opción ofrece mayor flexibilidad, implica un esfuerzo considerable y un plan de trabajo más extenso.
## Conclusión
Dadas las alternativas planteadas, se deben evaluar los esfuerzos y riesgos de ambas soluciones:
1. **Opción 1:** Mover temporalmente la operación de `prod` a `cert`, actualizar el *stack* y restablecer la operación al finalizar (posible impacto de un día en el peor caso).
2. **Opción 2:** Crear un nuevo *Authorizer* en paralelo, lo que requiere una implementación gradual con la colaboración de todas las células involucradas (tiempo de implementación indefinido).