Azure Backup and Snapshot Coverage Verifier
Daily, the flow uses Azure Resource Manager to verify that managed disks have a recent snapshot within the required RPO, flags any disk missing protection or with a stale recovery point, logs gaps to Dataverse, and alerts the platform team in Teams plus an email summary. Ensures critical workloads are actually recoverable.
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 verifies that Azure managed disks have a recent recovery point (snapshot) within the required RPO, using the Azure Resource Manager connector. It runs daily, lists every managed disk and every snapshot in the subscription, determines which disks lack a snapshot newer than the RPO window, logs each gap to a Dataverse table, and alerts the platform team in Teams plus an email summary.
Why it matters: "we have backups" is only true if recovery points are actually recent. A daily coverage check surfaces unprotected or stale-recovery-point disks before a failure proves them missing.
Ships Off (Stopped). Snapshot-based coverage avoids Recovery Services vault data-plane permissions.
Use Case
A platform / ops team needs assurance that every critical managed disk has a current, restorable recovery point, with gaps surfaced daily rather than discovered during an incident. The Dataverse table gives an auditable history of every gap, stamped with a per-run correlation id.
Flow Architecture
Daily Coverage Check
RecurrenceRuns the coverage check once per day (07:00 ET).
Initialize Config & Accumulators
Initialize variableMints a correlation id; binds subscription, ARM/Compute api-versions, RPO hours, Teams ids, alert email; seeds the recent-snapshot index, coverage-gaps array, and HTML rows.
List Disks & Snapshots
ARM - Resources_List (x2)Lists all Microsoft.Compute/disks and Microsoft.Compute/snapshots in the subscription.
Index Recent Snapshots
Apply to each + ARM GetById + ConditionReads each snapshot's timeCreated + source disk and keeps only those within the RPO window, keyed by lower-cased source disk id.
Flag Uncovered Disks
Apply to each + Filter array + Dataverse CreateRecordFor each disk, finds matching recent snapshots; if none, records a coverage gap in memory and writes a row to the Dataverse Backup Coverage Gap table.
Report (Teams + Email)
Compose + Teams + OutlookBuilds the HTML report (counts + gap table), posts the gap count to the platform channel, and emails the full report.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_AzureSubscriptionId | String | <your-subscription-id> | Subscription scanned for disks/snapshots. |
| flowlibs_ArmApiVersion | String | 2021-04-01 | API version for the generic ARM Resources_List call. |
| flowlibs_ComputeApiVersion | String | 2023-04-02 | API version for reading snapshot details (Microsoft.Compute). |
| flowlibs_BackupRpoHours | String | 24 | RPO window in hours; a disk is flagged with no snapshot newer than this. |
| flowlibs_TeamsGroupId | String | <your-team-id> | Teams team/group id for the alert channel. |
| flowlibs_TeamsChannelId | String | <your-channel-id> | Teams channel id for the alert channel. |
| flowlibs_AlertEmailRecipient | String | itadmin@yourcompany.com | Recipient of the daily coverage summary email. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Azure Resource Manager | shared_arm | Resources_List Resources_GetById |
| Microsoft Dataverse | shared_commondataserviceforapps | CreateRecord |
| Microsoft Teams | shared_teams | PostMessageToConversation |
| Office 365 Outlook | shared_office365 | SendEmailV2 |
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.
- Scope to a group or tag
- Add a resourceGroup or tag clause to the $filter on the disk/snapshot lists to limit the check to production targets.
- Tiered RPO
- Read a per-disk rpoHours tag inside the disk loop and compare against it instead of the single RPO value.
- Alert-only
- Wrap the Teams + email actions in a gap-count > 0 condition so they fire only when gaps exist.
- Cover VMs
- Add another Resources_List filtered to virtualMachines and correlate against Recovery Services restore points (requires that read scope).
- Pagination
- For very large subscriptions, follow nextLink in a Do Until to page through all results.
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.01Recent-snapshot gate (ticks)
Keeps snapshots within the RPO window.
EXPR.02Disk-to-snapshot match (case-insensitive)
Matches snapshots to their source disk.
EXPR.03Coverage gap test
A disk with no recent snapshot is a gap.
EXPR.04Snapshot short id for GetById
For the per-snapshot detail read.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.