< Back to blog

Implementing CI/CD for Microsoft Fabric with Azure DevOps: A Practical End-to-End Tutorial

Portrait-Robert

Roberto

Hernández

Jiménez

November 6, 2026
•
30 min

Introduction

As Microsoft Fabric projects grow in complexity, managing changes across development, testing, and production environments becomes increasingly challenging. Data engineers and analytics teams need a reliable way to promote changes, maintain version control, validate features before release, and ensure production stability.

Continuous Integration (CI) and Continuous Deployment (CD) are established practices that help development teams automate and standardize these processes. However, implementing CI/CD in Microsoft Fabric introduces unique considerations, as not every Fabric item supports deployment in the same way, and different deployment mechanisms provide varying levels of functionality.

In this tutorial, we will build a complete CI/CD workflow for Microsoft Fabric using Azure DevOps and the Microsoft-supported fabric-cicd deployment framework. Through a realistic supply chain scenario, we will demonstrate how to:

  • Synchronize Fabric workspaces with Git.
  • Manage multiple deployment environments.
  • Configure Azure DevOps repositories and pipelines.
  • Automate deployment of Fabric items across environments.
  • Implement approval gates for production readiness.
  • Understand common deployment limitations and workarounds.

By the end, you will have a repeatable framework that can be adapted to real-world Fabric projects.

Understanding CI and CD

What is Continuous Integration (CI)?

Continuous Integration is the practice of continuously incorporating code and solution changes into a shared repository. Changes are versioned, tracked, and validated before being promoted to higher environments.

In Microsoft Fabric, CI is commonly achieved using Git Integration, where workspace items are synchronized with a source control repository in Azure DevOps or GitHub.

What is Continuous Deployment (CD)?

Continuous Deployment focuses on moving approved changes from one environment to another through automated deployment pipelines.

For Fabric projects, CD can involve:

  • Deployment Pipelines
  • Azure DevOps automation
  • Fabric REST APIs
  • Hybrid deployment strategies

Why CI/CD Matters in Fabric Projects

Without CI/CD:

  • Workspace changes become difficult to track.
  • Rollbacks are complicated.
  • Testing is inconsistent.
  • Production deployments carry higher risk.

With CI/CD:

  • Every change is version controlled.
  • Promotion between environments is standardized.
  • Deployment history is recorded.
  • Releases become repeatable and auditable.

Available Deployment Approaches in Microsoft Fabric

There is no single deployment strategy that supports every Fabric artifact equally.

Option 1: Fabric Deployment Pipelines

Pros

  • Native Fabric experience
  • No code required
  • Easy setup

Cons

  • Limited customization
  • Not all items are supported equally

Option 2: Azure DevOps + fabric-cicd (Recommended)

The fabric-cicd is a Python library designed to deploy Microsoft Fabric items from a repository into a workspace.  

Pros

  • Good balance of automation and control
  • Git-based workflow
  • Microsoft-maintained tooling
  • Suitable for enterprise environments

Cons

  • Requires Azure DevOps expertise
  • Requires initial pipeline setup

Option 3: Direct Fabric REST APIs

Pros

  • Maximum flexibility
  • Full customization

Cons

  • Significant development effort
  • More maintenance overhead

Option 4: Hybrid Deployment

In practice, many organizations use a hybrid approach because some Fabric items may require additional manual configuration after deployment.

Important: CI, deployment, and post-deployment configuration are three separate concerns. Some items may still require manual configuration after deployment, such as permissions, connections, credentials, or environment-specific settings.

Solution Architecture

This tutorial uses Azure DevOps as the deployment orchestrator while Microsoft Fabric serves as the analytics platform.

High-Level Flow

Azure DevOps and Fabric deployment workflow Continuous integration across dev, preprod, and prod branches, with Git synchronization and automated deployment to Fabric workspaces, pipelines, lakehouse tables, semantic models, and external resources. Azure DevOps CONTINUOUS INTEGRATION dev/ preprod/ prod/ PR into Preprod PR into Prod Fabric Git-Synced to Dev Branch Automated Deployment to PreProd Automated Deployment to Prod DevWorkspace PreProdWorkspace ProdWorkspace CONTINUOUS DEPLOYMENT Pipeline Lakehouse Semantic Model External resources * DevPipeline PreProdPipeline ProdPipeline DevTable PreProdTable ProdTable DevSemanticModel PreProdSemanticModel ProdSemanticModel ... ... ... ... Dev PreProd Prod * External resources can be Referenced in the Fabric CD cycle using Variable Libraries. Dedicated resources per environment is recommended

Figure 1. High level of CI/CD Architecture using Azure DevOps.

The architecture follows these principles:

  1. Development workspace is connected and synced to Git.
  2. Fabric Git Integration is the source of truth for workspace content.
  3. Pre-Production and Production workspaces are not Git-connected.
  4. Azure DevOps pipelines deploy content using Fabric APIs through the fabric-cicd python library.
  5. Approval gates through Azure DevOps environments and branch policies are possible.
  6. Git branches provide a historical record of promoted versions.

Typical workflow

Developers work on features and items in the Development (Dev) Workspace in Fabric and changes are synced to the Dev branch in Azure DevOps. When features or items are ready for testing, a PR (Pull Request) is created to merge the Dev branch into the Pre Production (PreProd) branch, which, upon approval, triggers the item deployment through the Azure DevOps deployment pipeline, which includes item type selection and approval gates configured in Azure DevOps environments.  

Demo Scenario: OmniRoute Logistics

To demonstrate the deployment process, we will use a fictional company named OmniRoute Logistics.

OmniRoute transports:

  • Computer equipment
  • Electronics
  • Office supplies

across multiple warehouses located throughout the United States.

Developers work with limited datasets in Development, while broader datasets are available in Pre-Production and Production environments.

Figure 2. OmniRoute is a ficticious company that transports Computer Accessories, Electronics and Office Equipment. The PowerBI Report in this picture reflects underlying data and configurations that the Dev team works with.

Environment Setup

CI/CD Environment Model

This tutorial uses three environments:

Environments and Purposes
Environment Purpose
Development (Dev) Feature development
Pre-Production (PreProd) Validation and user acceptance
Production (Prod) Live environment

Table 1. Environment distribution.  

Fabric Workspaces

Environment Workspaces and Access
Environment Workspace Git Sync Recommended Access
Development OmniRoute__Dev Yes Developers and Technical Lead
Pre-Production OmniRoute__PreProd No Account Leads, Technical Leads, Managers
Production OmniRoute__Prod No Account Leads, Business Users

Table 2. Workspace distribution.

We will work with three Workspaces only. If a Medallion Architecture is implemented, more Workspaces are needed. That is outside the scope of this tutorial.  

Fabric Solution Components

The Fabric solution contains several interconnected items, listed in Table 3.

Items and Purposes
Item Purpose
Supply_Chain_Database Mock external source system
OmniRoute_Lakehouse Main data repository
Supply Chain Daily Pipeline Data orchestration
Supply Chain Data Notebook Data generation and processing
Supply Chain Variable Library Environment-specific configuration
OmniRoute Semantic Model Business data model
OmniRoute Report Reporting and visualization

Table 3. Fabric Items in the OmniRoute Workspace.

Figure 3. Fabric components in the OmniRoute Workspace
Figure 4. Fabric components. Each Dev, PreProd and Prod Workspaces will have these items, but PreProd and Prod items will be deployed through the deployment pipeline

Repository Download

To follow along this tutorial, you can manually create the Fabric items or you can download all the Fabric configuration from the following repository:

GitHub Repository Link

You can also simplify or customize to your use case.  

Step 1: Configure Git Integration

The first objective is to connect the Development workspace with Azure DevOps.

Prerequisites

  • An Azure DevOps organization and project
  • An Azure DevOps Git repository named Fabric_CICD_Experiment
  • The OmniRoute_Dev Workspace

If you are following this tutorial, it is recommended to keep the same names of the resources, but you can use any names if you prefer. Also, the Workspace can be empty at the beginning, and any development like creation and configuration of items can be synced later.

Configure Workspace Git Sync

In the OmniRoute_Dev Workspace, navigate to Workspace Settings→ Git Integration

Configure:

  • Git Provider: Azure DevOps
  • Organization and Project
  • Repository: Fabric_CICD_Experiment
  • Branch: dev
  • Folder: fabric

Then select Connect and Sync.

Figure 5. Fabric Git Integration Configuration

The sync process will begin. The first time, the Fabric data will be sent to the dev branch in the repository.  After synchronization:

  • The Fabric workspace shows Git status indicators.
  • The repository contains a fabric folder.
  • All Fabric items become version controlled.
Figure 6. Successful Git Sync.

Step 2: Configure Azure DevOps Branches

The repository contains three primary branches

Branches and Purposes
Branch Purpose
dev Development
preprod Pre-Production
prod Production

Table 4. Fabric Items in the OmniRoute Workspace.

Create the PreProd Branch

  1. Open Azure DevOps.
  2. Navigate to Repos > Branches.
  3. Select New Branch.
  4. Name it: preprod
  5. Base it on dev.

Create the Prod Branch  

Repeat the same process to create prod from preprod.  

Step 3: Configure Deployment Libraries

In this demo, we will use one single pipeline that will detect the deployment stages and execute accordingly.  We will base the deployment solution on the popular deploy-to-fabric.py script release by Microsoft as a starting point (full customization is possible). Also, we will use the deploy-to-fabric.yml yaml pipeline that fully describes the steps that the deployment process should follow, like triggers, parameters, variables, and stages. The final configuration of those files can be obtained in the project repository (LINK to DEV Git).  

Azure DevOps variable groups centralize pipeline configuration, and we will separate sensitive information from non-sensitive information.  

Non-Sensitive Variables

Create the fabric_cicd_group_non_sensitive variable group. For this tutorial, add the following variables:

Deployment Variables
Variable Value Description
devWorkspaceName OmniRoute__Dev Dev Workspace. Adjust to your Dev Workspace name.
preprodWorkspaceName OmniRoute__PreProd Dev Workspace. Adjust to your PreProd (Test, SIT, UAT, etc.)
prodWorkspaceName OmniRoute__Prod Dev Workspace. Adjust to your Prod Workspace name.
gitDirectory fabric Folder or path within the Git repository that will hold all the…

Table 5. Non-sensitive variables.

These variables will be called by the python script during the deployment process, so it's critical that they are named like this

Figure 7. Non-Sensitive Variable Group.

Sensitive Variables

Create the fabric_cicd_group_sensitive variable group with the following variables:

Service Principal Variables
Variable Value Description
azclientid Service Principal Client ID Service Principal Client ID. Needed for the Client Secret Credentials auth flow.
azspnsecret Service Principal Client Secret Service Principal Client Secret. Needed for the Client Secret Credentials auth flow.
aztenantid Service Principal Tenant ID Service Principal Tenant ID. Needed for the Client Secret Credentials auth flow.

Table 6. Sensitive variables.

Linking to an Azure key vault is recommended, but hard-coded values as variables (no linked key vault) is also possible; if so, treat variables as secrets in this variable group.   

Figure 7. Sensitive Variable Group.

Step 4: Configure Service Principal Access

Before deployments can work, the Service Principal must have permission to deploy Fabric items.

Enable Fabric API Access

Navigate to:

  • Admin Portal > Tenant Settings > Developer Settings

Enable:

  • Service principals can use Fabric APIs

Workspace Permissions

Grant the Service Principal Member access to:

  • PreProd Workspace
  • Prod Workspace
Figure 8. Workspace Permission Assignment. Add to PreProd and Prod Workspaces only.

Step 5: Configure Azure DevOps Pipeline

This tutorial uses a single YAML deployment pipeline. The pipeline executes the deploy-to-fabric.yml and deploy-to-fabric.py files.

Repository Link

Create the Pipeline

  1. Pipelines > New Pipeline
  2. Azure Repos Git
  3. Select repository
  4. Existing YAML File
  5. Select: pipelines/deploy-to-fabric.yml
  6. Save
Figure 9. Azure DevOps Deployment Pipeline.

IMPORTANT

  1. Make sure to have the proper branches and path in the trigger section of deploy-to-fabric.yml
  1. Under parameters in the deploy-to-fabric.yml file, items_in_scope should have a default value like:

‘[“Notebook”,"DataPipeline","Lakehouse","SemanticModel","Report","VariableLibrary"]'

to include a default list of supported Fabric items to be deployed in that run.  

  1. Make sure to have the variable groups properly configured.
  1. Make sure to have the scriptPath path point the exact location of deploy-to-fabric.py in the repo (scripts/deploy-to-fabric.py, in this case).

Step 6: Configure Approval Gates

Approval gates introduce governance and release control. We will have 2 Azure DevOps environments that will serve as approval gates when deploying from one stage to the other.    

Create Environments

Create the preprod and prod environments under Pipelines>Environments.  

For each environment:

  • Configure approvers
  • Configure checks
  • Set timeout values
Figure 10. PreProd Approval Gate.

Step 7: Configure the Deployment Script

The deployment mechanism relies on deploy-to-fabric.py. Important considerations are:

  • scriptPath in the PythonScript task of deploy-to-fabric.yml must point to the correct script (e.g., scripts/deploy-to-fabric.py).  
  • Service Principal authentication must be properly configured in the corresponding variable group. Alternatively, DefaultAzureCredential can be used, though it is not recommended for Production. If using it, add an az login command to the YAML to authenticate at runtime.  
  • Workspace variables in fabric_cicd_group_non_sensitive must include the correct [env]WorkspaceName values (e.g., devWorkspaceName, preprodWorkspaceName, prodWorkspaceName) for the target Fabric workspaces.  
  • gitDirectory in fabric_cicd_group_non_sensitive must point exactly to the repository folder where the Fabric data is stored—the folder selected when Fabric was initially linked to Azure DevOps.  

⚠️Critical Warning

unpublish_all_orphan_items must be used with caution. Disable it if you are unsure of its implications, as it can delete items from the target workspace even if those items are not part of the current release branch.

Always validate the implications before enabling this setting.

Step 8: Deploy to Pre-Production

There are two deployment approaches:

  1. Manual deployment
  2. Pull Request deployment

Option A: Manual Deployment

Navigate to Pipelines > Run Pipeline and select preprod as the target branch.

Use default deployment scope:

["Notebook","DataPipeline","Lakehouse","SemanticModel","Report","VariableLibrary"]

Run. You can see the running state by clicking on the current run. There, approve any requested resources and approval gates.

Figure 11. View the running state of a deployment pipeline and approve any resources and approval gates.

Once completed:

  • Fabric items appear in the PreProd workspace.
  • Validation in the Workspace can begin.

Validating the Deployment

Open the PreProd variable library and activate the PreProd value set. This can also be configured as parameters in the deployment process, but that's outside the scope of this tutorial.

Figure 12. View the running state of a deployment pipeline and approve any resources and approval gates.  

Next, open the Supply Chain Data notebook and add the OmniRoute_Lakehouse as Default lakehouse. This configuration can be also automated in the deployment pipeline using parameters, but that's not in the scope of this demo. Lastly, open the Supply Chain Daily Pipeline pipeline and make sure the connection the Copy Data Activity has, points to the correct source and destination (items in the PreProd Workspace). Then run the pipeline. The Variable Library automatically detects the environment and uses environment-specific settings when the notebook in the pipeline is running.  

Figure 13. Run the pipeline to generate or refresh the Workspace data based on environment values.

When the pipeline finishes, open the report and verify:

  • Data refresh succeeds.
  • Environment-specific records appear.
  • Visuals behave as expected.
Figure 14. The PreProd report shows data that is environment-aware.

Step 9: Deploy to Production

For production-grade workflows, deployments should be triggered through Pull Requests (PR). For example, once testing is completed in the PreProd Workspace, you can request to promote to Production.  We will explore so in this demo using Pull Requests.

Option B: via Pull Requests (recommended)

  1. Create PR
  2. Add reviewers
  3. Complete approval process
  4. Merge
Figure 14. Pull Request to merge PreProd into Prod.
Figure 15. When a PR is approved, the deployment pipeline will be triggered and start the deployment process. This is how the flow in production must run.

The merge triggers the deployment pipeline automatically.

After approval:

  • Pipeline executes
  • Approval gate pauses execution
  • Deployment proceeds
  • Changes become available in the target Workspace
Figure 16. Approve access to any required resource; in this case, the prod Azure DevOps environment. This is necessary usually the first time only.
Figure 17. Approve any other approval gate; in this case, the one configured in the prod Azure DevOps environment.

Run any required post-deployment activities:

  • Variable Library configuration
  • Notebook configuration with default Lakehouse
  • Copy Data activity configuration of source and destination in the Data Pipeline
  • Data pipeline execution
  • Semantic model validation

At the end, you should be able to open the Prod report and see that the data is showing as expected, according to the Production Workspace and connected Production components.

Figure 18. The PowerBI Report in Production shows all the live data.

Common Considerations and Limitations

Hybrid approach

Microsoft Fabric is evolving rapidly, with new features and item types being introduced frequently. However, not all of them have the same level of support across Fabric Deployment Pipelines, Azure DevOps Pipelines using the fabric-cicd Python library, or the Fabric APIs directly. Therefore, a hybrid approach is often necessary.

Manual configurations

Some items require manual configuration or additional initialization related to specific settings, such as a Default Lakehouse in a Notebook (if needed), the Active Value Set in Variable Libraries, or connections and credential setup in Data Pipelines and Semantic Models.

For larger projects, parameterization can reduce manual configuration requirements and improve environment portability. Parameterization is supported to some extent by the fabric-cicd Python library, but it is not covered in this tutorial.

Results

The completed solution provides:

✅ Source-controlled Fabric assets

✅ Automated deployment process

✅ Approval-based promotion

✅ Environment-specific configuration

✅ Reduced deployment risk

✅ Repeatable release management

Conclusions

Microsoft Fabric provides several deployment mechanisms, but Azure DevOps combined with the fabric-cicd framework offers one of the most flexible and enterprise-ready approaches currently available.

The strategy demonstrated in this tutorial separates development, validation, and production concerns while maintaining full traceability through Git branches and deployment pipelines. By connecting only the Development workspace to source control and deploying to higher environments through automation, organizations can reduce operational risks while gaining visibility into release history.

It is important to remember that deployment itself is only one part of the release process. Environment-specific configuration, permissions, credentials, semantic model connections, and operational validation may still require additional steps. Planning for those activities early is essential to achieving a fully reliable deployment process.

For teams adopting Microsoft Fabric at scale, this CI/CD pattern provides a solid foundation that can be expanded with automated testing, parameterization, advanced release governance, and Infrastructure-as-Code practices.

References

Microsoft Learn

Microsoft fabric-cicd

Demo Assets