List icon
ForEach icon
Copy icon
SlackIncomingWebhook icon
Pause icon
DeleteList icon
Schedule icon

Weekly Azure Blob Backup Archive with Gated Expiry Cleanup

Automate a weekly Azure Blob backup archive with Kestra. Copy blobs into a dated archive prefix, notify Slack, and gate the destructive retention cleanup behind human approval.

Categories
CloudInfrastructure

A backup process that runs unattended end to end, including the deletion step, is one bad prefix away from destroying data nobody can recover. This blueprint splits the two halves of a backup rotation: the archive copy runs fully automated every week, and only the genuinely destructive step, deleting backups past retention, waits for a named reviewer to resume the execution. Azure Storage's own geo-redundant replication (GRS or RA-GRS on the storage account) already handles copying the data to the paired region; this flow's job is the archive bookkeeping, the notification, and the approval gate around the one step that cannot be undone.

How it works

  1. The weekly io.kestra.plugin.core.trigger.Schedule fires every Sunday at 03:00.
  2. list_container (io.kestra.plugin.azure.storage.blob.List) enumerates the backups container, up to 1,000 blobs per run.
  3. archive_each_blob (io.kestra.plugin.core.flow.ForEach) iterates the listed blob names, and copy_to_archive (io.kestra.plugin.azure.storage.blob.Copy) copies each one into a dated archive/{{ execution.startDate | date('yyyy-MM-dd') }}/ prefix in the same container, an ordinary same-account copy the plugin genuinely supports.
  4. notify_archived posts the archived count to Slack, so the team sees the run happened before the approval step is even reached.
  5. approval_gate (io.kestra.plugin.core.flow.Pause) stops the execution. This is the one step in the whole flow that a human reviews, because it precedes the destructive delete.
  6. delete_expired (io.kestra.plugin.azure.storage.blob.DeleteList) only runs after a reviewer resumes the execution, removing blobs under the archive/expired/ prefix.

What you get

  • Weekly archiving that runs completely unattended, with no human gate on the safe, non-destructive half of the job.
  • A named reviewer required before anything is permanently deleted, logged on the execution.
  • A Slack notification that lands before the approval gate, so reviewers see the archive count while deciding.
  • One execution history spanning the archive copy, the notification, and the eventual cleanup.

Who it's for

  • Platform and storage teams running scheduled backup rotations on Azure Blob Storage.
  • Compliance-conscious teams who need an audited, named approval before any backup deletion.
  • Teams replacing a cron script and a lifecycle management policy with a single auditable flow.

Why orchestrate this with Kestra

Azure Storage lifecycle management policies can expire blobs automatically, but they cannot notify a team first, pause for a named human review, or tie the archive copy and the eventual cleanup to one execution history. Kestra runs the archive copy unattended, notifies Slack with the count, then uses a Pause task to stop before the one irreversible step, recording exactly who resumed it and when, all in one auditable execution.

Prerequisites

  • A Storage account with a backups container to archive.
  • A Slack incoming webhook for notifications.
  • Geo-redundant replication (GRS or RA-GRS) configured on the storage account if cross-region durability is required; this flow does not perform that replication itself.

Secrets

  • AZURE_STORAGE_CONNECTION, AZURE_STORAGE_ENDPOINT: Storage account credentials.
  • SLACK_WEBHOOK_URL: Slack incoming webhook URL.

Quick start

  1. Add the secrets above to your Kestra instance.
  2. Set container to your real backup container name.
  3. Confirm your retention policy for what counts as expired under archive/expired/.
  4. Enable the weekly schedule trigger, and assign a reviewer who is expected to resume the execution after checking the Slack notification.

How to extend

  • Add a size or count threshold check before the approval gate, alerting if an archive run is unusually large or small.
  • Chain a verification read after copy_to_archive that spot-checks a sample blob's checksum before notifying.
  • Replace the fixed weekly cron with a Flow trigger so archiving runs right after your primary backup job finishes.
  • Route the approval notification to a dedicated on-call or compliance channel instead of a general Slack channel.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.