Blob Lifecycle Tiering and Cleanup
On a schedule, the flow scans an Azure Blob folder, moves blobs to cool/archive folders based on age, deletes expired blobs per retention, logs each action to Dataverse, and reports counts and bytes reclaimed to Teams. Automates cost-saving lifecycle management with a full audit trail.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
This flow automates cost-saving lifecycle management for Azure Blob Storage. On a daily schedule it scans a configured source folder, evaluates each blob's age, and applies a single mutually-exclusive lifecycle action - tier to Cool, tier to Archive, or delete (retention) - then writes an audit row to Dataverse for every action and posts a run summary (counts + bytes reclaimed) to a Microsoft Teams channel.
Why it matters: keeping cold data on hot-tier storage is expensive. Rule-driven, reportable tiering and cleanup cut storage cost while keeping the process auditable and portable across tenants.
Ships Off (demo). The connector cannot set native access tiers, so tiering is folder-based moves (copy + delete); see customizations to drive true Hot/Cool/Archive tiers.
Use Case
IT admins and developers want automated, reportable tiering and retention enforcement across a storage account without hand-managing files or relying solely on static lifecycle policies.
Flow Architecture
Daily Lifecycle Sweep
RecurrenceRuns daily at 02:00 Eastern.
Initialize Config, Thresholds & Counters
Initialize variable (x19)Mints a correlation id; binds the storage account, source/cool/archive folders, Teams ids, and log table; sets the cool/archive/delete day thresholds (30/90/365) and run counters + HTML accumulator.
List Source Blobs
Azure Blob - ListFolder_V4Lists the source folder (returns LastModified and Size per blob).
For Each Blob
Apply to each (concurrency 1)For files only: computes age in days and chooses one mutually-exclusive action (highest threshold first): delete >= delete days, else archive, else cool, else skip.
Apply Action + Log
Azure Blob Delete/Copy + Dataverse CreateRecordDeletes expired blobs or copies-then-deletes (move) to the cool/archive folder, increments the matching counter and bytes, and writes an audit row + HTML summary row when an action was taken.
Compose & Post Summary
Compose + TeamsBuilds the per-tier counts + bytes-reclaimed card and posts it to the Teams channel.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_BlobStorageAccount | String | flowlibsdemostorage | Azure Storage account name (Blob dataset). |
| flowlibs_BlobSourceFolderPath | String | /lifecycle-source | Root folder scanned for lifecycle evaluation. |
| flowlibs_BlobCoolFolderPath | String | /lifecycle-cool | Destination folder for blobs tiered to Cool. |
| flowlibs_BlobArchiveFolderPath | String | /lifecycle-archive | Destination folder for blobs tiered to Archive. |
| flowlibs_TeamsGroupId | String | <your-team-id> | Teams team (group) id for the summary post. |
| flowlibs_TeamsChannelId | String | <your-channel-id> | Teams channel id for the summary post. |
| flowlibs_BlobLifecycleLogTable | String | flowlibs_bloblifecycleactionlogs | Dataverse entity-set name of the audit-log table. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Azure Blob Storage | shared_azureblob | ListFolder_V4 CopyFile_V2 DeleteFile_V2 |
| Microsoft Dataverse | shared_commondataserviceforapps | CreateRecord |
| Microsoft Teams | shared_teams | PostMessageToConversation |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Native access tiers
- Replace the folder-move actions with an ARM/HTTP Set Blob Tier call, or point the cool/archive folders at containers governed by an Azure lifecycle-management policy.
- Access-based tiering
- Decide on last-accessed time rather than LastModified (requires last-access tracking on the account).
- Per-container rules
- Drive thresholds from a Dataverse config table (one row per container) instead of fixed Initialize Variables.
- Legal hold
- Add a check to skip blobs flagged for legal hold before deleting.
- Recursion
- Extend the listing to walk sub-folders if the source tree is nested.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Blob age in days
Whole days since last modified.
EXPR.02Lifecycle decision
Highest threshold first: delete, else archive, else cool.
EXPR.03Archive destination path
Move destination for archived blobs.
EXPR.04Bytes reclaimed to MB
For the summary card.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.