New to Kestra?
Use blueprints to kickstart your first workflows.
Automate Azure Batch pool cost control with Kestra. Query idle node metrics, scale the pool down with an automated If gate, and purge expired scratch blobs on the same schedule.
An idle Azure Batch pool burns compute cost every hour nobody notices it, and a scratch storage container with no lifecycle policy grows forever. This blueprint checks both on the same hourly run: it pulls the idle node count for a Batch pool from Azure Monitor, resizes the pool down automatically when idle nodes have stayed high for the whole window, and deletes scratch blobs past their retention prefix in the same execution. Nothing here waits on a human to click resize in the portal or run a manual storage sweep.
hourly io.kestra.plugin.core.trigger.Schedule fires every hour.query_pool_metric (io.kestra.plugin.azure.monitoring.Query) reads the PoolIdleNodeCount metric for the Batch account from Azure Monitor's regional metrics endpoint, averaged over the window.scale_decision (io.kestra.plugin.core.flow.If) checks whether the average idle count exceeds the threshold. This is an automated gate, not a human approval step: routine pool sizing does not need a person in the loop, only genuinely destructive operations do.resize_pool (io.kestra.plugin.azure.batch.pool.Resize) scales targetDedicatedNodes and targetLowPriorityNodes down independently to the configured floor.purge_cold_blobs (io.kestra.plugin.azure.storage.blob.DeleteList) runs in the same execution, deleting every blob under the expired/ prefix in the scratch container, regardless of whether the pool was resized this run.errors block alerts Slack if any step fails, so a broken metric query or a permissions issue on the storage account does not fail silently.targetDedicatedNodes and targetLowPriorityNodes tuned independently, so spot capacity scales down first.Azure Batch has autoscale formulas for compute, but nothing native ties pool sizing to a storage retention sweep in one auditable run, and a custom autoscale formula still needs somewhere to alert when it misbehaves. Kestra runs the metric check, the resize decision, and the storage cleanup as one execution with full history, retries on transient Azure API failures, and a dedicated failure path to Slack, all declared in version-controlled YAML instead of a formula string embedded in the pool configuration.
expired/ prefix once past retention.AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET: service principal credentials for Azure Monitor.AZURE_BATCH_ACCOUNT_RESOURCE_ID: full Azure resource ID of the Batch account.AZURE_BATCH_ACCOUNT, AZURE_BATCH_ACCESS_KEY, AZURE_BATCH_ENDPOINT: Batch account credentials for the resize call.AZURE_STORAGE_CONNECTION, AZURE_STORAGE_ENDPOINT: Storage account credentials for the blob purge.SLACK_WEBHOOK_URL: Slack incoming webhook URL.resourceIds, poolId, and container to your real Batch account and storage container.scale_decision and the target node counts in resize_pool to your workload.hourly schedule trigger.expired/ prefix with a computed date-based prefix if retention is date-partitioned.