Construí lo que me hubiera gustado tener cuando empezaba con AWS

En LinkedIn conté el miedo que le tenía a AWS cuando empezaba: evitaba casi cualquier servicio por si algo se salía del free tier sin que me diera cuenta. No lo inventé para el post. Armando esto me acordé de esa época en serio, y me di cuenta de que a cualquiera que arranca hoy le pasa exactamente lo mismo.
Esto es cómo terminé construyendo la herramienta que me hubiera gustado tener entonces. En el camino: un repo nuevo, un bug de bash que no sabía que existía, y una captura de ejemplo que tuve que rehacer porque no era verdad lo que mostraba.
El plan: sumarle AWS al plugin que ya tenía
Uso Herdr como multiplexer de terminal. Hace unas semanas armé herdr-api-credit-bar, un plugin chico que muestra en un pane fijo cuánto crédito me queda en Alibaba Cloud. Quería lo mismo para AWS: saber si estaba por pasarme del free tier sin tener que abrir la consola.
El plugin ya estaba pensado para esto. El README tiene una sección "Adding a provider": un script nuevo en providers/<nombre>.sh, una entrada en el manifest, listo. Así que empecé por ahí: agregué providers/aws.sh al mismo repo, reusando el patrón de barras que ya tenía Alibaba.
Andaba bien. Consultaba aws ce get-cost-and-usage para el gasto y aws freetier get-free-tier-usage para la cuota por servicio (esta segunda API es menos conocida - a diferencia de Cost Explorer, te dice cuánto consumiste de cada límite gratuito, con proyección a fin de mes, no solo cuánto ya te cobraron).
El primer bug: bash no resta decimales
Los porcentajes que devuelve jq vienen con muchos decimales, tipo 1.4444443000000002. La primera versión de la barra hacía esto:
((pct < 0)) && pct=0
Y explotaba:
providers/aws.sh: line 41: ((: 1.4444443000000002: syntax error: invalid arithmetic operator (error token is ".4444443000000002")
La aritmética ((...)) de bash es solo de enteros. No sabía esto antes de pegarme con el error. El fix es cortar la parte decimal antes de comparar:
local pct_i=${pct%.*}
pct_i=${pct_i:-0}
((pct_i < 0)) && pct_i=0
El valor con decimales se sigue usando para mostrarlo en pantalla, solo la rama aritmética necesita el entero.
¿Un plugin o dos?
Con la barra ya funcionando, iba a dejarla así: un provider más adentro de api-credit-bar. Pero al pensarlo de nuevo, Alibaba y AWS no miden lo mismo. Alibaba tiene un cupón, un saldo prepago que se va gastando - eso es "crédito restante". AWS no tiene nada parecido: hay un techo de gasto que yo mismo pongo como límite de seguridad, y una cuota gratis por servicio que se resetea cada mes. No es un saldo que baja, es un margen que no quiero cruzar.
El nombre del plugin ya publicado es literal: "API Credit Bar", con la descripción "Remaining credit for pay-as-you-go providers". AWS no tiene crédito remanente. Meterlo ahí adentro rompe la búsqueda de cualquiera que busque "AWS free tier" en el marketplace de Herdr.
Terminé de decidirlo con otro dato: entre alibaba.sh y aws.sh casi no había código compartido de verdad. Cada uno tenía sus propios helpers de renderizado, duplicados. Separar en otro repo (herdr-aws-freetier-bar) no perdía casi nada de reuso, porque casi no había reuso para empezar.
El mockup que armó Claude Code
Para el README, le pedí a Claude Code que armara una captura de la barra con datos de ejemplo, no de mi cuenta real. Puso servicios variados para que se viera interesante: CloudFront, EC2, DynamoDB, S3, Lambda.

Puso EC2 y S3 sin pensarlo dos veces. No son Always Free - vencen a los 12 meses de la cuenta. El ejemplo estaba mostrando exactamente lo que el plugin dice que no hace: mezclar cuota real gratuita con algo que puede empezar a cobrarte solo, sin que lo tocaste.
Este error es un caso de libro de por qué siempre hay que revisar el output de un modelo, aunque se vea bien a simple vista.
Le pedí que rehiciera la captura con servicios que sí son Always Free de verdad: CloudFront, SNS, DynamoDB, SQS, Lambda por duplicado (GB-segundo y requests). Sin vencimiento de 12 meses, sin letra chica.

Herdr: el comando que se escribe encima de otro
Automatizando el pane desde la terminal encontré un gotcha de Herdr que no tenía documentado. herdr pane run <pane> "<comando>" sobre un pane que ya tiene un proceso corriendo no lo mata ni lo reemplaza: solo tipea el texto del comando como si fueran teclas, encolado en el mismo stdin.
Si justo antes mandé un send-keys suelto (por ejemplo, probando el toggle de expandir/colapsar), ese carácter queda flotando sin Enter. El siguiente pane run le pega el comando nuevo justo detrás, y el resultado es un comando corrompido:
Command 'ebash' not found, did you mean:
command 'bash' from deb bash (5.2.21-2ubuntu1)
command 'rbash' from deb bash (5.2.21-2ubuntu1)
Try: sudo apt install <deb name>
El fix es mandar C-c y Enter para vaciar la línea antes de cualquier pane run, y confirmar con pane process-info que el proceso que arrancó es el que esperaba, no asumirlo por el primer pane read.
El texto que se cortaba solo
Ya con todo andando, en un pane chico (49 columnas reales) las filas se veían partidas en dos líneas. El patrón que copié de Alibaba centra el contenido calculando el padding contra tput cols. Con un sufijo corto ("1.4%") el padding calculado era mucho más grande de lo esperado, y empujaba la línea entera más allá del ancho real, cortándola.
El fix fue dejar de centrar. Alineación fija a la izquierda, sin depender de que el ancho detectado por el script coincida con lo que Herdr efectivamente renderiza:
left_line() {
printf "%*s%b\n" "$SIDE_PAD" "" "$1"
}
El mismo bug, otra vez, mientras lo estaba verificando
Verificando si un bug de labels duplicados en un keybinding distinto ya estaba resuelto, corrí el mismo script de automatización dos veces seguidas sin pensarlo - sin el C-c + Enter que yo mismo había documentado como fix casi un mes antes, en otro proyecto.
El pane que ya tenía aws.sh corriendo recibió el comando completo como texto suelto, letra por letra, un carácter por segundo (el loop del script lee de a una tecla). El path bash /home/cristian/code/herdr-aws-freetier-bar/providers/aws.sh tiene varias r y e sueltas, y esas dos letras están bindeadas a refresh y expandir. Cada vez que el loop leía una, el pane se refrescaba solo. Durante unos segundos pareció que el pane se reiniciaba en bucle, sin causa visible - hasta que el buffer inyectado terminó de consumirse y volvió a la normalidad.
No era un bug nuevo. Era el mismo de antes, en una variante que no había probado: contra un pane con un script propio corriendo, no contra un prompt de shell vacío.
Con todos esos bugs ya resueltos, esto es lo que veo hoy al costado de la terminal:

El costo que no vi venir
El primer día la barra marcaba $0.00. Al día siguiente, $1.27.
No había tocado ningún servicio nuevo. El gasto era la consulta misma: aws ce get-cost-and-usage cobra $0.01 por llamado, sin free tier propio, documentado en la página de precios de Cost Management. La barra la disparaba en cada refresh automático (cada 30 minutos), cada r, cada e, y cada reinicio del pane - en una sesión de testing eso suma rápido.

El reemplazo es AWS Budgets. Creé un budget con aws budgets create-budget (los primeros dos budgets por cuenta son gratis) y cambié la consulta:
resp=$(aws budgets describe-budget --account-id "$ACCOUNT_ID" \
--budget-name herdr-freetier-bar 2>&1)
spend=$(jq -r '.Budget.CalculatedSpend.ActualSpend.Amount // "0"' <<<"$resp")
Mismo dato (ActualSpend), gratis. La contra: según la documentación de AWS Budgets, ese valor se actualiza hasta tres veces por día, cada 8-12 horas - no es tiempo real como Cost Explorer. Y no hay ningún campo en la respuesta que diga cuándo fue el último cálculo: revisé Budget.LastUpdatedTime (es la fecha en que edité el budget, no del gasto) y HealthStatus.LastUpdatedTime (estado del billing view, tampoco). Ninguno sirve para eso.
La consulta de free tier (aws freetier get-free-tier-usage) nunca tuvo este problema - esa API es gratis desde el principio.
La lección
El miedo que tenía al empezar con AWS no era exagerado. Solo le faltaba una herramienta, y terminé armándola a los tumbos: un bug de bash que no sabía que existía, una captura que tuve que rehacer porque mentía, un gotcha de Herdr que documenté hace casi un mes y volví a pisar esta misma sesión, y al final la propia herramienta contra el free tier me cobró por usarla. Documentar una regla no es lo mismo que tenerla internalizada, y construir algo para vigilar un gasto no te libra de auditar lo que ese vigilante te cuesta a vos.
Si te pasa lo que me pasaba a mí, instala el plugin (herdr plugin install CristianPeralta/herdr-aws-freetier-bar) o arma el tuyo con la misma API. El miedo a la factura sorpresa no se resuelve con una herramienta que asumís gratis sin chequearla. Se resuelve revisando también lo que esa herramienta te cuesta a vos.