Data Bear

Turn Off Fabric Capacities with Azure Data Factory

Semantic Model in Power BI
Why Turning Off Fabric Capacities Matters

Microsoft Fabric capacity is powerful  but it isn’t cheap.

If you’ve looked at pricing recently, you already know:

  • An F128 capacity can cost nearly $17,000 per month
  • An F16 capacity runs around $2,000 per month

If those capacities remain running overnight or during unused hours, you’re burning budget unnecessarily.

For organizations running Fabric for development, testing, or standard business hours analytics, automating capacity shutdowns can save thousands of dollars every month.

In this guide, you’ll learn how to:

  • Automatically turn off Fabric capacities using Azure Data Factory
  • Use Azure REST APIs to suspend capacities
  • Verify shutdown status programmatically
  • Send confirmation alerts to Microsoft Teams
  • Configure managed identity and RBAC correctly
  • Schedule automated daily shutdowns

If you’re serious about optimizing Power BI and Fabric costs, this is essential reading.

Why Use Azure Data Factory Instead of Fabric Pipelines?

You might ask:

“Why not just use Fabric pipelines to turn off Fabric capacities?”

Here’s the issue:

If a Fabric pipeline runs on a Fabric capacity — and that pipeline turns off the capacity — you create a circular dependency problem.

To solve this inside Fabric, you’d need:

  • A dedicated always-on capacity just to control other capacities.

That defeats the purpose of cost savings.

Why Azure Data Factory (ADF) Is Better

Azure Data Factory is ideal because:

  • You only pay for pipeline execution time
  • It runs outside Fabric capacity
  • It can call Azure Management REST APIs
  • It supports system-assigned managed identities
  • It integrates easily with Teams via webhooks

This makes ADF a cost-efficient orchestration tool for capacity management.

Architecture Overview

The solution works like this:

  1. Store a list of capacities in a CSV file (in Azure Data Lake Gen2)
  2. Use a Lookup activity to retrieve that list
  3. Loop through each capacity using a ForEach activity
  4. Check whether the capacity is running or paused
  5. If running → call the suspend API
  6. Verify the capacity is paused
  7. Send a Microsoft Teams alert
  8. Trigger this process daily at a scheduled time
Step 1: Build Your Capacity ListBuild Your Capacity List

Instead of using the Fabric API to retrieve capacities, we create our own controlled dataset.

Why?

The Fabric API does NOT return:

  • Resource Group
  • Subscription ID

But the Azure Management API requires:

  • Subscription ID
  • Resource Group
  • Capacity Name

So we store a CSV in Azure Data Lake Gen2 containing:

Capacity Name Resource Group Subscription ID

This gives us full control and allows selective shutdown (not all capacities).

Step 2: Use a Lookup Activity in Azure Data FactoryUse a Lookup Activity in Azure Data Factory

In ADF:

  • Add a Lookup activity
  • Connect it to your CSV file
  • Enable “First row as header”
  • Return all rows

The output will be a JSON array like:

[
  {
    "name": "Capacity1",
    "resourceGroup": "RG-Prod",
    "subscriptionId": "xxxx-xxxx"
  }
]

Understanding pipeline outputs is critical for chaining activities properly.

Step 3: Loop Through Capacities with ForEachLoop Through Capacities with ForEach

Add a ForEach activity and set the items property to:

@activity('LookupActivityName').output.value

This loops through each capacity object.

Step 4: Check Capacity Status Using Azure Management API

Inside the ForEach:

Add a Web Activity configured as:

  • Method: GET
  • Authentication: System Assigned Managed Identity
  • Resource: https://management.azure.com/
API Pattern
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Fabric/capacities/{capacityName}?api-version=2023-11-01

This returns a state property:

  • Paused
  • Resumed
Step 5: Add If Condition Logic

Create an If Condition:

@equals(activity('CheckCapacity').output.properties.state, 'Paused')
True Path (Already Paused)
  • Send Teams notification
  • Log confirmation
False Path (Currently Running)
  • Call Suspend API
  • Verify Pause
  • Send Teams confirmation
Step 6: Suspend the Capacity

Add another Web Activity:

  • Method: POST
Suspend Endpoint
.../capacities/{capacityName}/suspend?api-version=2023-11-01

This turns off the capacity.

Step 7: Verify Suspension (Best Practice)

Do NOT assume it worked.

Call the GET API again to confirm state = Paused.

This prevents false positives and ensures accurate notifications.

Step 8: Send Microsoft Teams Adaptive Card AlertSend Microsoft Teams Adaptive Card Alert

Create:

  • A string variable (e.g., AdaptiveCardJSON)
  • Use Set Variable activity
  • Build adaptive card JSON including:
    • Capacity name
    • State
    • Timestamp
    • Pipeline Run ID

Use a final Web Activity:

  • Method: POST
  • URL: Teams Webhook URL
  • Body: @variables('AdaptiveCardJSON')
Setting Up Teams Webhook

In Microsoft Teams:

  1. Go to your channel
  2. Click the ellipsis (…)
  3. Choose Workflows
  4. Select template: “Send webhook alerts to a channel”
  5. Copy generated webhook URL

Now you receive alerts like:

Fabric Capacity PW-Prod has been paused ✅

Step 9: Schedule with ADF Trigger

Create a Trigger:

  • Type: Schedule
  • Example: Daily at 6:00 PM

This ensures:

  • No capacities run overnight
  • No accidental cost leakage
  • Full automation
Step 10: Configure Managed Identity and RBAC

This is critical.

When you create Azure Data Factory, it includes a System Assigned Managed Identity.

You must:

  1. Go to the Resource Group (or Subscription)
  2. Create a Custom Role
  3. Add permissions under Microsoft.Fabric

Required permissions:

  • Read Fabric Capacity
  • Suspend Fabric Capacity
  • Resume Fabric Capacity (optional but recommended)

Then:

  • Assign this custom role to the ADF Managed Identity
  • Do this for each capacity you want to control

Without proper RBAC, API calls will fail.

Why Not Just Use the Fabric API?

The Fabric API can list capacities.

But it does NOT return:

  • Resource Group
  • Subscription ID

Since Azure Management API requires those values, you must maintain your own dataset.

This is actually beneficial because:

  • You control which capacities are automated
  • You avoid accidental global shutdown
  • You maintain governance
Advanced Improvements You Can Add
  • Morning Resume Pipeline
  • Slack Notifications
  • Logging to Azure Log Analytics
  • Failure Alerting
  • Parameterized Environments (Dev/Test/Prod)
  • Central Capacity Governance Dashboard in Power BI
Cost Savings Impact

If you shut down:

  • 1 × F16 nightly → Save thousands annually
  • Multiple F64/F128 capacities → Potential six-figure annual savings

Fabric costs add up fast. Automation protects your budget.

When to Implement This

This solution is ideal if:

  • You migrate to Microsoft Fabric
  • You run development capacities
  • Your workloads run during business hours only
  • You manage multiple client tenants
  • You want proactive cost governance

This is something we regularly implement in client environments to protect budgets and prevent overnight spend leakage.

Want to Master Fabric & Power BI?

If you’re looking to deepen your expertise in Fabric architecture, governance, cost optimization, and enterprise deployment strategies, check out:

Professional training helps you go beyond features and into real-world implementation best practices.