Blob Cross-Account Replication and Sync
On a schedule, the flow replicates new and changed blobs from a source account/container to a destination account (cross-region or cross-tenant), tracking sync state in Dataverse to copy only deltas (ETag comparison) and reporting counts to Teams. Provides controlled, auditable blob replication for DR or distribution.
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 provides controlled, auditable, delta-aware replication for Azure Blob Storage. On an hourly schedule it scans a source container, copies only new or changed blobs to a destination storage account, and writes an auditable sync-state row to Dataverse for every blob it replicates. Each run is stamped with a unique correlation id, and a summary is posted to Microsoft Teams.
Why it matters: built-in Azure replication (GRS / object replication) is account-scoped, all-or-nothing, and offers little run-level visibility. A flow-based approach gives targeted, container-level DR or content distribution with per-blob delta detection, a Dataverse audit trail, and operational reporting - portable across tenants by changing only env-var values.
Ships Off (Stopped).
Use Case
A team needs specific containers replicated to another storage account (cross-region or cross-tenant) on a schedule, copying only what has actually changed, with a record of what was copied and when. Typical drivers: disaster-recovery staging, content distribution to a secondary region, or feeding a downstream system from a curated container.
Flow Architecture
Hourly Recurrence
RecurrenceReplication cadence - runs hourly.
Initialize Trace, Config & Counters
Initialize variableMints a correlation id; binds source/destination accounts + containers and Teams ids; seeds replicated/skipped counters.
List & Filter Source Blobs
Azure Blob ListFolder_V4 + Filter arrayLists the source container and drops subfolder entries (files only).
For Each Source Blob
Apply to each (concurrency 1)Looks up the latest Dataverse sync row for the blob path; if no prior row or the source ETag differs, reads the bytes, writes them to the destination dataset, records an auditable sync-state row (ETag/size/timestamps/correlation id), and increments replicated; otherwise increments skipped.
Compose & Post Summary
Compose + TeamsPosts replicated/skipped counts and the correlation id to the ops channel.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_SourceStorageAccount | String | criticaldatastore | Source account name (read dataset). |
| flowlibs_SourceContainer | String | /critical-data | Source container path scanned. |
| flowlibs_DestStorageAccount | String | replicastore | Destination account name (write dataset). |
| flowlibs_DestContainer | String | /critical-data-replica | Destination container path. |
| flowlibs_TeamsGroupId | String | <your-team-id> | Teams team (group) id for the summary. |
| flowlibs_TeamsChannelId | String | <your-channel-id> | Teams channel id for the summary. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Azure Blob Storage | shared_azureblob | ListFolder_V4 GetFileContentByPath_V2 CreateFile_V2 |
| Microsoft Dataverse | shared_commondataserviceforapps | ListRecords 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.
- Cadence
- Change the hourly recurrence (e.g. daily off-hours for DR staging).
- Multiple destinations
- Wrap the copy/log block in a second Foreach over a comma-split destination list to fan out to several targets.
- Conflict policy
- Current rule is newer-ETag-wins; switch to a Last-Modified comparison instead of ETag.
- Deletes
- Add a second pass that lists destination blobs and tombstones/removes those no longer present at source.
- Large blobs
- Replace the read+write pair with a SAS-based server-side Copy Blob (HTTP to the Blob REST API with a source SAS) to avoid pulling bytes through the flow.
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.01Files only
Drops subfolders from the source listing.
EXPR.02Delta condition
Copy when new or the ETag changed.
EXPR.03Lookup filter
Latest sync row for the blob path (top 1, desc).
EXPR.04Replicate body
Source bytes written to the destination dataset.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.