De $32 a $0.90 al mes: un pool de CI que solo existe cuando hace falta
Описание и применение
Пул самохостинга CI, работающий только при необходимости, снизил ежемесячные расходы с $32.34 до $0.90, удерживая время работы на 2.7 %.
Задача
Mantener un pool de runners autoalojados en GitHub Actions costoso y siempre encendido resulta en gastos innecesarios cuando el flujo de trabajo está inactivo.
Результат
El pool de runners autoalojados pasó de estar activo 97.5 % del tiempo y costar $32.34 / mes a dormir la mayor parte del tiempo, con un costo de ~$0.90 / mes y un tiempo activo del 2.7 %. Los tiempos de arranque aumentaron a 1 m 44 s–3 m 56 s, pero el ahorro de costos fue significativo.
Рабочий процесс
- 1. Configurar ASG con minCapacity = 0, maxCapacity = 2, capacityRebalance = true y deleteOnTermination = true en el volumen EBS.
- 2. Crear workflow "runner-pool.yml" que se dispara en pull_request, push a main, workflow_dispatch y cron, con concurrency group "runner-pool".
- 3. En el job "wake" establecer DesiredCapacity = 1 para arrancar el pool.
- 4. En el job "sleep" verificar que no haya runners ocupados ni ejecuciones activas; si no, establecer DesiredCapacity = 0 para apagar el pool.
- 5. Configurar los demás workflows (ci.yml, deploy-backend.yml, deploy-frontend.yml, deploy-intelligence.yml, security-scan.yml) para usar runners self‑hosted sin preocuparse por el estado del pool.
- 6. Añadir workflow "rerun-on-runner-loss.yml" que re‑ejecuta jobs fallidos por pérdida de runner, con máximo 3 intentos.
- 7. Utilizar GitHub Actions concurrency y workflow_run triggers para sincronizar el pool con los demás workflows.
- 8. Monitorear métricas de ASG y ajustar según sea necesario.
- 9. Validar que los costos y tiempos de ejecución se mantengan dentro de los objetivos.
- 10. Documentar la configuración y los pasos para futuros mantenedores.
Доказательства
El pool siempre encendido: 24/7; Pool scale-to-zero: 2.7 % (2h12m de 81h)
El cambio de CDK son dos líneas y una eliminación: ... minCapacity: 0, maxCapacity: 2, capacityRebalance: true, desiredCapacity deliberadamente NO declarado.
El volumen de EBS es deleteOnTermination.
- Дата записи: 2026-10-10T23:11:11.526Z