Get icon
Fail icon
Resize icon
LoopUntil icon
SlackIncomingWebhook icon
Schedule icon

Business-Hours Resize for DigitalOcean Managed Databases

Schedule DigitalOcean managed database resizes with Kestra: scale up for business hours, down at night, and wait until the cluster is healthy again.

Categories
CloudData

Stop paying peak-capacity prices for a database that only works office hours. This blueprint resizes a DigitalOcean managed database cluster on a schedule, scaling it up before the workday and back down in the evening. One flow serves both directions: each Schedule trigger passes its own target_size and target_nodes inputs. Before resizing, the flow verifies the cluster is actually online, refusing to stack a resize on top of an in-flight migration, and afterwards it polls until DigitalOcean reports the cluster healthy again, so the Slack confirmation means the capacity change really landed.

How it works

  1. check_cluster (io.kestra.plugin.digitalocean.database.Get) reads the cluster and exposes its status.
  2. stop_if_busy (io.kestra.plugin.core.execution.Fail) fails fast when the status is anything but online, protecting against overlapping operations when a previous resize is still running.
  3. resize_cluster (io.kestra.plugin.digitalocean.database.Resize) submits the resize with the size slug and node count received as inputs.
  4. wait_until_online (io.kestra.plugin.core.flow.LoopUntil) polls database.Get every 30 seconds until the cluster status returns to online, with a 45 minute ceiling that fails the run when exceeded, matching how long larger cluster migrations can take.
  5. notify posts the success to Slack; the errors block posts a distinct alert when the pre-check, the resize, or the completion poll fails.
  6. Two disabled-by-default Schedule triggers encode the policy, weekday mornings up to db-s-4vcpu-8gb with 2 nodes, weekday evenings down to db-s-2vcpu-4gb with 1 node, each simply passing different inputs to the same tasks.

What you get

  • Vertical scaling as code: the sizing policy lives in version-controlled YAML, not in someone's calendar reminder.
  • A pre-flight health check that prevents stacked resize operations from bricking a maintenance window.
  • Completion polling, so downstream automation and the on-call human both know when the cluster is actually back.
  • One reusable flow for scale-up, scale-down, and ad-hoc manual resizes with custom inputs.

Who it's for

  • Teams running DigitalOcean managed Postgres, MySQL, or Redis with pronounced business-hours load curves.
  • Startups controlling burn who want the bigger database only when customers are awake.
  • Platform engineers replacing untracked console clicks with auditable, scheduled capacity changes.

Why orchestrate this with Kestra

DigitalOcean has no native scheduled resize: the console offers a one-off manual action, and the API call returns immediately while the migration runs for many minutes in the background. Kestra supplies everything around that call that makes it safe to automate: schedules with per-trigger inputs, a health precondition, LoopUntil polling that turns the asynchronous migration into a synchronous step, Slack signaling on both outcomes, and an execution history showing every capacity change ever made to the cluster.

Prerequisites

  • A DigitalOcean managed database cluster and its UUID (visible in the console URL or via the API).
  • A personal access token with read and write scopes for databases.
  • A Slack incoming webhook.
  • Note that resizes to a smaller size are only possible when the target still fits your data, and brief connection interruptions can occur during migration; schedule the scale-down outside critical batch windows.

Secrets

  • DIGITALOCEAN_TOKEN: DigitalOcean personal access token.
  • SLACK_WEBHOOK_URL: Slack incoming webhook URL.

Quick start

  1. Add the two secrets above to your Kestra namespace.
  2. Set the database_id input default to your cluster UUID.
  3. Run the flow manually once with a small change to verify permissions and timing.
  4. Adjust the size slugs and cron expressions in both triggers to your load curve, then set disabled: false on each.

How to extend

  • Add a step querying your own metrics (CPU, connections) before resizing, skipping the scale-down when the evening is unexpectedly busy.
  • Chain a io.kestra.plugin.dbt or warehouse batch job after wait_until_online on the morning trigger, so heavy jobs always run on the larger size.
  • Apply the same pattern to droplets with droplet.Resize, which additionally requires a POWER_OFF action first.
  • Send the confirmation to PagerDuty or email instead of Slack by swapping the notification tasks.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.