Con las etiquetas activadas y el informe de costes y uso entregándose cada día en mercadofresco-informes-analitica, MercadoFresco ya puede repartir su factura. Falta lo otro: mirarla de verdad. No el total, no una tabla resumida, sino el desglose completo por servicio, entrar en las tres o cuatro líneas que casi nadie entiende, y salir de ahí con una lista de acciones concretas y su ahorro calculado.

Esta lección hace ese recorrido. Verás qué es Cost Explorer y con qué datos trabaja, los conceptos de facturación que hay que entender antes de mirar un gráfico —porque si no, los números no cuadran y se pierde la confianza en la herramienta—, la factura real de MercadoFresco servicio por servicio hasta los 2.237,60 USD, las tres sorpresas que aparecen casi siempre, la detección de anomalías, las recomendaciones automáticas y su relación con Compute Optimizer y Trusted Advisor, la consulta desde boto3 para publicar el gasto junto al negocio, y las diez optimizaciones que MercadoFresco ejecuta con su ahorro una por una.

Aviso de coste. La interfaz de Cost Explorer es gratuita. Lo que sí cuesta es la API: cada llamada paginada a GetCostAndUsage y compañía se factura a 0,01 USD. Un panel que consulte la API cada cinco minutos son unos 90 USD al mes, un error caro y sorprendentemente frecuente. La detección de anomalías es gratuita. Datos, cuentas e identificadores ficticios; los precios son orientativos y varían por región y fecha.

Contenido

  1. Qué es Cost Explorer y con qué datos trabaja
  2. Conceptos de facturación: no combinado, amortizado y neto
  3. Cargos, créditos, reembolsos e impuestos: por qué la suma no cuadra
  4. Facturación consolidada entre las seis cuentas
  5. La factura de MercadoFresco, servicio por servicio
  6. Sorpresa 1: los NAT Gateway
  7. Sorpresa 2: la transferencia de datos entre zonas
  8. Sorpresa 3: CloudWatch
  9. Filtros, agrupaciones e informes guardados
  10. El panel de coste que revisa Marta cada mes
  11. Detección de anomalías de coste
  12. El caso de la carga nocturna a Redshift
  13. Recomendaciones de reducción y recursos huérfanos
  14. Compute Optimizer y Trusted Advisor
  15. Previsión de gasto y cómo interpretarla
  16. Consultar Cost Explorer desde boto3
  17. Publicar el gasto diario como métrica de negocio
  18. Las diez optimizaciones de MercadoFresco
  19. Errores comunes y consejos
  20. Ejercicios
  21. Conclusión

Qué es Cost Explorer y con qué datos trabaja

AWS Cost Explorer es la herramienta de análisis interactivo de la factura: gráficos, filtros, agrupaciones y previsiones sobre el gasto y el uso. Se activa una vez desde la cuenta de gestión y, a partir de ese momento, empieza a preparar los datos.

Lo que hay que saber antes de fiarse de un número:

Característica Detalle Consecuencia práctica
Histórico 13 meses hacia atrás por defecto, ampliable a 38 Permite comparar con el mismo mes del año anterior
Granularidad mensual y diaria Disponible en todo el histórico Suficiente para el 90 % del análisis
Granularidad horaria Opcional, de pago (unos 0,01 USD por 1.000 registros consultados), con 14 días de retención Imprescindible para el pico del viernes y para 11-05
Retraso de actualización Hasta 24 horas, a veces 48 al cierre del mes El gasto de hoy no está completo; comparar días parciales induce a error
Previsión Hasta 12 meses hacia delante Útil con matices; ver más abajo
Datos a nivel de recurso Opcional, 14 días Cuando hace falta más, se va al CUR (11-02)
Coste de la interfaz Gratuita La API sí cuesta: 0,01 USD por petición

La primera regla operativa que evita disgustos: nunca saques conclusiones del día en curso. Con el retraso de actualización, el gasto de hoy siempre parece menor de lo que será, y más de un equipo ha celebrado un ahorro que era simplemente un dato incompleto.

Conceptos de facturación: no combinado, amortizado y neto

Antes de mirar un gráfico hay que entender qué está midiendo, porque Cost Explorer ofrece varias métricas de coste y dan resultados distintos para el mismo mes. Es la causa número uno de desconfianza en la herramienta.

Métrica Qué mide Cuándo usarla
Coste no combinado (unblended) El coste tal y como se factura, cuando se factura Cuadrar con la factura del mes; el valor por defecto
Coste amortizado (amortized) Reparte los pagos por adelantado de reservas y Savings Plans a lo largo del periodo que cubren Analizar el coste real de operar; imprescindible con compromisos
Coste neto no combinado (net unblended) Igual que el no combinado, pero descontando descuentos y créditos Ver lo que realmente se paga
Coste neto amortizado (net amortized) Amortizado y con descuentos aplicados La métrica más fiel para el seguimiento a largo plazo
Coste combinado (blended) Promedio de tarifas entre cuentas de la organización Casi nunca; existe por razones históricas

La diferencia se ve mejor con un ejemplo que MercadoFresco vivirá en 11-05. Supongamos un Savings Plan de 1 año con pago total por adelantado de 1.200 USD contratado el 1 de marzo:

Mes Coste no combinado Coste amortizado
Marzo 1.200 USD (todo el pago) 100 USD
Abril 0 USD 100 USD
Mayo 0 USD 100 USD

Con el coste no combinado, el gráfico muestra un pico enorme en marzo y una caída a cero después, lo que es cierto para la tesorería y absolutamente inútil para analizar la eficiencia. Con el amortizado, cada mes carga los 100 USD que le corresponden y el gráfico refleja el coste real de operar.

La recomendación práctica: usa el no combinado para cuadrar con la factura y el neto amortizado para analizar. Y di siempre cuál estás usando cuando presentes un número, porque dos personas mirando la misma pantalla con métricas distintas discutirán durante media hora sin darse cuenta de que ambas tienen razón.

MercadoFresco, que todavía no tiene ningún compromiso comprado, ve exactamente el mismo número en las cuatro métricas. Eso cambia en 11-05, y conviene saberlo de antemano.

Cargos, créditos, reembolsos e impuestos: por qué la suma no cuadra

La segunda fuente de desconfianza es que la suma de Cost Explorer no coincide con el importe cobrado en la tarjeta. No es un error: es que la factura contiene tipos de línea que Cost Explorer, por defecto, filtra o muestra por separado.

Tipo de línea Qué es ¿Aparece por defecto?
Usage Consumo real de un servicio
Tax Impuestos (IVA, en el caso español) No, se excluye por defecto
Credit Créditos promocionales, de programas o de compensación Se puede incluir o excluir
Refund Devoluciones por errores o ajustes Se puede incluir o excluir
RIFee / SavingsPlanUpfrontFee Cuota de una reserva o de un Savings Plan Sí, con matices según la métrica
Support Cuota del plan de soporte
Enterprise Discount Descuento negociado Solo en las métricas «netas»

La factura de MercadoFresco de agosto, completa:

Coste de servicios (Usage) ...................... 2.237,60 USD
Créditos aplicados .............................. -   45,00 USD  (créditos de activación)
Soporte (plan Basic) ............................       0,00 USD
Subtotal ........................................ 2.192,60 USD
Impuestos (IVA 21 %) ............................ +  460,45 USD
------------------------------------------------------------
Total cobrado ................................... 2.653,05 USD

De ahí salen dos reglas que conviene fijar en el equipo:

  1. El número de trabajo es el coste de servicios: 2.237,60 USD. Es el que se puede reducir con decisiones de ingeniería. Los impuestos no se optimizan, se pagan.
  2. Los créditos engañan. Mientras duren, el gasto parece menor de lo que es, y el día que se agotan aparece un salto que nadie ha causado. MercadoFresco los excluye del análisis y los trata como lo que son: un descuento temporal.

Facturación consolidada entre las seis cuentas

La organización o-a1b2c3d4e5 tiene facturación consolidada activada, que es el comportamiento por defecto de AWS Organizations (09-04). Implica tres cosas que afectan directamente a este análisis:

  • Una sola factura y un solo método de pago, emitidos desde la cuenta de gestión 999988887777. Las cuentas miembro no reciben factura propia.
  • Agregación de uso para los tramos por volumen. Los 40 GB de S3 de producción, los 12 de preproducción y los 8 de desarrollo cuentan como 60 GB a efectos de tramos de precio. Con volúmenes pequeños el ahorro es simbólico, pero con transferencia de datos o S3 a gran escala llega a ser relevante.
  • Los compromisos se comparten. Un Savings Plan comprado en cualquier cuenta cubre el uso de todas las demás, salvo que se desactive la compartición. Es un punto central de 11-05.

En Cost Explorer, la cuenta de gestión ve todo; una cuenta miembro solo se ve a sí misma, y únicamente si el acceso está habilitado. Marta trabaja siempre desde la cuenta de gestión con el rol de solo lectura de facturación, y Luis y Sara ven su propia cuenta.

La factura de MercadoFresco, servicio por servicio

Este es el desglose completo del mes de agosto, agrupado por servicio, con coste no combinado y las seis cuentas consolidadas:

# Servicio USD/mes % Qué es exactamente
1 Amazon Aurora (RDS) 342,60 15,3 % aurora-mercadofresco-pedidos: escritor + 2 lectores, almacenamiento, E/S, copias; más preproducción y desarrollo
2 Amazon ECS – Fargate 262,40 11,7 % svc-mercadofresco-tienda-fg arm64 y -trabajadores con Spot, en 3 entornos
3 NAT Gateway 243,80 10,9 % 6 NAT (2 por entorno): cargo por hora + datos procesados
4 Amazon CloudWatch 214,90 9,6 % Registros, métricas personalizadas, Container Insights, paneles, alarmas, canario
5 Amazon ElastiCache 135,40 6,1 % mercadofresco-catalogo: primario + réplica, más un nodo pequeño en preproducción
6 Amazon S3 128,90 5,8 % 5 buckets: fotos, informes, registros web, copias, artefactos
7 VPC: endpoints y transferencia entre AZ 118,60 5,3 % 4 endpoints de interfaz × 2 AZ + tráfico cruzado entre zonas
8 Amazon Redshift Serverless 104,50 4,7 % wg-mercadofresco-analitica: RPU-hora y almacenamiento gestionado
9 Elastic Load Balancing 104,20 4,7 % alb-mercadofresco-tienda en 3 entornos: cargo fijo + unidades de capacidad
10 AWS Config 74,60 3,3 % grabador-mercadofresco en 6 cuentas + 29 reglas
11 Amazon CloudFront 62,80 2,8 % Distribución E2QWERTY123ABC: transferencia por encima del tramo gratuito
12 Amazon DynamoDB 58,40 2,6 % mercadofresco-carritos e -idempotencia: bajo demanda + PITR
13 AWS Backup e instantáneas 46,80 2,1 % Copias de Aurora, EBS y DynamoDB, con copia entre regiones
14 AWS Lambda 41,20 1,8 % Las 6 funciones del curso: GB-segundo e invocaciones
15 Amazon GuardDuty 38,60 1,7 % Análisis de eventos en las 6 cuentas
16 AWS KMS 34,60 1,5 % alias/mercadofresco-datos y peticiones de cifrado
17 Amazon EC2 y EBS (residual) 33,90 1,5 % Un bastión olvidado, 3 volúmenes sueltos, 2 IP elásticas
18 AWS WAF 31,20 1,4 % waf-mercadofresco-cdn y -alb: Web ACL, reglas y peticiones
19 Mensajería (SQS, SNS, EventBridge, Step Functions) 27,50 1,2 % Las colas, el tema, el bus y la máquina de estados
20 Herramientas de desarrollo (CodeBuild, Pipeline, Deploy, ECR) 26,40 1,2 % Minutos de compilación, pipelines activos y 42 GB de imágenes
21 Transferencia de datos a internet (fuera de CloudFront) 24,80 1,1 % Salidas directas desde el ALB y desde las tareas
22 Amazon Inspector 21,40 1,0 % Escaneo continuo de imágenes de ECR
23 AWS CloudTrail 18,70 0,8 % trail-mercadofresco, eventos de datos acotados e Insights
24 Amazon Route 53 12,40 0,6 % Zona alojada, consultas y comprobaciones de salud
25 AWS X-Ray 10,60 0,5 % Trazas con muestreo optimizado
26 Otros (Athena, Chatbot, Systems Manager, API de Cost Explorer) 9,80 0,4 % Servicios de importe menor
27 Secrets Manager y Parameter Store 8,60 0,4 % 2 secretos con rotación y parámetros avanzados
Total 2.237,60 100 %

Lo primero que hay que hacer con una tabla así es leerla al revés de como la mira todo el mundo. La reacción típica es fijarse en Aurora, que es la línea mayor, y empezar a discutir si hacen falta dos lectores. Pero Aurora está ahí por una decisión consciente, documentada y firmada por gerencia (ADR-014 de 11-01). Lo interesante son las líneas que nadie decidió: el NAT, la transferencia entre zonas, CloudWatch y el EC2 residual. Suman 611,20 USD al mes, un 27,3 % de la factura, y ninguna de ellas ha sido nunca objeto de una decisión explícita.

Sorpresa 1: los NAT Gateway

243,80 USD al mes, la tercera línea de la factura, por un componente que nadie recuerda haber elegido. Es el hallazgo más repetido en todas las revisiones de coste del sector.

El NAT Gateway se factura por dos conceptos:

Concepto Precio aproximado en eu-west-1 Comentario
Cargo por hora ~0,045 USD/h ≈ 33 USD al mes por NAT Se paga aunque no pase un solo byte
Datos procesados ~0,045 USD/GB Se paga por los datos en ambos sentidos

El desglose de MercadoFresco:

Entorno NAT Cargo fijo Datos procesados Total
Producción 2 (uno por AZ) 66,00 USD 34,00 USD (756 GB) 100,00 USD
Preproducción 2 66,00 USD 8,00 USD (178 GB) 74,00 USD
Desarrollo 2 66,00 USD 3,80 USD (85 GB) 69,80 USD
Total 6 198,00 USD 45,80 USD 243,80 USD

Dos observaciones que cambian la conversación:

  1. El 81 % del coste es el cargo fijo por hora, no el tráfico. Optimizar el tráfico no arregla el problema; reducir el número de NAT sí.
  2. Preproducción y desarrollo pagan 143,80 USD al mes por salir a internet, en entornos donde no hay un solo cliente y donde una hora sin salida a internet no le importa a nadie. Dos NAT en desarrollo son alta disponibilidad para un entorno que nadie considera crítico.

Y hay una tercera observación que conecta con 10-02: buena parte de los 756 GB de producción son descargas de imágenes de ECR, llamadas a la API de S3 y envío de registros a CloudWatch, es decir, tráfico hacia servicios de AWS que podría no pasar por el NAT si hubiera endpoints. MercadoFresco ya puso cuatro endpoints del camino crítico; el análisis pendiente es si compensa poner más, y la respuesta —como se vio en 10-02— es que con siete endpoints en dos AZ salen más caros que el NAT.

Sorpresa 2: la transferencia de datos entre zonas

Dentro de los 118,60 USD de la línea de VPC hay dos cosas muy distintas:

Concepto Coste Naturaleza
4 endpoints de interfaz × 2 AZ 64,20 USD Cargo fijo por hora y por AZ
Transferencia de datos entre AZ 54,40 USD ~0,01 USD/GB en cada sentido

La transferencia entre zonas es el coste más invisible de AWS, porque no tiene un recurso al que culpar: no aparece bajo ninguna etiqueta, no hay un panel que la muestre y no se puede apagar. Aparece sola en cuanto una arquitectura es Multi-AZ, que es justo lo que se recomienda por fiabilidad.

De dónde salen esos 54,40 USD en MercadoFresco:

  • El ALB reparte entre dos AZ. Con cross-zone load balancing activado —que en un ALB está siempre activo y es gratuito para ALB, pero no para NLB— una petición que llega a la AZ a puede acabar en una tarea de la AZ b.
  • Aurora replica del escritor a los dos lectores, y uno de ellos está en la otra zona. Cada byte escrito cruza la zona.
  • ElastiCache replica del primario a la réplica, que está en la otra AZ.
  • Las tareas de Fargate leen del escritor de Aurora, que está en una zona concreta; la mitad de las tareas cruzan.

Y aquí viene lo importante: casi todo ese coste es el precio de la alta disponibilidad, y no debe eliminarse. Este es el caso ejemplar del compromiso entre pilares de 11-01: se podría ahorrar concentrando todo en una zona, y se perdería exactamente la propiedad por la que se montó Multi-AZ. Lo que sí tiene sentido es reducir el cruce innecesario: dirigir las lecturas al lector de la misma zona cuando se pueda, y no mover volúmenes grandes de datos entre zonas por costumbre.

La acción correcta con esta línea no es recortarla, sino saber que existe, entenderla y no descubrirla el día que la factura suba un 40 % por un cambio de topología.

Sorpresa 3: CloudWatch

214,90 USD, cuarta línea de la factura. Es la sorpresa que más incomoda, porque la observabilidad es una virtud y aquí aparece como un gasto considerable. El desglose:

Concepto de CloudWatch Coste Origen
Ingesta de registros 118,40 USD ~61 GB/mes a ~0,50 USD/GB (Logs Standard)
Almacenamiento de registros 34,60 USD ~1,1 TB acumulados: la retención nunca se configuró
Métricas personalizadas 27,00 USD 90 métricas × 0,30 USD
Container Insights 18,60 USD Métricas por tarea y contenedor
Alarmas 8,40 USD 84 alarmas × 0,10 USD
Paneles 6,00 USD 2 paneles por encima de los 3 gratuitos, más versiones antiguas
Canario de Synthetics 1,90 USD Comprobación cada 5 minutos

Las dos líneas que dominan son ingesta y almacenamiento de registros, y ambas tienen la misma raíz: nadie decidió nunca cuánto retener ni qué registrar. Concretando:

  • Las aplicaciones registran en nivel DEBUG en preproducción y en producción, porque se activó para depurar un incidente en abril y no se volvió a bajar.
  • Los registros de acceso del ALB y los del WAF van a CloudWatch Logs además de a S3, duplicando el coste.
  • Ningún grupo de registros tiene retentionInDays configurado, lo que significa retención indefinida. Un grupo creado hace un año sigue guardando todo.

Esta es la partida con mejor relación entre esfuerzo y ahorro de toda la factura, y aparece en la lista de optimizaciones más abajo.

Filtros, agrupaciones e informes guardados

La utilidad de Cost Explorer está en cruzar dimensiones. Las agrupaciones disponibles y para qué sirve cada una:

Agrupar por Responde a Uso típico en MercadoFresco
Servicio ¿En qué gastamos? La tabla anterior; el punto de partida
Cuenta vinculada ¿Qué entorno gasta? Producción 66 %, preproducción 18 %, desarrollo 11 %
Región ¿Dónde gastamos? Detectar recursos olvidados en otras regiones
Tipo de uso (usage type) ¿Qué concreto dentro del servicio? Separar NatGateway-Hours de NatGateway-Bytes
Tipo de cargo (charge type) ¿Uso, impuesto, crédito o cuota? Cuadrar con la factura
Etiqueta ¿Qué componente o quién? Componente, Propietario, Entorno (11-02)
Categoría de coste ¿Qué área de negocio? producto, plataforma, analitica
Familia de instancia / plataforma ¿Qué hardware? Ver cuánto queda en x86 frente a arm64

El tipo de uso es la dimensión más infravalorada y la que resuelve más misterios. «Amazon Virtual Private Cloud: 362,40 USD» no dice nada; agrupado por tipo de uso aparece EUW1-NatGateway-Hours: 198,00, EUW1-NatGateway-Bytes: 45,80, EUW1-VpcEndpoint-Hours: 64,20 y EUW1-DataTransfer-Regional-Bytes: 54,40, y de golpe se sabe exactamente qué hacer.

Los informes guardados son consultas con sus filtros y agrupaciones, con nombre y compartidas en la cuenta de gestión. Los cinco de MercadoFresco:

Informe guardado Configuración Para qué
mf-mensual-por-servicio Mensual, agrupado por servicio, 13 meses La foto general y su tendencia
mf-por-entorno Mensual, agrupado por cuenta vinculada Cuánto se lleva lo no productivo
mf-por-componente Mensual, agrupado por etiqueta Componente La conversación con cada dueño
mf-red Mensual, filtrado a VPC + ELB + CloudFront, agrupado por tipo de uso Vigilar NAT y transferencia
mf-no-productivo-diario Diario, filtrado a las cuentas 2222… y 3333… Detectar lo que se queda encendido

El último es el más útil de los cinco: en una vista diaria de desarrollo, un recurso encendido un sábado se ve a simple vista.

El panel de coste que revisa Marta cada mes

Marta bloquea 45 minutos el día 5 de cada mes —cuando los datos del mes anterior ya están cerrados— y sigue siempre el mismo guion. La disciplina de mirar siempre lo mismo, en el mismo orden, es lo que convierte el ruido en tendencia:

  1. Total del mes frente al anterior y frente al mismo mes del año pasado. Si la variación supera el ±10 %, se explica antes de seguir.
  2. Coste por pedido. Es el primer número que se dice en voz alta, antes que el total (11-02).
  3. Las cinco líneas que más han subido en valor absoluto, no en porcentaje. Un servicio que pasa de 0,40 a 1,20 USD ha subido un 200 % y no importa.
  4. Reparto por entorno. Objetivo declarado: que lo no productivo no supere el 25 % del total.
  5. Coste sin etiquetar. Debe tender a cero; si sube, hay recursos nuevos creados fuera del pipeline.
  6. Anomalías detectadas desde la última revisión y qué se hizo con cada una.
  7. Previsión del mes en curso y comparación con el presupuesto (11-04).
  8. Una acción concreta con dueño y fecha. Solo una. Una reunión mensual que produce doce acciones al año ejecutadas vale más que una que produce cuarenta abandonadas.

Detección de anomalías de coste

Mirar la factura una vez al mes tiene un problema evidente: un error cometido el día 6 se descubre el día 5 del mes siguiente, con treinta días de gasto acumulado. AWS Cost Anomaly Detection cubre ese hueco con aprendizaje automático sobre el patrón histórico de gasto, y es gratuito.

Los conceptos:

  • Un monitor define qué se vigila: todos los servicios, una cuenta, una etiqueta o una categoría de coste.
  • Una suscripción define a quién se avisa, con qué umbral y con qué frecuencia.
  • Los umbrales pueden ser absolutos (más de X USD de impacto) o porcentuales (más de X % sobre lo esperado). Se pueden combinar con AND/OR.

Los tres monitores de MercadoFresco:

# 1. Monitor general por servicio: detecta cualquier servicio que se dispare
aws ce create-anomaly-monitor --anomaly-monitor '{
  "MonitorName": "mf-todos-los-servicios",
  "MonitorType": "DIMENSIONAL",
  "MonitorDimension": "SERVICE"
}'

# 2. Monitor especifico de las cuentas no productivas, mas sensible
aws ce create-anomaly-monitor --anomaly-monitor '{
  "MonitorName": "mf-entornos-no-productivos",
  "MonitorType": "CUSTOM",
  "MonitorSpecification": {
    "Dimensions": {
      "Key": "LINKED_ACCOUNT",
      "Values": ["222233334444", "333344445555"],
      "MatchOptions": ["EQUALS"]
    }
  }
}'

# 3. Suscripcion: avisa a alertas-mercadofresco cuando el impacto supere
#    25 USD absolutos O el 40 % sobre lo esperado
aws ce create-anomaly-subscription --anomaly-subscription '{
  "SubscriptionName": "mf-avisos-coste",
  "MonitorArnList": [
    "arn:aws:ce::999988887777:anomalymonitor/mf-todos-los-servicios",
    "arn:aws:ce::999988887777:anomalymonitor/mf-entornos-no-productivos"
  ],
  "Subscribers": [
    {"Type": "SNS", "Address": "arn:aws:sns:eu-west-1:111122223333:alertas-mercadofresco"}
  ],
  "Frequency": "IMMEDIATE",
  "ThresholdExpression": {
    "Or": [
      {"Dimensions": {"Key": "ANOMALY_TOTAL_IMPACT_ABSOLUTE",
                      "Values": ["25"], "MatchOptions": ["GREATER_THAN_OR_EQUAL"]}},
      {"Dimensions": {"Key": "ANOMALY_TOTAL_IMPACT_PERCENTAGE",
                      "Values": ["40"], "MatchOptions": ["GREATER_THAN_OR_EQUAL"]}}
    ]
  }
}'

Comentarios sobre las decisiones tomadas aquí:

  • MonitorType: DIMENSIONAL con SERVICE crea automáticamente un monitor por cada servicio que se use. Es la opción por defecto sensata y no hay que mantenerla.
  • El segundo monitor existe porque los entornos no productivos tienen un patrón mucho más plano: cualquier subida es sospechosa, mientras que en producción una subida puede ser simplemente un viernes bueno.
  • Frequency: IMMEDIATE solo funciona con SNS; el correo admite DAILY o WEEKLY. Para el aviso inmediato hay que ir por SNS, que además ya está integrado con Chatbot y llega al canal del equipo.
  • Los umbrales combinados con Or evitan los dos fallos clásicos: un umbral solo porcentual dispara constantemente en servicios baratos, y uno solo absoluto no detecta que un servicio pequeño se ha multiplicado por diez.

Un consejo de calibración: empieza con umbrales altos y bájalos. Un detector de anomalías que avisa tres veces por semana se silencia en quince días y ya no sirve para nada.

El caso de la carga nocturna a Redshift

El 14 de agosto a las 09:12, alertas-mercadofresco recibe este aviso:

Anomalía de coste detectada
  Servicio:            Amazon Redshift
  Cuenta:              111122223333
  Impacto total:       68,40 USD
  Coste esperado:      3,10 USD/día
  Coste real:          14,50 USD/día
  Detectada el:        2026-08-14
  Primer día afectado: 2026-08-08

La investigación de Sara sigue tres pasos que sirven de plantilla para cualquier anomalía de coste:

graph TD
  A["Aviso de anomalia<br/>Redshift, +68,40 USD"] --> B["1. Agrupar por TIPO DE USO<br/>en Cost Explorer"]
  B -->|"RPU-Hours"| C["Es computo:<br/>algo se ejecuta de mas"]
  B -->|"Storage"| C2["Son datos:<br/>algo se acumula"]
  C --> D["2. Vista HORARIA<br/>de los dias afectados"]
  D --> E["Patron: actividad continua<br/>02:00 a 08:00, antes 40 min"]
  E --> F["3. CloudTrail + registros<br/>de consultas"]
  F --> G["Causa: despliegue del 7 de agosto<br/>JOIN sin condicion"]
  G --> H["Corregir + limite de uso<br/>+ bajar el umbral del monitor"]

Los tres pasos, con su resultado concreto:

  1. Agrupar por tipo de uso en Cost Explorer, filtrando a Redshift y a los últimos 14 días. El resultado señala RPU-Hours, no almacenamiento: el problema es cómputo, no datos.
  2. Vista horaria de esos días. El patrón es inequívoco: antes, un pico de 40 minutos a las 02:00; ahora, actividad continua desde las 02:00 hasta las 08:00.
  3. CloudTrail y los registros de consultas. El 7 de agosto se desplegó un informe nuevo con una consulta que hace un producto cartesiano por un JOIN sin condición. La consulta no falla: simplemente tarda seis horas, y mientras tanto el grupo de trabajo Serverless no se pausa nunca.

El coste real del incidente: 68,40 USD en siete días, que a ese ritmo serían unos 340 USD al mes, un 15 % de la factura, por un JOIN mal escrito.

Las tres acciones que se toman, y ninguna es «arreglar la consulta» a secas:

Acción Qué evita
Corregir el JOIN y añadir la consulta a las pruebas del pipeline Que vuelva a desplegarse igual
Fijar un límite de uso en wg-mercadofresco-analitica: alerta a 40 RPU-hora diarias y parada a 60 Que cualquier consulta futura se coma la factura
Bajar el umbral del monitor de anomalías de la cuenta de producción de 25 a 15 USD Que se detecte en dos días en lugar de en siete

La lección general: una anomalía de coste casi siempre es un error técnico, no un problema de dinero. El aviso de facturación fue, en este caso, el sistema de detección de errores más eficaz que tenía el equipo.

Recomendaciones de reducción y recursos huérfanos

Cost Explorer incluye una sección de Rightsizing recommendations que analiza el uso de CPU y memoria de los últimos 14 días y propone reducir o apagar. Sus límites conviene conocerlos: solo cubre EC2 (no Fargate, no Lambda, no Aurora) y asume que el patrón de las dos últimas semanas se repetirá.

Para MercadoFresco, cuyo cómputo ya está casi todo en Fargate, esa sección aporta poco. Lo que sí aporta mucho es la caza de recursos huérfanos, que no requiere ninguna herramienta especial:

Tipo de huérfano Cómo se detecta En MercadoFresco Coste
Volúmenes EBS sin asociar Estado available 3 volúmenes, 100 GiB 8,00 USD/mes
Direcciones IP elásticas sin asociar Sin instancia ni interfaz 2 direcciones 7,30 USD/mes
Instantáneas antiguas Anteriores a la política de retención 4 de RDS, 11 de EBS 6,20 USD/mes
Instancias EC2 paradas con volumen Estado stopped pero el EBS se sigue pagando 1 bastión parado desde mayo 4,80 USD/mes
Imágenes de ECR sin política de ciclo de vida Recuento creciente por repositorio 412 imágenes, 42 GB 4,20 USD/mes
Balanceadores sin destinos sanos Grupo de destino vacío 1 ALB de una prueba de abril 17,10 USD/mes
Grupos de registros sin retención retentionInDays nulo 84 grupos 34,60 USD/mes
Endpoints de VPC en entornos parados Cargo fijo sin tráfico 4 en preproducción 32,10 USD/mes

Suman 114,30 USD al mes en cosas que nadie usa, es decir, un 5,1 % de la factura tirado. Y son, sin excepción, restos de trabajo legítimo: una prueba que se hizo, un entorno que se levantó, una instancia que se paró en lugar de terminarse.

El script que MercadoFresco ejecuta cada lunes para detectarlos:

#!/usr/bin/env bash
# Cazador de huerfanos. Solo informa: no borra nada.
REGION=eu-west-1

echo "== Volumenes EBS sin asociar =="
aws ec2 describe-volumes --region $REGION \
  --filters Name=status,Values=available \
  --query 'Volumes[].{Id:VolumeId,GiB:Size,Creado:CreateTime}' --output table

echo "== IP elasticas sin asociar =="
aws ec2 describe-addresses --region $REGION \
  --query 'Addresses[?AssociationId==null].[PublicIp,AllocationId]' --output table

echo "== Grupos de registros sin retencion =="
aws logs describe-log-groups --region $REGION \
  --query 'logGroups[?retentionInDays==null].[logGroupName,storedBytes]' \
  --output table

echo "== Grupos de destino sin destinos sanos =="
for tg in $(aws elbv2 describe-target-groups --region $REGION \
              --query 'TargetGroups[].TargetGroupArn' --output text); do
  sanos=$(aws elbv2 describe-target-health --region $REGION --target-group-arn "$tg" \
            --query 'length(TargetHealthDescriptions[?TargetHealth.State==`healthy`])' \
            --output text)
  [ "$sanos" = "0" ] && echo "SIN DESTINOS SANOS: $tg"
done

Dos decisiones de diseño de este script merecen comentario. Solo informa, nunca borra: un volumen available puede ser la copia que alguien separó a propósito antes de una migración, y un borrado automático destruiría datos. Y se ejecuta semanalmente, no a diario, porque los huérfanos aparecen despacio y un informe diario que casi siempre está vacío se deja de leer.

Compute Optimizer y Trusted Advisor

Tres herramientas se solapan aquí y conviene saber cuál usar para qué:

Herramienta Qué analiza Fortaleza Límite
Cost Explorer – Rightsizing EC2 con datos de facturación Integrado con el coste Solo EC2, 14 días
AWS Compute Optimizer EC2, Auto Scaling, EBS, Lambda, ECS en Fargate Aprendizaje automático sobre métricas reales; cubre Fargate y Lambda Necesita 14 días de datos; mejor con métricas de memoria
Trusted Advisor (05-05) Comprobaciones predefinidas transversales Cubre coste, seguridad, fiabilidad y cuotas Las comprobaciones de coste completas exigen plan Business

Para MercadoFresco, la más útil de las tres es Compute Optimizer, precisamente porque cubre lo que Cost Explorer no ve:

  • Lambda: recomienda memoria por función. La función mercadofresco-generar-miniaturas está en 1.024 MB y usa 340 MB de pico; bajarla a 512 MB ahorra poco en dinero pero también reduce el tiempo, porque la CPU escala con la memoria. Aquí hay que tener cuidado: bajar la memoria de una Lambda puede hacerla más lenta y más cara, y hay que medirlo con el ajuste de potencia, no suponerlo.
  • ECS en Fargate: valida el dimensionado por percentil que se hizo en 10-02, y señala que svc-mercadofresco-trabajadores está sobredimensionado en memoria.
  • EBS: propone pasar volúmenes gp2 restantes a gp3, un 20 % más barato con el mismo rendimiento base.

El reparto de papeles que funciona: Trusted Advisor para lo evidente y transversal, Compute Optimizer para el dimensionado fino, Cost Explorer para entender el dinero y decidir. Ninguna de las tres sustituye a la revisión mensual con criterio humano, porque ninguna sabe que un entorno de preproducción tiene que parecerse a producción aunque esté infrautilizado.

Previsión de gasto y cómo interpretarla

Cost Explorer proyecta el gasto futuro con un intervalo de confianza. Para MercadoFresco, la previsión de agosto a mitad de mes era de 2.180 USD con un intervalo del 80 % entre 2.050 y 2.310; el cierre real fue de 2.237,60 USD, dentro del intervalo.

Tres advertencias sobre la previsión, en orden de importancia:

  1. Extrapola el pasado. No sabe que el 1 de septiembre se apaga el entorno de desarrollo por las noches, ni que en diciembre hay campaña. Toda decisión ya tomada invalida la previsión.
  2. El intervalo de confianza es parte del número. Presentar «2.180 USD» sin decir «entre 2.050 y 2.310» convierte una estimación en una promesa, y alguien la tratará como tal.
  3. Es muy mala al principio de mes. Con tres días de datos, la previsión de MercadoFresco osciló entre 1.900 y 2.600 USD. A partir del día 10 se estabiliza.

Su uso legítimo es como entrada de los presupuestos con umbral sobre coste previsto de 11-04: enterarse el día 8 de que se va a superar el presupuesto es mucho más útil que enterarse el día 30 de que se superó.

Consultar Cost Explorer desde boto3

Todo lo anterior se puede automatizar con la API. El ejemplo completo que MercadoFresco ejecuta cada día:

import boto3
from datetime import date, timedelta

ce = boto3.client("ce", region_name="us-east-1")   # el endpoint de CE es global

hoy = date.today()
inicio = (hoy - timedelta(days=32)).replace(day=1)  # mes anterior completo

respuesta = ce.get_cost_and_usage(
    TimePeriod={"Start": inicio.isoformat(), "End": hoy.isoformat()},
    Granularity="DAILY",
    Metrics=["UnblendedCost"],
    GroupBy=[
        {"Type": "DIMENSION", "Key": "SERVICE"},
        {"Type": "TAG", "Key": "Componente"},
    ],
    Filter={
        "And": [
            {"Dimensions": {"Key": "RECORD_TYPE",
                            "Values": ["Usage"], "MatchOptions": ["EQUALS"]}},
            {"Dimensions": {"Key": "LINKED_ACCOUNT",
                            "Values": ["111122223333"], "MatchOptions": ["EQUALS"]}},
        ]
    },
)

# Acumular por servicio para sacar el top 10 del periodo
por_servicio = {}
for dia in respuesta["ResultsByTime"]:
    for grupo in dia["Groups"]:
        servicio = grupo["Keys"][0]
        importe = float(grupo["Metrics"]["UnblendedCost"]["Amount"])
        por_servicio[servicio] = por_servicio.get(servicio, 0.0) + importe

print(f"{'Servicio':<45} {'USD':>10}")
for servicio, importe in sorted(por_servicio.items(),
                                key=lambda x: -x[1])[:10]:
    print(f"{servicio:<45} {importe:>10.2f}")

Los detalles que hacen falta para que esto funcione y no salga caro:

  • El cliente se crea en us-east-1. El endpoint de Cost Explorer es global y vive ahí; crearlo en eu-west-1 produce un error de conexión que despista bastante.
  • RECORD_TYPE = Usage excluye impuestos, créditos y cuotas, para que la suma coincida con el coste de servicios y no con el total facturado.
  • Cada llamada cuesta 0,01 USD. Este script se ejecuta una vez al día: 0,30 USD al mes. Ejecutado cada cinco minutos desde un panel serían 87 USD al mes, más de lo que cuesta ElastiCache en preproducción.
  • GroupBy admite un máximo de dos dimensiones. Para cruces más ricos, el camino es el CUR con Athena de 11-02.
  • La respuesta viene paginada con NextPageToken cuando hay muchos grupos; en producción hay que recorrerla, y cada página es otra petición facturada.

Publicar el gasto diario como métrica de negocio

El paso que convierte el análisis en algo que se mira sin querer: llevar el gasto al panel donde ya vive el negocio.

import boto3
from datetime import date, timedelta

ce = boto3.client("ce", region_name="us-east-1")
cw = boto3.client("cloudwatch", region_name="eu-west-1")

ayer = date.today() - timedelta(days=2)   # 2 dias: el dato de ayer aun no esta cerrado
hasta = ayer + timedelta(days=1)

datos = ce.get_cost_and_usage(
    TimePeriod={"Start": ayer.isoformat(), "End": hasta.isoformat()},
    Granularity="DAILY",
    Metrics=["UnblendedCost"],
    GroupBy=[{"Type": "DIMENSION", "Key": "LINKED_ACCOUNT"}],
    Filter={"Dimensions": {"Key": "RECORD_TYPE",
                           "Values": ["Usage"], "MatchOptions": ["EQUALS"]}},
)

ENTORNOS = {
    "111122223333": "produccion",
    "222233334444": "preproduccion",
    "333344445555": "desarrollo",
}

metricas, total = [], 0.0
for grupo in datos["ResultsByTime"][0]["Groups"]:
    cuenta = grupo["Keys"][0]
    importe = float(grupo["Metrics"]["UnblendedCost"]["Amount"])
    total += importe
    if cuenta in ENTORNOS:
        metricas.append({
            "MetricName": "CosteDiario",
            "Dimensions": [{"Name": "Entorno", "Value": ENTORNOS[cuenta]}],
            "Value": round(importe, 2),
            "Unit": "None",
        })

metricas.append({"MetricName": "CosteDiario",
                 "Dimensions": [{"Name": "Entorno", "Value": "total"}],
                 "Value": round(total, 2), "Unit": "None"})

cw.put_metric_data(Namespace="MercadoFresco/Tienda", MetricData=metricas)
print(f"Publicado el coste del {ayer}: {total:.2f} USD")

Por qué esto importa más de lo que parece:

  • Usa el dato de hace dos días, no el de ayer, por el retraso de actualización. Publicar el de ayer produce una serie con valles falsos que confunden más de lo que informan.
  • Publica una serie por entorno y una de total, lo que permite poner en el panel mercadofresco-negocio una gráfica con CosteDiario junto a PedidosConfirmados. Ver las dos líneas juntas es la forma más directa de entender el coste unitario sin calcular nada.
  • Permite alarmas de CloudWatch sobre el coste, con toda la maquinaria del módulo 5: umbrales, datos ausentes, acciones y silenciamiento. Una alarma de CosteDiario en desarrollo por encima de 10 USD avisa en horas, no en semanas.
  • Este script vive en una Lambda con EventBridge Scheduler ejecutándose a las 06:00, y su coste total es de céntimos.

Las diez optimizaciones de MercadoFresco

Con todo el análisis hecho, Marta y Luis dedican dos días a ejecutar. Estas son las diez acciones, ordenadas por ahorro:

# Optimización Ahorro/mes Riesgo Esfuerzo
1 Apagado nocturno y de fin de semana de preproducción y desarrollo 118,00 USD Bajo Medio
2 Retención de registros y bajada del nivel a INFO en producción 74,00 USD Bajo Bajo
3 De 2 NAT a 1 en preproducción y desarrollo 66,00 USD Bajo Bajo
4 Autoescalado de lectores de Aurora: de 2 a 1 en horario valle 54,00 USD Medio Medio
5 Retirar los endpoints de interfaz de preproducción 32,00 USD Bajo Bajo
6 Ciclo de vida en S3 para mercadofresco-registros-web y copias 38,00 USD Bajo Bajo
7 Borrar los huérfanos: volúmenes, IP, instantáneas, ALB de pruebas 41,00 USD Bajo Bajo
8 arm64 en trabajadores y preproducción (la tienda ya lo tenía) 27,00 USD Bajo Medio
9 Redshift: bajar la RPU base, límite de uso y quitar la carga duplicada 27,00 USD Bajo Bajo
10 Ciclo de vida en ECR: conservar 20 etiquetadas, borrar sin etiquetar > 14 días 11,00 USD Bajo Bajo
Total 488,00 USD

El detalle de las tres primeras, que son las que más aportan.

1. Apagado nocturno (118,00 USD). Preproducción y desarrollo funcionan 24×7 para un equipo que trabaja de 8 a 19 de lunes a viernes. Encendidos de 07:30 a 20:30 en días laborables son 65 de las 168 horas semanales: un 61 % de reducción en lo que se puede apagar. Con EventBridge Scheduler:

# Bajar a cero las tareas del servicio de desarrollo cada noche
aws scheduler create-schedule \
  --name mf-desarrollo-apagar \
  --schedule-expression "cron(30 20 ? * MON-FRI *)" \
  --schedule-expression-timezone "Europe/Madrid" \
  --flexible-time-window '{"Mode":"OFF"}' \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:ecs:updateService",
    "RoleArn": "arn:aws:iam::333344445555:role/rol-mercadofresco-planificador",
    "Input": "{\"Cluster\":\"ecs-mercadofresco\",\"Service\":\"svc-mercadofresco-tienda-fg\",\"DesiredCount\":0}"
  }'

La zona horaria explícita Europe/Madrid no es un detalle menor: sin ella, el horario de verano desplaza el apagado una hora y, dos veces al año, alguien encuentra el entorno apagado a las 19:30. Lo que se apaga: tareas de Fargate a cero, instancias de Aurora paradas —recordando que RDS y Aurora arrancan solos a los 7 días de estar parados, así que hace falta un planificador que los vuelva a parar—, y el grupo de trabajo de Redshift, que se pausa solo.

2. Retención de registros (74,00 USD). Dos cambios independientes. El primero, poner retención a los 84 grupos de registros:

# Politica por defecto: 30 dias en no productivo, 90 en produccion,
# 365 solo para los registros de auditoria
for grupo in $(aws logs describe-log-groups \
                 --query 'logGroups[?retentionInDays==null].logGroupName' \
                 --output text); do
  case "$grupo" in
    *cloudtrail*|*auditoria*) dias=365 ;;
    *produccion*|*prod*)      dias=90  ;;
    *)                        dias=30  ;;
  esac
  aws logs put-retention-policy --log-group-name "$grupo" --retention-in-days $dias
  echo "$grupo -> $dias dias"
done

El segundo, bajar el nivel de registro de DEBUG a INFO en producción, que reduce la ingesta de 61 a unos 38 GB al mes. Y una decisión de arquitectura que se toma de paso: los registros de acceso del ALB y del WAF dejan de duplicarse en CloudWatch Logs y se quedan solo en S3, donde ya se consultan con Athena y cuestan veinte veces menos.

3. De 2 NAT a 1 (66,00 USD). En preproducción y desarrollo se elimina un NAT por entorno y se enruta el tráfico de las dos subredes privadas por el que queda. La consecuencia real, escrita para que nadie se sorprenda: si cae la AZ del NAT superviviente, ese entorno se queda sin salida a internet. En desarrollo, eso significa que Luis no puede descargar dependencias durante un rato. En producción no se toca, y esa asimetría es exactamente lo que significa tratar los entornos según su criticidad en lugar de por costumbre.

El resultado global:

Concepto Antes Después
Factura mensual 2.237,60 USD 1.749,60 USD
Reducción −488,00 USD (−21,8 %)
Ahorro anualizado −5.856 USD
Coste por pedido 0,01243 USD 0,00972 USD (−21,8 %)
Peso de lo no productivo 29,0 % 19,4 %

Y una observación honesta sobre esta lista: ninguna de las diez acciones ha degradado la producción. No se ha quitado un lector de Aurora en el pico, no se ha reducido la observabilidad de producción por debajo de lo necesario y no se ha tocado la redundancia de salida a internet donde hay clientes. Un ahorro del 22 % sin tocar la calidad del servicio es lo normal en la primera pasada de optimización de una arquitectura que nunca se ha revisado. La segunda pasada ya cuesta mucho más trabajo por cada dólar.

Errores Comunes y Consejos

Error: comparar el mes en curso con el mes anterior completo. El día 12 parece que se ha ahorrado un 60 %. Consejo: compara periodos equivalentes —día 1 a 12 frente a día 1 a 12— o usa la previsión, nunca un mes parcial contra uno cerrado.

Error: sacar conclusiones del gasto de hoy. Con hasta 24 horas de retraso, el día en curso siempre parece barato. Consejo: trabaja con datos de hace dos días como mínimo, y publica las métricas con ese desfase.

Error: mezclar coste no combinado y amortizado en la misma conversación. Dos personas ven números distintos y discuten media hora. Consejo: di siempre qué métrica estás usando. No combinado para cuadrar con la factura, neto amortizado para analizar.

Error: perseguir la línea más grande de la factura. Aurora es la mayor y es una decisión consciente y firmada; el dinero mal gastado está en las líneas medianas que nadie decidió. Consejo: ordena por «coste que nadie ha decidido», no por importe.

Error: consultar la API de Cost Explorer desde un panel que refresca cada minuto. A 0,01 USD por petición, el análisis de costes acaba siendo una partida de la factura. Consejo: consulta una vez al día y publica el resultado como métrica de CloudWatch; los paneles leen la métrica, no la API.

Error: activar la granularidad horaria y olvidarla. Tiene coste por registros consultados y se paga aunque casi no se use. Consejo: actívala para el análisis concreto que la necesite —el pico del viernes, la base estable de 11-05— y revisa si sigue haciendo falta.

Error: umbrales de anomalía demasiado sensibles. Tres avisos por semana y el canal se silencia. Consejo: empieza alto —25 USD o 40 %— y baja según la experiencia real, con umbrales combinados absoluto y porcentual.

Error: borrar huérfanos automáticamente. Un volumen available puede ser la copia que alguien apartó antes de una migración. Consejo: el detector informa, la persona decide. Y antes de borrar, etiqueta con FechaBaja y espera una semana.

Error: apagar entornos sin avisar. El equipo se encuentra el entorno caído a las 20:31 en medio de una prueba. Consejo: anúncialo, deja un procedimiento de encendido manual documentado y empieza por desarrollo antes que por preproducción.

Consejo: el primer análisis de una factura nunca revisada rinde entre un 15 y un 30 %. No hace falta ser brillante, hace falta mirar. Lo difícil es la segunda pasada.

Consejo: convierte cada hallazgo en una comprobación permanente. La retención de registros no es una tarea, es una regla de Config; el ciclo de vida de ECR no es un borrado, es una política; el apagado nocturno no es un recordatorio, es un planificador.

Ejercicios

Ejercicio 1: interpretar una anomalía

El 3 de octubre, alertas-mercadofresco recibe un aviso: Amazon S3 en la cuenta 111122223333 ha pasado de 4,20 a 19,80 USD diarios desde el 28 de septiembre. Impacto acumulado: 78,00 USD.

  1. Enumera cuatro hipótesis ordenadas de más a menos probable.
  2. Indica qué agrupación y qué filtro usarías en Cost Explorer para descartarlas.
  3. Si la causa resulta ser que se activó el registro de acceso al bucket mercadofresco-catalogo-fotos y esos registros se escriben en el mismo bucket, ¿qué tres acciones tomarías?

Ejercicio 2: priorizar optimizaciones con presupuesto de tiempo

Dispones de un solo día de trabajo y esta lista de acciones posibles sobre la factura de MercadoFresco:

Acción Ahorro/mes Esfuerzo Riesgo
A. Apagado nocturno de no productivo 118 USD 6 h Bajo
B. Retención de registros 74 USD 1 h Bajo
C. Migrar los trabajadores a arm64 27 USD 8 h Medio
D. De 2 NAT a 1 en no productivo 66 USD 2 h Bajo
E. Borrar huérfanos 41 USD 2 h Bajo
F. Comprar un Savings Plan a 3 años 210 USD 1 h Alto
  1. Elige qué harías en ese día y justifícalo.
  2. ¿Por qué F es peligrosa ahora mismo, si es la de mayor ahorro y menor esfuerzo?
  3. Calcula el ahorro conseguido y el porcentaje sobre los 2.237,60 USD.

Ejercicio 3: leer un desglose por tipo de uso

Cost Explorer, filtrado a Amazon CloudWatch y agrupado por tipo de uso, devuelve para un mes:

Tipo de uso USD
EUW1-DataProcessing-Bytes 118,40
EUW1-TimedStorage-ByteHrs 34,60
EUW1-CW:MetricMonitorUsage 27,00
EUW1-CW:Requests 18,60
EUW1-CW:AlarmMonitorUsage 8,40
EUW1-CW:Dashboards 6,00
EUW1-CW:Canaries 1,90
  1. Traduce cada línea a lo que significa en la práctica.
  2. ¿Cuáles atacarías primero y con qué acción concreta?
  3. Estima el ahorro si la ingesta baja de 61 a 38 GB al mes y la retención pasa de indefinida a 30/90 días, sabiendo que el almacenamiento se estabilizaría en torno a los 130 GB.

Soluciones

Solución al ejercicio 1

(1) Cuatro hipótesis, de más a menos probable:

  1. Se ha activado un registro que escribe en S3 —acceso al bucket, registros del ALB, del WAF, del CUR o de flujo de la VPC— y el volumen de peticiones PUT se ha disparado. Es la causa más frecuente de un salto brusco en S3, porque el coste no está en los bytes sino en las peticiones.
  2. Se ha subido un volumen grande de datos: una carga inicial, una copia de seguridad manual, una exportación de la base de datos.
  3. Un proceso en bucle que reescribe los mismos objetos, o versionado activado sin ciclo de vida que conserva todas las versiones antiguas.
  4. Transferencia de salida hacia internet o hacia otra región, si algún consumidor externo empezó a leer directamente del bucket saltándose CloudFront.

(2) Cómo descartarlas. Filtro: servicio = Amazon S3, cuenta = 111122223333, últimos 30 días, granularidad diaria. Agrupación: tipo de uso. Esa única vista discrimina las cuatro hipótesis en un vistazo, porque los tipos de uso son distintos: Requests-Tier1 (peticiones PUT) señala la primera o la tercera; TimedStorage-ByteHrs señala la segunda; DataTransfer-Out-Bytes señala la cuarta. Si Requests-Tier1 domina, un segundo paso con el CUR agrupando por line_item_resource_id da el bucket exacto.

(3) Tres acciones si es el registro de acceso escribiendo en el mismo bucket:

  1. Mover el destino de los registros a mercadofresco-registros-web, nunca al mismo bucket que se está registrando. Escribir los registros de acceso en el propio bucket crea un bucle: cada escritura de registro genera un acceso, que genera un registro. Es un error clásico y puede crecer sin límite.
  2. Poner ciclo de vida a esos registros: 30 días en Standard, después Glacier Instant Retrieval, borrado a los 180. Los registros de acceso casi nunca se consultan pasado el primer mes.
  3. Preguntarse si hacen falta. Si el objetivo era auditoría, los eventos de datos de CloudTrail (05-03) ya cubren el acceso a S3 con mejor formato y mejor integración, y probablemente ya estén activos. Un registro duplicado se paga dos veces.

Solución al ejercicio 2

(1) Qué haría en un día (8 horas): B (1 h) + D (2 h) + E (2 h) = 5 horas, y con las 3 horas restantes empezar A, dejando el planificador escrito y probado en desarrollo pero sin aplicarlo aún a preproducción.

El razonamiento: B, D y E son de riesgo bajo, esfuerzo bajo y efecto inmediato, y juntas suman 181 USD al mes en cinco horas de trabajo. A es la de mayor ahorro pero necesita seis horas de reloj más un aviso al equipo, así que partirla es lo sensato. C queda para otra semana: ocho horas por 27 USD al mes es la peor relación de la lista, y además tiene riesgo medio porque exige probar la imagen arm64 en preproducción antes.

(2) Por qué F es peligrosa. Por una razón de orden que 11-05 desarrolla y que conviene interiorizar ahora: comprometer capacidad antes de optimizar es comprar lo que estás a punto de dejar de usar. Si se compra un Savings Plan a tres años dimensionado sobre el consumo actual y a la semana siguiente se ejecutan las acciones A a E, el consumo baja un 22 % y el compromiso sobrante se paga igualmente durante tres años. A eso se suman dos agravantes: tres años es un horizonte en el que la arquitectura casi seguro cambia, y un Savings Plan no se puede cancelar. El orden correcto es siempre: primero apagar lo que sobra, después dimensionar lo que queda, y solo entonces comprometer.

(3) Ahorro conseguido:

B (retencion de registros) .......  74,00 USD
D (de 2 NAT a 1) .................  66,00 USD
E (huerfanos) ....................  41,00 USD
--------------------------------------------
Total ............................ 181,00 USD/mes
Sobre 2.237,60 USD ............... 8,1 %
Anualizado ....................... 2.172 USD

Ocho por ciento de la factura en cinco horas de trabajo. Es un rendimiento que ninguna otra actividad técnica iguala, y es exactamente por eso que el plan de mejora de 11-01 empezaba por el pilar de costes.

Solución al ejercicio 3

(1) Traducción de cada línea:

Tipo de uso Qué es en la práctica
DataProcessing-Bytes Ingesta de registros: GB que llegan a CloudWatch Logs. La línea dominante
TimedStorage-ByteHrs Almacenamiento de registros ya ingeridos, mes a mes. Crece si no hay retención
CW:MetricMonitorUsage Métricas personalizadas, a 0,30 USD cada una al mes. Son 90
CW:Requests Llamadas a la API: PutMetricData, GetMetricData, Container Insights
CW:AlarmMonitorUsage Alarmas, a 0,10 USD estándar. Son 84
CW:Dashboards Paneles por encima de los 3 gratuitos
CW:Canaries Comprobaciones de Synthetics, por ejecución

(2) Qué atacar primero. Las dos líneas de registros, que son el 71 % del total, y en este orden:

  1. Retención (TimedStorage), porque es el cambio de menor riesgo: un comando por grupo, ningún efecto sobre la aplicación y el ahorro empieza el mes siguiente. Solo hay que decidir con criterio los grupos de auditoría, que deben conservar más tiempo.
  2. Ingesta (DataProcessing), bajando el nivel a INFO en producción y dejando de duplicar los registros del ALB y del WAF en CloudWatch cuando ya están en S3.
  3. En un tercer plano, revisar las 90 métricas personalizadas y las 84 alarmas: casi siempre hay métricas que nadie grafica y alarmas que nadie atiende. Son 35 USD al mes y, más importante, cada alarma que nadie mira degrada la credibilidad de las que sí importan.

(3) Estimación del ahorro:

Ingesta:        61 GB -> 38 GB, a ~0,50 USD/GB
                118,40 -> ~73,70 USD          ahorro  44,70 USD
Almacenamiento: 1,1 TB -> ~130 GB estabilizado
                 34,60 -> ~ 4,10 USD          ahorro  30,50 USD
------------------------------------------------------------------
Ahorro total estimado                                 75,20 USD/mes

Coincide con los 74 USD de la acción 2 de la lista de optimizaciones. Dos matices para no prometer de más: el ahorro del almacenamiento no es inmediato, porque los registros existentes van expirando a lo largo de las semanas siguientes según su antigüedad, así que el efecto completo se ve en el segundo o tercer mes; y bajar de DEBUG a INFO tiene un coste real que hay que aceptar por escrito, que es tener menos detalle disponible el día que haya que investigar un incidente raro en producción. La mitigación es dejar el nivel DEBUG activable bajo demanda mediante un parámetro en /mercadofresco/produccion/... sin necesidad de desplegar.

Conclusión

MercadoFresco ha abierto su factura y ha salido de ahí con un 22 % menos de gasto y ninguna degradación del servicio.

Sabes qué es Cost Explorer y con qué datos trabaja: 13 meses de histórico, granularidad diaria gratuita y horaria de pago, hasta 24 horas de retraso —de ahí la regla de no sacar nunca conclusiones del día en curso— y una interfaz gratuita con una API que cuesta 0,01 USD por petición, que es el error caro que convierte un panel de costes en una partida de la factura.

Tienes los conceptos de facturación que hay que entender antes de mirar un gráfico: no combinado para cuadrar con la factura, amortizado para analizar cuando hay compromisos —con el ejemplo del Savings Plan de 1.200 USD que se ve como un pico en marzo o como 100 USD al mes según la métrica—, y las variantes netas que descuentan créditos. Más la razón por la que la suma nunca cuadra con lo cobrado: los tipos de línea Tax, Credit, Refund y las cuotas, con la regla de trabajar siempre sobre el coste de servicios, que es el único que se optimiza con ingeniería. Y la facturación consolidada entre las seis cuentas, con sus tres consecuencias: una sola factura, agregación de tramos por volumen y compromisos compartidos.

Tienes la factura completa de MercadoFresco: 27 líneas hasta los 2.237,60 USD, encabezadas por Aurora (342,60), Fargate (262,40), NAT Gateway (243,80) y CloudWatch (214,90). Y la forma correcta de leerla, que no es de mayor a menor importe sino separando lo decidido de lo no decidido: Aurora está ahí por un ADR firmado, mientras que los 611,20 USD del NAT, la transferencia entre zonas, CloudWatch y el EC2 residual —el 27,3 % de la factura— no los ha decidido nadie nunca.

Tienes las tres sorpresas desmontadas con su origen concreto. El NAT Gateway, cuyo 81 % es cargo fijo por hora y no tráfico, con 143,80 USD al mes pagados por entornos sin un solo cliente. La transferencia entre zonas, el coste más invisible de AWS porque no tiene recurso al que culpar, que nace del ALB repartiendo entre AZ, de la réplica de Aurora y de la de ElastiCache, y que no hay que eliminar porque es el precio de la alta disponibilidad. Y CloudWatch, donde el 71 % son registros y la raíz es la misma en ambas líneas: nadie decidió nunca qué registrar ni cuánto retener.

Tienes las herramientas de vigilancia: filtros y agrupaciones —con el tipo de uso como la dimensión más infravalorada, la que convierte «VPC: 362,40 USD» en cuatro líneas accionables—, los cinco informes guardados, el guion de ocho pasos de la revisión mensual de Marta que termina siempre con una sola acción con dueño y fecha, y la detección de anomalías con monitores dimensionales, umbrales combinados absoluto y porcentual, y aviso inmediato por SNS. Con el caso real de la carga nocturna a Redshift —un JOIN sin condición que costaba 340 USD al mes y se detectó por la factura— y su lección: una anomalía de coste casi siempre es un error técnico, no un problema de dinero.

Tienes la caza de recursos huérfanos, 114,30 USD al mes en cosas que nadie usa, con el script semanal que informa y nunca borra; el reparto de papeles entre Cost Explorer, Compute Optimizer y Trusted Advisor, sabiendo que solo Compute Optimizer ve Fargate y Lambda; la previsión con sus tres advertencias, empezando por que extrapola el pasado y por tanto cualquier decisión ya tomada la invalida; y la consulta desde boto3 con get_cost_and_usage, el cliente en us-east-1, el filtro RECORD_TYPE=Usage y el script que publica CosteDiario en MercadoFresco/Tienda con dos días de desfase, para que el gasto viva por fin en el mismo panel que los pedidos.

Y tienes las diez optimizaciones ejecutadas con su ahorro: apagado nocturno (118), retención de registros (74), de dos NAT a uno en no productivo (66), autoescalado de lectores de Aurora (54), ciclo de vida en S3 (38), huérfanos (41), endpoints de preproducción (32), arm64 en trabajadores (27), límites en Redshift (27) y ciclo de vida en ECR (11). 488,00 USD al mes, un 21,8 %, que dejan la factura en 1.749,60 USD y el coste por pedido en 0,00972 USD. Con la observación honesta de que ninguna de las diez ha degradado la producción, y con la advertencia sobre lo que viene después: la primera pasada de optimización de una arquitectura nunca revisada rinde entre un 15 y un 30 % sin ser brillante; la segunda ya cuesta mucho más trabajo por cada dólar.

Queda un problema que este análisis no resuelve. Todo lo anterior es mirar hacia atrás: se descubre lo que ya se ha gastado. El detector de anomalías avisa en un día o dos, que está bien, pero nadie ha puesto todavía un límite. Si mañana Luis levanta un clúster de EKS de pruebas en la cuenta de desarrollo y se olvida, o si una consulta nueva se dispara un viernes por la noche, la factura crecerá sin que nada se interponga. Y el presupuesto-mensual-mercadofresco de 10 USD creado en 01-02 lleva veintitantos meses saltando todos los días 2, hasta el punto de que ya nadie lee sus correos.

En 11-04, «AWS Budgets», se pasa de analizar a controlar: presupuestos por cuenta, por servicio, por etiqueta y por categoría de coste, con umbrales sobre coste real y previsto, con avisos escalonados y con acciones automáticas capaces de congelar la cuenta de desarrollo cuando alcanza su límite. Más la rutina FinOps que sostiene todo el ciclo.

Curso de AWS

Módulo 1: Introducción a AWS

Módulo 2: Servicios principales de AWS

Módulo 3: Redes y entrega de contenido

Módulo 4: Seguridad e identidad

Módulo 5: Monitorización y gestión

Módulo 6: Bases de datos

Módulo 7: Integración de aplicaciones

Módulo 8: Herramientas para desarrolladores

Módulo 9: Infraestructura como código y gobierno de cuentas

Módulo 10: Contenedores en AWS

Módulo 11: Mejores prácticas y gestión de costos

© Copyright 2026. Todos los derechos reservados