Autor: Iker Acevedo¶
Fecha creacion: 2026-10-18
Estado: desarrollo
Runbook: poner en marcha y operar novedades Inter¶
Qué hace cada pieza y en qué orden se enciende. Nada de esto se ejecuta solo: Terraform, los pipelines y los scripts los lanza una persona. En producción cada paso es una escritura; léelos antes.
| Pieza | Dónde vive | Quién la crea |
|---|---|---|
| Lambda, rol, alarmas, dashboard, SNS | Terraform_Infraestructura_Logigho → environments/<env>/novedades + modules/novedades-inter |
terraform apply (Iker) |
| Ruta del webhook en el REST del entorno + API key | modules/novedades-webhook, llamado desde environments/preprod/datos (PreProd) y environments/prod/novedades (producción) |
terraform apply (Iker); en producción el deployment lo publica el CLI |
| Step y disparador de PreProd | environments/preprod/procesos-automaticos/step_procesos_logigho.tf |
terraform apply (Iker) |
| Estado en la Step de producción | pipelines/novedades/scripts/agregar_novedades_a_step_function.py (la Step prod no está en Terraform) |
Script (Iker) |
| Código y variables sensibles | pipelines/novedades/ |
Pipeline de Azure DevOps |
| Colección e índices | Tres createIndex (secciones A2 y B2) |
mongosh (Iker) |
A. PreProd¶
A1. Infraestructura (Terraform) — en PowerShell¶
Son tres directorios, en este orden (el webhook vive en el REST de PreProd, que administra datos):
environments/preprod/novedades: la lambda, su rol, las alarmas y el dashboard.environments/preprod/datos: agrega la ruta/webhooks/ws-inter/flujo-guiaal RESTAPI_LogiGho_Rest_PreProd, crea la API key y redespliega el stage.environments/preprod/procesos-automaticos: la Step y su disparador (deshabilitado).
cd C:\Users\Iker\Documents\LogiGho\Terraform_Infraestructura_Logigho
git switch feature/novedades-inter
$env:AWS_PROFILE = "Dev-logigho-test-01" # cuenta 376313750428 (en PowerShell NO se usa "export")
aws sts get-caller-identity --query Account --output text # debe imprimir 376313750428
terraform -chdir=environments/preprod/novedades init
terraform -chdir=environments/preprod/novedades plan "-out=novedades.tfplan"
terraform -chdir=environments/preprod/novedades apply novedades.tfplan
$env:AWS_PROFILE: qué credenciales usa AWS en esa ventana. Si olvidas definirla, Terraform usa otra cuenta y su guardiaallowed_account_idslo frena.-chdir=: ejecuta Terraform dentro de esa carpeta sin moverte."-out=…"va entre comillas porque PowerShell parte el argumento en el punto.plan -out: calcula qué cambiará y lo guarda.apply <archivo>ejecuta exactamente ese plan, no otro.- Tras el
apply, confirma la suscripción del correo (AWS envía un mail a cada dirección decorreos_alarma).
Si en este directorio ves
destroyde recursosaws_api_gateway_*y deaws_lambda_permission.api_gateway, es el API temporalWebhooks-LogiGho-PreProdde una primera versión (descartado por ADR-002): se destruye y nadie lo usaba.
Luego datos. Este directorio también gestiona la lambda de reportes, así que necesita el mismo valor de la cadena Mongo
que ya usa (si no, el plan intentaría cambiarle las variables). Se lee de la propia lambda, sin imprimirla:
$env:TF_VAR_mongodb_connection_string = aws lambda get-function-configuration --function-name ApiLambdaPublicarReporteAnalytics --query "Environment.Variables.MONGODB_CONNECTION_STRING" --output text
terraform -chdir=environments/preprod/datos init
terraform -chdir=environments/preprod/datos plan "-out=datos.tfplan"
Revisa el plan antes de aplicar. Debe mostrar: 9 recursos novedades_webhook por crear, aws_api_gateway_deployment.preprod
reemplazado (redeploy) y aws_api_gateway_stage.preprod actualizado. Resultado esperado: Plan: 10 to add, 1 to change, 1 to destroy.
Si aparece module.datos.aws_lambda_function.reportes cambiando, detente: el valor de la cadena no coincide.
terraform -chdir=environments/preprod/datos apply datos.tfplan
Remove-Item Env:\TF_VAR_mongodb_connection_string # no dejar el secreto en la sesión
terraform -chdir=environments/preprod/datos output novedades_url_webhook # URL para el proveedor y para URL_WEBHOOK
terraform -chdir=environments/preprod/novedades output azure_devops_novedades_cd_rol_arn
La API key (secreta) se lee solo cuando se necesita: terraform -chdir=environments/preprod/datos output -raw novedades_api_key_webhook.
Por último la Step y su disparador (réplica de Step_Procesos_Logigho, deshabilitado):
terraform -chdir=environments/preprod/procesos-automaticos init
terraform -chdir=environments/preprod/procesos-automaticos plan "-out=step.tfplan"
terraform -chdir=environments/preprod/procesos-automaticos apply step.tfplan
El plan de este directorio también mostrará
aws_sfn_state_machine.procesos"updated in-place". Es un cambio de solo espacios en blanco del JSON de la Step de TCC, anterior a este trabajo y sin efecto. Si prefieres no tocarlo:apply -target=aws_iam_role.step_logigho -target=aws_iam_role_policy.step_logigho_invocar_lambdas -target=aws_sfn_state_machine.logigho -target=aws_iam_role.scheduler_logigho -target=aws_iam_role_policy.scheduler_logigho_iniciar_step -target=aws_scheduler_schedule.task_procesos_inter.
A2. Colección e índices¶
En mongosh (o la consola de Atlas / DBeaver), contra Atlas PreProd:
use LogighoDB
db.SeguimientoNovedadesInter.createIndex({ Numeropreenvio: 1 }, { name: "ux_numeropreenvio", unique: true })
db.SeguimientoNovedadesInter.createIndex({ "Solicitud.Ref": 1 }, { name: "ix_solicitud_ref" })
db.SeguimientoNovedadesInter.createIndex({ EstadoSeguimiento: 1 }, { name: "ix_estado_seguimiento" })
db.SeguimientoNovedadesInter.getIndexes()
Crea la colección SeguimientoNovedadesInter y sus 3 índices. No afecta a PedidosInter.
Tanto Atlas PreProd como DocumentDB usan la base LogighoDB. Si la colección no existe, createIndex la crea.
A3. Secretos cifrados y variable group¶
Los valores sensibles van cifrados con AES (igual que en las demás lambdas). Para cifrar uno:
mkdir $env:TEMP\cifrar; cd $env:TEMP\cifrar
dotnet new console --force # proyecto de consola desechable, fuera del repo
dotnet add reference "C:\Users\Iker\Documents\LogiGho\Lambdas_NET_LogiGho\LambdasLogiGho.Infraestructura\Seguridad\Seguridad.csproj"
Reemplaza Program.cs por (lee de la entrada para que el secreto no quede en el historial de comandos):
Luego dotnet run, pega el valor en claro y Enter: imprime el texto cifrado.
Variable group novedades-inter-preprod-secretos (Azure DevOps → Pipelines → Library):
| Variable | Valor | ¿Secreta? |
|---|---|---|
CADENA_CONEXION |
Cadena de Atlas preprod, cifrada | Sí |
API_KEY_WS_INTER |
La clave que da el proveedor para llamar a ws-inter, cifrada | Sí |
WEBHOOK_API_KEY |
Salida novedades_api_key_webhook de environments/preprod/datos, cifrada |
Sí |
URL_WEBHOOK |
Salida novedades_url_webhook de environments/preprod/datos, sin cifrar |
No |
SLACK_WEBHOOK_ALERTAS |
(opcional en PreProd) webhook del canal de alertas, cifrado; si lo usas, agrégalo a claves en cd-preprod.yml |
Sí |
A4. Azure DevOps¶
- Service connection AWS por OIDC llamada
aws-preprod-novedadescon el rolazdo-novedades-preprod(ARN en la salida de Terraform). - Pipelines desde
pipelines/novedades/:ci.yml(nombre sugeridoLambdas-Novedades-CI, con política de rama como los demás),cd-preprod.yml(Lambdas-Novedades-CD-PreProd) ycd-prod.yml(Lambdas-Novedades-CD-Prod). - Una rama
release/…con el código disparacd-preprod: sube el zip, respalda, agrega las variables, publica el código, verifica el SHA y hace la prueba de humo (el webhook sin API key debe dar 403).
A5. Prueba de punta a punta¶
# (bash; en PowerShell usa curl.exe y $URL = terraform … output -raw novedades_url_webhook)
URL=$(terraform -chdir=environments/preprod/datos output -raw novedades_url_webhook)
KEY=$(terraform -chdir=environments/preprod/datos output -raw novedades_api_key_webhook)
# 1) Sin clave: API Gateway rechaza (403)
curl -i -X POST "$URL" -d '{}'
# 2) Con clave y una guía que nunca pedimos: 200 con "desconocidos":1
curl -i -X POST "$URL" -H "x-api-key: $KEY" -H "Content-Type: application/json" -d '{"guia":"1","encontrado":false}'
# 3) Contrato real del proveedor, en modo síncrono (valida que la API key y el formato son los esperados)
curl -s -X POST https://wsinter.duckdns.org/webhook/flujo-guia/sync -H "x-api-key: <clave del proveedor>" \
-H "Content-Type: application/json" -d '{"guia":"240063616541"}'
Luego, una corrida real: consola de Step Functions → Step_Procesos_Logigho → Start execution con entrada {}
(no hace falta activar el disparador). Revisa en Atlas:
db.SeguimientoNovedadesInter.find({}, {Guia:1, Prioridad:1, "Solicitud.Estado":1, "UltimoMotivo.Motivo":1})
db.PedidosInter.find({ MotivoNovedadInter: { $exists: true } }, { Numeropreenvio:1, MotivoNovedadInter:1 })
Entrega al proveedor la URL y la API key (canal seguro), espera los callbacks y comprueba:
MotivoNovedadInter escrito, historial con 1 entrada y una segunda ejecución con 0 envíos repetidos
(solicitudesEnviadas: 0 en el log fin). Para simular una caída pon temporalmente una URL_WS_INTER inválida
y verifica que llega la alerta de Slack.
Cuando todo esté bien, activa el disparador a mano: EventBridge Scheduler → TaskProcesosInter → Enable.
Terraform no lo vuelve a apagar.
B. Producción¶
Todo es nuevo y aditivo (el plan de producción es 30 recursos a crear, 0 a cambiar, 0 a destruir; al REST existente solo se le agrega una ruta), salvo el permiso y el estado en la Step. Orden:
- Webhook de Slack del canal
#logigho-alertas-prod(Slack → Apps → Incoming Webhooks). Cifrarlo (A3). - Índices en DocumentDB (túnel SSH al bastion, ver la memoria de conexiones):
los mismos tres
createIndexde A2 sobre la baseLogighoDBde DocumentDB (versión 5.0):
use LogighoDB
db.SeguimientoNovedadesInter.createIndex({ Numeropreenvio: 1 }, { name: "ux_numeropreenvio", unique: true })
db.SeguimientoNovedadesInter.createIndex({ "Solicitud.Ref": 1 }, { name: "ix_solicitud_ref" })
db.SeguimientoNovedadesInter.createIndex({ EstadoSeguimiento: 1 }, { name: "ix_estado_seguimiento" })
db.SeguimientoNovedadesInter.getIndexes()
environments/prod/novedades), con las credenciales de producción. En PowerShell:
$env:AWS_PROFILE = "<perfil prod>" # cuenta 522814697657
aws sts get-caller-identity --query Account --output text # debe imprimir 522814697657
terraform -chdir=environments/prod/novedades init
terraform -chdir=environments/prod/novedades plan "-out=novedades.tfplan"
Plan: 30 to add, 0 to change, 0 to destroy (lambda, rol, alarmas, dashboard, SNS, rol OIDC y la
ruta /webhooks/ws-inter/flujo-guia con su API key). No debe tocar nada existente del REST API_LogiGho_Rest: solo
le agrega recursos nuevos. Si es correcto: terraform -chdir=environments/prod/novedades apply novedades.tfplan y
confirma el correo de SNS. La Lambda queda en la VPC/subred/SG de ApiLambdaProcesoAutomaticoInter (ya tiene salida a
internet por NAT y acceso a DocumentDB).
Terraform solo crea la ruta; todavía no está publicada en el stage. Se publica en el paso siguiente.
3b. Publicar el deployment del REST (el stage Produccion no es de Terraform, igual que hace el pipeline de datos).
Antes de publicar, anota el deployment actual (para revertir) y revisa que no haya cambios manuales sin publicar
de otras personas en API_LogiGho_Rest, porque create-deployment publica TODO lo pendiente del API:
aws apigateway get-stage --rest-api-id 7elgyten88 --stage-name Produccion --query deploymentId --output text # anotar (hoy: r5pecy)
aws apigateway create-deployment --rest-api-id 7elgyten88 --stage-name Produccion --description "novedades ws-inter"
aws apigateway update-stage --rest-api-id 7elgyten88 --stage-name Produccion --patch-operations op=replace,path=/deploymentId,value=<deployment anotado>.
Al ser un REST edge (CloudFront), la ruta tarda unos minutos en propagar: mientras tanto responde
403 {"message":"Missing Authentication Token"}.
4. Variable group novedades-inter-prod-secretos (mismas variables que A3 más SLACK_WEBHOOK_ALERTAS) y service
connection aws-prod-novedades (rol azdo-novedades-prod).
5. Merge a main → cd-prod (pide aprobación en el Environment produccion).
6. Primera corrida acotada: antes de tocar la Step, pon el tope en 50 guías:
export AWS_PROFILE=<perfil prod> # cuenta 522814697657
MAX_GUIAS_POR_CORRIDA=50 python3 pipelines/scripts/lambda_release.py variables \
--funcion ApiLambdaNovedadesInter --claves MAX_GUIAS_POR_CORRIDA
export AWS_PROFILE=<perfil prod>
python3 pipelines/novedades/scripts/agregar_novedades_a_step_function.py ensayo
python3 pipelines/novedades/scripts/agregar_novedades_a_step_function.py aplicar
aplicar guarda respaldo-step-<fecha>.json, agrega al rol de la Step una política que le permite invocar solo
ApiLambdaNovedadesInter (sin ella el paso falla con AccessDenied y el Catch lo oculta) e inserta el estado después
de Lambda Pedidos Inter. Para deshacerlo: … revertir --archivo respaldo-step-<fecha>.json.
8. Vigila la siguiente corrida de la Step (cada 3 h) o lanza una ejecución manual: logs, dashboard
Novedades-Inter-prod, Slack. Verifica también que $push con $slice funciona en DocumentDB (el historial se llena).
9. Entrega al proveedor la URL de producción y su API key, y sube el tope:
python3 pipelines/scripts/lambda_release.py quitar-variables --funcion ApiLambdaNovedadesInter --claves MAX_GUIAS_POR_CORRIDA
C. Operación¶
Cambiar un parámetro de ajuste o rotar un secreto¶
La fusión de variables del pipeline es aditiva: no cambia una variable que ya existe con otro valor. Para cambiar una:
quitar-variables --claves NOMBRE y luego variables (o redesplegar). Para rotar la API key del webhook:
terraform apply -replace=module.novedades_webhook.aws_api_gateway_api_key.ws_inter (en preprod/datos o prod/novedades; en producción hay que publicar de nuevo el deployment), cifrar la nueva, actualizar el variable
group, quitar-variables + redespliegue y entregarla al proveedor.
Si llega una alerta¶
Ver la tabla de observabilidad. La más importante, ws-inter NO responde: llamar al proveedor; la corrida se reintenta sola cada 3 h y nada se pierde (las guías pendientes se envían cuando vuelva).
Reversión¶
- Código: el pipeline imprime el comando de reversión (respaldo en
s3://logigho-artefactos-<env>/respaldo/ApiLambdaNovedadesInter/). - Step de producción:
agregar_novedades_a_step_function.py revertir --archivo …. - Apagar solo esta función sin tocar nada más: en la Step, quitar el estado con
revertir, o dejar el disparador de PreProd deshabilitado. MotivoNovedadInterenPedidosInteres un campo extra: no rompe nada si se deja.
D. Historia 027: distancias y reportes¶
Qué se enciende y en qué orden para las dos funciones nuevas (ApiLambdaNovedadesInterDistancias y ApiLambdaNovedadesInterReportes).
Nada se ejecuta solo: Terraform, el pipeline y los scripts los lanza una persona. PreProd está hecha y validada (2026-11-06).
Producción: todo lo de abajo está pendiente y cada paso es una escritura; en prod se avanza paso a paso con el OK de Iker.
| Pieza | Dónde vive | Quién la crea |
|---|---|---|
| 2 funciones, roles, logs, 4 alarmas, Scheduler | modules/novedades-inter desde environments/<env>/novedades |
terraform apply (Iker) |
Ruta POST /novedades-inter/reportes/slack |
modules/novedades-reportes-slack; en PreProd desde environments/preprod/datos, en prod desde environments/prod/novedades |
terraform apply (Iker); en prod el deployment lo publica el CLI |
| Rama de Distancias en la Step | PreProd: environments/preprod/procesos-automaticos. Prod: pipelines/novedades/scripts/agregar_distancias_a_step_function.py |
PreProd: Terraform. Prod: script (Iker) |
| Código y variables | pipelines/novedades/{cd-preprod,cd-prod}.yml (lista de 3 funciones) |
Pipeline de Azure DevOps |
| App de Slack y comando | App de Slack | Iker (consola de Slack) |
| Índices | Sección D3 | mongosh (Iker; en PreProd puede la IA) |
D1. Orden de puesta en marcha¶
- Terraform
novedades(environments/<env>/novedades): crea las dos funciones, sus roles (Reportes con permiso de autoinvocarse), logs, las 4 alarmas, el rol de despliegue con las 3 funciones y el Scheduler. El Scheduler nace apagado en ambos entornos (reportes_programados_habilitados = false). Revisar el plan: solo recursos nuevos. - Ruta del comando de Slack. PreProd:
environments/preprod/datos(terraform output novedades_url_comando_slack). El orden seguido en PreProd fuenovedades,datos,procesos-automaticos(spec 012, estado 2026-11-06). Discrepancia: el comentario deenvironments/preprod/datos/main.tfdice «aplicar ANTES environments/preprod/novedades»; la ruta apunta a la función por nombre, así que lo seguro es que la función exista primero. Prod: viene enenvironments/prod/novedades(terraform output url_comando_slack). En prod, antes del apply, confirmar que el REST7elgyten88no tenga ya un recurso/novedades-inter(el módulo del webhook y el de la ruta de Slack lo declaran por separado: si choca, hay que importarlo o pasar su id). En prod, anotar el deployment actual del stage y publicar con el CLI (sección B, 3b); reversión conupdate-stage. - Terraform
procesos-automaticos(PreProd): rama nueva enStep_Procesos_Logigho. En prod se usa el script de la sección D5. - Crear la App de Slack y el comando con la URL del paso 2 (App de Slack); sacar el token del bot y el signing secret, cifrarlos con AES (A3) y guardarlos en el variable group.
- Variable group
novedades-inter-<env>-secretos: agregar las variables nuevas (D2). - CD de las 3 funciones (
cd-preprod.ymldesde una ramarelease/*;cd-prod.ymldesdemaincon aprobación del Environmentproduccion). Publica el zip una sola vez, respalda el código actual de cada función, agrega las variables sensibles (aditivo), publica y verifica. - Índices (D3) y, en prod, verificar con
explainla lectura de pendientes sobre DocumentDB antes de liberar. - Relleno: las corridas de Distancias lo hacen solas por tandas de
MAX_GUIAS_DISTANCIA_POR_CORRIDA(1500). Para forzar una: Step Functions,Start execution, o invocar la función con{"origen":"step"}. En producción el relleno cubre todas las novedades (Iker 2026-11-06). VigilarLlamadasGoogle,PendientesPorTopey el costo en Google. - Probar el comando (
/reporte-novedades, en PreProd/reporte-novedades-pruebas) y verificar que llegan los 2 archivos al canal. - Encender el Scheduler (solo prod, Iker 2026-11-06): segundo
applyconreportes_programados_habilitados = true, cuando el pipeline ya publicó código y variables. Verificar la expresióncron(0 8 ? * TUE,FRI *)enAmerica/Bogota.
D2. Variables nuevas del variable group (solo nombres)¶
| Variable | ¿Cifrada? | Función | Notas |
|---|---|---|---|
GOOGLE_MAPS_API_KEY |
Sí (AES) | Distancias | Llave de servidor (Geocoding + Routes); con tope diario de cuotas en GCP |
SLACK_BOT_TOKEN |
Sí (AES) | Reportes | Token del bot de la App «LogiGho» |
SLACK_SIGNING_SECRET |
Sí (AES) | Reportes | Valida la firma del comando |
SLACK_CANAL_REPORTES |
No | Reportes | ID del canal (C…), uno por entorno |
SLACK_USUARIOS_PERMITIDOS |
No | Reportes | IDs de usuario de Slack separados por ; o , |
SLACK_WEBHOOK_ALERTAS |
Sí (AES) | Distancias (prod) y función original | Opcional en PreProd; en prod el CD se la pasa a Distancias y a la función original |
EVIDENCIAS_SECRETO_FIRMA |
Sí (AES256) | Reportes | v8. Clave HMAC de los enlaces de imágenes; ver D9 |
URL_EVIDENCIAS |
No | Reportes | v8. URL https de GET /novedades/evidencia (salida url_evidencias de Terraform), sin query |
EVIDENCIAS_BUCKET |
No | Reportes | v8. Bucket de las fotos (wsinter-evidencias-prod en prod) |
MAX_GUIAS_DISTANCIA_POR_CORRIDA, CONCURRENCIA_GOOGLE, FALLAS_SEGUIDAS_PARA_CORTAR, MOTIVOS_EXCLUIDOS_REPORTE2, ZONA_HORARIA |
No | Opcionales | Tienen valor por defecto en el código; el CD no las pasa |
- El CD pasa a cada función solo las claves que le corresponden (
claves:en el YAML). Las variables son aditivas: para cambiar una ya publicada,quitar-variablesy volver a correr el CD. - Los valores nunca se escriben en la documentación ni en git.
- Observado: el CD de prod no pasa
SLACK_WEBHOOK_ALERTASa Reportes (el código de Reportes la lista como opcional, peroclavesno la incluye). Elaws-lambda-reportes.jsonla menciona. Revisar si se desea alerta inmediata desde Reportes (hoy sus avisos van por el bot al canal).
D3. Índices (mejora M-256)¶
use LogighoDB
db.CandadosNovedadesInter.createIndex({ ExpiraEn: 1 }, { name: "ttl_expira_en", expireAfterSeconds: 0 })
db.ReportesNovedadesInter.createIndex({ Estado: 1, FechaInicio: -1 }, { name: "ix_estado_fecha_inicio" })
// Solo si el explain de la selección de pendientes lo pide:
// db.SeguimientoNovedadesInter.createIndex({ HuellaMotivos: 1 }, { name: "ix_huella_motivos" })
Los nombres de índice son una propuesta (la mejora M-256 fija las claves, no los nombres). Si el índice TTL no existe, el candado igual funciona (el código comprueba el vencimiento). En prod los crea Iker; en PreProd puede hacerlo la IA.
D4. La Step en PreProd¶
La rama de PreProd llama a ApiLambdaNovedadesInterDistancias con {"origen":"step"}, TimeoutSeconds: 330 y un Catch que termina en éxito. El rol de la Step de PreProd
puede invocar las dos funciones (observado: step_procesos_logigho.tf).
D5. Step de producción (script, lo ejecuta Iker)¶
export AWS_PROFILE=<perfil prod>
python3 pipelines/novedades/scripts/agregar_distancias_a_step_function.py ensayo # no escribe nada
python3 pipelines/novedades/scripts/agregar_distancias_a_step_function.py aplicar # respaldo + política IAM + rama nueva en 'Parallel Init'
# reversión:
python3 pipelines/novedades/scripts/agregar_distancias_a_step_function.py revertir --archivo respaldo-step-<fecha>.json
aplicar guarda el respaldo, agrega una política (InvocarLambdaNovedadesInterDistancias) que solo permite invocar esa función y añade la rama con Retry y un Catch que cae en
un Pass que termina la rama en éxito. Antes deben existir la función (Terraform) y su primer despliegue.
D6. Operación de las funciones nuevas¶
- Reporte a mano: el comando de Slack o invocar
ApiLambdaNovedadesInterReportescon{"origen":"programado"}. El comando solo funciona para los IDs deSLACK_USUARIOS_PERMITIDOS. - Candado ocupado: si Distancias devuelve
CandadoOcupado, hay otra corrida vigente; el candado vence solo a los 15 min. - Cambiar la regla de geocodificación: subir
VersionReglaGeocodificacion.Actualrecalcula todo una vez; avisar antes del costo en Google. SubirVersionReglaRuta.Actualrecalcula solo las rutas (sin geocodificar). - Argumentos del comando (v6):
/reporte-novedades completoy/reporte-novedades desde AAAA-MM-DDcambian qué es «Nuevas»; un argumento inválido responde la ayuda y no genera nada. - Empezar los reportes de cero:
tools/reportes-novedades/limpiar_ejecuciones_reportes.py(lo ejecuta Iker) borraReportesNovedadesInter.
D7. Reversión¶
| Qué | Cómo |
|---|---|
| Reportes programados | Scheduler a DISABLED (reportes_programados_habilitados = false y apply) o desde la consola. El comando de Slack sigue funcionando |
| Rama de Distancias | PreProd: quitar la rama en Terraform. Prod: agregar_distancias_a_step_function.py revertir |
| Código | El CD imprime el comando de reversión de cada función (respaldo en s3://logigho-artefactos-<env>/respaldo/<función>/) |
| Ruta del comando | Prod: update-stage al deployment anterior anotado |
| Columna en el front | Revert del PR del front |
| Campos nuevos en Mongo | No afectan a nadie; se pueden ignorar o borrar con $unset (lo hace Iker) |
D8. Reprocesar por tandas (backfill)¶
Cuándo: después de subir una versión de regla, de agregar un campo que se completa en lo ya procesado (como DireccionMensajero, v8) o si quedaron guías Error/pendientes. No es otro proceso: Distancias ya selecciona
las guías pendientes (huella distinta, mínimo por evaluar o falta la dirección del mensajero) y las atiende por tandas. Cada paso en prod es una escritura en Mongo y gasta Google: Iker lo ejecuta, con su OK por paso.
- Medir antes (solo lectura): contar pendientes con el script de lectura del workspace (
tools/db-lectura, siempre con--proyeccion, sin datos personales) y estimar el costo (referencia: ~8 100 geocodificaciones inversas ≈ USD 40 una vez; ~3 600 rutas por la recarga de la v6). - Revisar topes:
MAX_GUIAS_DISTANCIA_POR_CORRIDAes 1 500 por defecto (la tanda); el presupuesto de una corrida es 240 s y la función tiene 300 s. Si Google corta por cuota (M-268), bajarCONCURRENCIA_GOOGLE(4 por defecto) antes de seguir. - Lanzar una tanda: Step Functions
Start executioncon{}, o invocarApiLambdaNovedadesInterDistanciascon{"modo":"backfill"}(el modo solo queda anotado en el log; la selección es la misma). Ejemplo con el CLI:
aws lambda invoke --function-name ApiLambdaNovedadesInterDistancias --payload '{"modo":"backfill"}' --cli-binary-format raw-in-base64-out salida-distancias.json
- Leer el resumen (
[RESULT] fino el JSON de salida):GuiasSeleccionadas,GuiasProcesadas,GuiasConError,PendientesPorTope,PendientesPorTiempo,LlamadasGoogle,CorridaCortada,CandadoOcupado. - Repetir por tandas de 1 500 hasta que
PendientesPorTopeyPendientesPorTiemposean 0. Si saleCandadoOcupado, hay otra corrida vigente: esperar (el candado vence solo a los 15 min). SiCorridaCortada, revisar la llave, las cuotas y el aviso de Slack antes de reintentar. - Comprobar idempotencia (CA5): una corrida extra debe dar
LlamadasGoogle = 0.
Reversión: los campos nuevos no afectan a nadie; se pueden ignorar o borrar con $unset (lo hace Iker).
D9. Rotar EVIDENCIAS_SECRETO_FIRMA¶
Efecto: invalida todos los enlaces de imagen de los Excel ya enviados (responden 403 hasta que se regeneren los reportes). El valor nunca se imprime, se pega en el chat ni va a git ni a docs/.
Mejora M-274: evaluar una segunda clave «anterior» para rotar sin romper los Excel viejos (hoy no existe: hipótesis de diseño, no implementada).
- Avisar a quienes usan los reportes: los Excel viejos perderán las imágenes; los nuevos funcionarán.
- Generar el valor nuevo en tu máquina con un generador seguro y cifrarlo con AES256 igual que los demás secretos (sección A3), sin mostrarlo en pantalla ni en el historial del terminal.
- Variable group
novedades-inter-prod-secretos: reemplazarEVIDENCIAS_SECRETO_FIRMApor el valor cifrado. - Publicar: las variables del pipeline son aditivas, así que se aplica
quitar-variablesy se vuelve a correr el CD de las 3 funciones (cd-prod.ymldesdemain, con aprobación del Environmentproduccion) para que la función de Reportes reciba la clave nueva. - Verificar sin imprimir valores: generar un reporte (
/reporte-novedades) y abrir un «Ver imagen» del archivo nuevo (debe redirigir a la foto). Un enlace de un Excel anterior debe dar 403 (Prohibido), y sin parámetros 400. - Reversión: volver a poner el valor anterior en el variable group y repetir el paso 4 (los Excel viejos vuelven a abrir). Si el valor anterior no se guardó cifrado en un lugar seguro, no hay reversión: guardarlo antes del paso 3.