<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article Azure DevOps with Databricks DABs: Step-by-Step Integration Guide in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/ba-p/141451</link>
    <description>&lt;P&gt;&lt;SPAN&gt;Establishing a trusted &lt;/SPAN&gt;&lt;STRONG&gt;&lt;I&gt;Continuous Integration/Continuous Deployment (CI/CD)&lt;/I&gt;&lt;/STRONG&gt; &lt;SPAN&gt;process is crucial for effectively managing the lifecycle of your data and AI workloads in Azure Databricks. However, with numerous setup options and a constantly evolving platform, the big question is, "Where do I even start?" This comprehensive blog cuts through the complexity to outline a &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/ci-cd/best-practices" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;recommended CI/CD approach&lt;/STRONG&gt;&lt;/A&gt; &lt;SPAN&gt;for Azure Databricks.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="jim_thorstad_0-1776186435312.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/25999i080FF82107D99CC4/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jim_thorstad_0-1776186435312.png" alt="jim_thorstad_0-1776186435312.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;We focus on the latest best practices that support strong governance with minimal administrative overhead, even when &lt;/SPAN&gt;&lt;STRONG&gt;supporting&lt;/STRONG&gt; &lt;STRONG&gt;multiple teams in a shared infrastructure&lt;/STRONG&gt;&lt;SPAN&gt;. It's tailored for developers who enjoy working in the Databricks workspace UI, though it also fully supports IDEs like Visual Studio Code.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The recommended approach uses &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/bundles/" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Declarative Automation Bundles&lt;/STRONG&gt;&lt;/A&gt; &lt;SPAN&gt;(DABs; formerly known as Databricks Asset Bundles) for deployment. Bundles seamlessly integrate with &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/repos/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Databricks Git Folders&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; for version control, Azure DevOps for automation, and Azure DevOps service connections for Databricks connectivity. At the end of the blog, I compare the DevOps service connection and Databricks OIDC approaches for integrating DevOps and Databricks for your reference.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Finally, we’ll follow a &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/ci-cd/best-practices#branching-strategy" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;simple but effective trunk-based branching strategy&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; in DevOps.&amp;nbsp; Staging will be deployed automatically after feature branch pull requests are approved and merged into main. Production deployment from main will be contingent on a successful staging deployment and will require an additional approval step, which we will implement.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_1-1776186629097.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26001iF57EF441D810B508/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_1-1776186629097.png" alt="jim_thorstad_1-1776186629097.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;This blog covers a wide range of topics, but by guiding you toward the optimal choices, it will save you significant time and effort in the long run. The content is divided into three parts:&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Aligning your infrastructure and governance requirements&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Setting up a versioned bundle development process&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Setting up an Azure DevOps pipeline for deployment to staging and production&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;H1&gt;&lt;SPAN&gt;Part 1: Align Your Infrastructure and Governance Requirements&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;SPAN&gt;Every organization needs to decide what level of separation and organization is required for Databricks workspaces, deployment environments, Unity Catalog, DevOps projects, and Git repositories. There is no one right answer for every organization, and we can only touch on the considerations before moving on to the article's topic.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="121px" height="50px"&gt;
&lt;P&gt;&lt;STRONG&gt;Topic&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="355px" height="50px"&gt;
&lt;P&gt;&lt;STRONG&gt;Consideration&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="344px" height="50px"&gt;
&lt;P&gt;&lt;STRONG&gt;For This Article&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="121px" height="77px"&gt;
&lt;P&gt;&lt;SPAN&gt;Environments&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="355px" height="77px"&gt;
&lt;P&gt;&lt;SPAN&gt;Three is common, but some may use two, and others four or more.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="344px" height="77px"&gt;
&lt;P&gt;&lt;SPAN&gt;We’ll use: &lt;/SPAN&gt;&lt;STRONG&gt;dev, staging, and prod&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="121px" height="289px"&gt;
&lt;P&gt;&lt;SPAN&gt;Databricks Workspaces&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="355px" height="289px"&gt;
&lt;P&gt;&lt;SPAN&gt;Generally, workspaces align with environments. Larger organizations may also organize business units in separate workspaces.&lt;/SPAN&gt;&lt;/P&gt;
&lt;BR /&gt;
&lt;P&gt;&lt;SPAN&gt;An advantage of three workspaces is that the workspace admin can freely enable &lt;/SPAN&gt;&lt;STRONG&gt;preview features&lt;/STRONG&gt;&lt;SPAN&gt; and other settings in the “dev” workspace and be certain not to affect the staging and prod workloads.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="344px" height="289px"&gt;
&lt;P&gt;&lt;SPAN&gt;We’ll show how multiple independent teams can use two workspaces (&lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-dev&lt;/FONT&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-prod&lt;/FONT&gt;&lt;SPAN&gt;) with reasonable governance. Staging will deploy to a secure folder in the dev workspace.&lt;/SPAN&gt;&lt;/P&gt;
&lt;BR /&gt;
&lt;P&gt;&lt;SPAN&gt;You can follow along and use 3 workspaces with dev, staging, and prod, each in its own workspace.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="121px" height="132px"&gt;
&lt;P&gt;&lt;SPAN&gt;Catalogs&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="355px" height="132px"&gt;
&lt;P&gt;&lt;SPAN&gt;There are many strategies for organizing your data in Unity Catalog.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="344px" height="132px"&gt;
&lt;P&gt;&lt;SPAN&gt;We’ll name our catalogs &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_dev&lt;/FONT&gt;, &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_stg&lt;/FONT&gt;, &lt;SPAN&gt;and&amp;nbsp;&lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_prd&lt;/FONT&gt;,&lt;SPAN&gt; demonstrating how independent business units can operate within a single Unity Catalog metastore.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="121px" height="160px"&gt;
&lt;P&gt;&lt;SPAN&gt;Azure DevOps Projects&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="355px" height="160px"&gt;
&lt;P&gt;&lt;SPAN&gt;Smaller organizations use a single project to simplify setup, while larger organizations may require multiple projects to have hard boundaries between code repositories and approvers.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="344px" height="160px"&gt;
&lt;P&gt;&lt;SPAN&gt;We’ll use a project called &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-team1&lt;/FONT&gt;,&lt;SPAN&gt; allowing for independent teams (e.g., HR, Legal, Finance) within a “corporate” BU to operate securely within the shared workspaces alongside other BU teams.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD width="121px" height="105px"&gt;
&lt;P&gt;&lt;SPAN&gt;Git Repository&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="355px" height="105px"&gt;
&lt;P&gt;&lt;SPAN&gt;There are pros and cons for a single “mono repo” versus multiple team or domain-based repos.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD width="344px" height="105px"&gt;
&lt;P&gt;&lt;SPAN&gt;Since we have already selected a team-based DevOps project, we’ll use its single &lt;/SPAN&gt;&lt;STRONG&gt;default repo&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&lt;SPAN&gt;Note: I encourage you to follow the example and organizational strategy outlined in this blog to see how the whole process works together effectively. Then you can consider what you learned, how your organization’s governance and organization needs may differ, and make the necessary changes. Having made these choices, let’s look over our organizational strategy visually.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_2-1776186912117.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26003i24994D3FD7C4EF98/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_2-1776186912117.png" alt="jim_thorstad_2-1776186912117.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Within our “corporate” organization (BU1), Team 2 handles HR data, and everything else is handled by Team 1. These two teams will work independently in our shared &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-dev&lt;/FONT&gt; and &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-prod&lt;/FONT&gt; workspaces. For this to work well, it is important to note that one or more individuals must be trusted by both teams to serve as workspace Administrators. If this can be arranged, infrastructure management is simplified; if not, teams 1 and 2 should be separated into their own dev/prod workspaces.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Down the road, another division (BU2) could be acquired that shares the same Entra ID directory but elects to have separate workspaces and DevOps infrastructure. That’s okay, and it's the reason we’ll prefix our catalog names in Unity Catalog (e.g., &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_dev&lt;/FONT&gt;, &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu2_dev&lt;/FONT&gt;, …).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;We’ll align with the “mono repo” approach within each DevOps project and further organize our code using Declarative Automation Bundles. In this blog, we’ll use a single “Hello World” bundle to illustrate how the recommended development and CI/CD processes work. In practice, you will have many bundles for a given data domain (e.g., finance), and these can all be versioned in the same repo. We’ll use a single DevOps pipeline for staging and production deployments, but you may choose a different pipeline strategy.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_3-1776186945297.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26004iFC07BFFB27376B4A/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_3-1776186945297.png" alt="jim_thorstad_3-1776186945297.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H1&gt;&lt;SPAN&gt;Part 2 - Setting Up a Versioned Bundle Development Process&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;SPAN&gt;Databricks bundles and Git folders work seamlessly together with Azure DevOps, and set you up for success in your CI/CD process. Let’s jump into it.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Initial Azure DevOps Set Up&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;This is pretty straightforward and involves creating the team’s Azure DevOps project and initializing the repo. You do not need to create any branches–we will use the built-in &lt;/SPAN&gt;&lt;STRONG&gt;main branch&lt;/STRONG&gt;&lt;SPAN&gt; and create our &lt;/SPAN&gt;&lt;STRONG&gt;feature branches&lt;/STRONG&gt;&lt;SPAN&gt; within Databricks using the built-in Git integration UI.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Create your project, initialize the main branch, and then go to the repo and copy the repository URL to your clipboard for the next step.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_4-1776186982114.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26005i663A964FC68AEB0D/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_4-1776186982114.png" alt="jim_thorstad_4-1776186982114.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Create a Linked Account to Access the Repo&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;In the Databricks workspace, each developer creates their own &lt;/SPAN&gt;&lt;STRONG&gt;Azure DevOps (MSFT Entra) linked account credential&lt;/STRONG&gt;&lt;SPAN&gt;, allowing them to authenticate to the Git repository. Do this now in your “dev” workspace on the &lt;/SPAN&gt;&lt;STRONG&gt;Settings &amp;gt; User &amp;gt; Linked accounts&lt;/STRONG&gt;&lt;SPAN&gt; page. You do not need to do this in your prod workspace because there is no Git integration required there (DevOps will push the code to prod).&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_5-1776187016894.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26006iEA3F1BF3EC19242C/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_5-1776187016894.png" alt="jim_thorstad_5-1776187016894.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Create a Git Folder that Points to the Repo&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;In their &lt;/SPAN&gt;&lt;STRONG&gt;Home&lt;/STRONG&gt;&lt;SPAN&gt; directory, each developer creates their own &lt;/SPAN&gt;&lt;STRONG&gt;Git folder &lt;/STRONG&gt;&lt;SPAN&gt;that points to the team’s repo. This step is done by each developer only once. Click &lt;/SPAN&gt;&lt;STRONG&gt;Create &amp;gt; Git folder&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_6-1776187041430.png" style="width: 508px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26007i00214B7521DA6DE9/image-dimensions/508x159?v=v2" width="508" height="159" role="button" title="jim_thorstad_6-1776187041430.png" alt="jim_thorstad_6-1776187041430.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Paste in the repo URL from your Azure DevOps project (should still be on your clipboard), then click &lt;/SPAN&gt;&lt;STRONG&gt;Create Git folder&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_7-1776187095926.png" style="width: 730px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26008i1CDAB5B3539C6D0B/image-dimensions/730x287?v=v2" width="730" height="287" role="button" title="jim_thorstad_7-1776187095926.png" alt="jim_thorstad_7-1776187095926.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;You will notice that Git folders have special properties in the Workspace UI, including these two buttons.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_8-1776187129932.png" style="width: 606px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26009iB65F59BDA86B2ECC/image-dimensions/606x85?v=v2" width="606" height="85" role="button" title="jim_thorstad_8-1776187129932.png" alt="jim_thorstad_8-1776187129932.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Open in editor&lt;/STRONG&gt;&lt;SPAN&gt; and notice that a new browser tab opens with your Git folder in a new “focused” &lt;/SPAN&gt;&lt;STRONG&gt;authoring mode&lt;/STRONG&gt;&lt;SPAN&gt;. We’ll discuss this in a moment.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_9-1776187180928.png" style="width: 452px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26010i13DA4733FF040AA0/image-dimensions/452x156?v=v2" width="452" height="156" role="button" title="jim_thorstad_9-1776187180928.png" alt="jim_thorstad_9-1776187180928.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;We won’t use this view right now, so close the &lt;/SPAN&gt;&lt;STRONG&gt;browser tab&lt;/STRONG&gt;&lt;SPAN&gt; that was just opened.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Now, click the &lt;/SPAN&gt;&lt;STRONG&gt;Git branch button&lt;/STRONG&gt;&lt;SPAN&gt; as shown below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_10-1776187214034.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26011i82EAA6D52F1A4330/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jim_thorstad_10-1776187214034.png" alt="jim_thorstad_10-1776187214034.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;In the Git integration UI, click &lt;/SPAN&gt;&lt;STRONG&gt;Create Branch&lt;/STRONG&gt;&lt;SPAN&gt;, assign a name to your feature branch (e.g., &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;features/initial_work_on_hello_world&lt;/FONT&gt;&lt;SPAN&gt;), and then click &lt;/SPAN&gt;&lt;STRONG&gt;Create&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_11-1776187253227.png" style="width: 789px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26012i6A40384D2119E024/image-dimensions/789x269?v=v2" width="789" height="269" role="button" title="jim_thorstad_11-1776187253227.png" alt="jim_thorstad_11-1776187253227.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click the “X” button in the top right corner of the Git integration dialog to close it. Using your Microsoft ENTRA credentials, the Databricks Git integration created the branch in your Azure DevOps Repo and switched you to it in the Workspace UI, as shown below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_12-1776187294011.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26013i6D51097E8CBE9AA9/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_12-1776187294011.png" alt="jim_thorstad_12-1776187294011.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Navigating the Workspace UI&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;As of April, 2026, there are two UI previews that affect the behavior of the menus shown in this article. Have your workspace Admin go to &lt;/SPAN&gt;&lt;STRONG&gt;Previews&lt;/STRONG&gt;&lt;SPAN&gt; and search for “tree”. By default, the new “authoring” context preview (the first one, below) is enabled, and the new tree view for the file browser is not. We recommend enabling both so you can follow along with the article and because they both make working with Git folders and asset bundles easier. Here are the documentation links (as of April, 2026) for reference:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://docs.databricks.com/aws/en/workspace/workspace-browser#authoring-contexts" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Authoring context&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; preview&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://docs.databricks.com/aws/en/workspace/workspace-browser#tree-view-of-the-workspace-browser-side-panel-public-preview" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;File browser tree view&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; preview&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;General &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/workspace/" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Workspace UI documentation&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; (in case those links above change)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_13-1776187328636.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26014iB5982225DF6EBD1D/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_13-1776187328636.png" alt="jim_thorstad_13-1776187328636.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Create and Deploy Your First Bundle to “Dev”&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;From your Git folder, click &lt;/SPAN&gt;&lt;STRONG&gt;Create&lt;/STRONG&gt;&lt;SPAN&gt; and then choose &lt;/SPAN&gt;&lt;STRONG&gt;Bundle&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_14-1776187353760.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26015iA2B6266BFBA43F80/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_14-1776187353760.png" alt="jim_thorstad_14-1776187353760.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;There are different approaches to organizing your development copy of the bundles in your Git folder. A flat list of bundles, as shown below, works fine. You can also create folders under the Git folder and organize your bundles within them.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_15-1776187376364.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26016iBEEA771F6D6E009B/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jim_thorstad_15-1776187376364.png" alt="jim_thorstad_15-1776187376364.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;For the purposes of this blog, enter a name like &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;hello_world&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; for the &lt;/SPAN&gt;&lt;STRONG&gt;Bundle name&lt;/STRONG&gt;&lt;SPAN&gt; and choose the &lt;/SPAN&gt;&lt;STRONG&gt;Empty project&lt;/STRONG&gt;&lt;SPAN&gt; option. After clicking &lt;/SPAN&gt;&lt;STRONG&gt;Create&lt;/STRONG&gt;&lt;SPAN&gt;, you will see a list of add-on resources for your bundle. Choose &lt;/SPAN&gt;&lt;STRONG&gt;Add a new job definition&lt;/STRONG&gt;&lt;SPAN&gt;, enter a job title like &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;Update Event Table.&amp;nbsp;&lt;/SPAN&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color="#FF0000"&gt;&lt;SPAN&gt;&lt;U&gt;&lt;STRONG&gt;Important:&lt;/STRONG&gt; Don’t click&lt;/U&gt;&amp;nbsp;&lt;FONT color="#000000"&gt;the&lt;/FONT&gt;&amp;nbsp;&lt;FONT color="#000000"&gt;Add and deploy button&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT color="#000000"&gt;&lt;SPAN&gt;; instead, &lt;STRONG&gt;click the down arrow&lt;/STRONG&gt; and choose &lt;/SPAN&gt;&lt;STRONG&gt;Only add, deploy later&lt;/STRONG&gt;&lt;SPAN&gt;. &lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;SPAN&gt;If you accidentally clicked Add and deploy, it's ok, but you have deployed a job to dev that doesn’t have anything to do yet.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_16-1776187458541.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26017iA32BA994C50CAFEF/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_16-1776187458541.png" alt="jim_thorstad_16-1776187458541.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Add Some Code and Configure Your Job&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Let’s add some code to our project to see the CI/CD process in action. For the purposes of this blog, you can download the&lt;/SPAN&gt; &lt;STRONG&gt;Hello_World.ipynb&lt;/STRONG&gt; &lt;SPAN&gt;notebook from this location and then import it into your bundle folder as shown below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://github.com/databricks-solutions/databricks-dab-examples/blob/main/knowledge-base/azure-devops-cicd-example/Hello_World.ipynb" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;https://github.com/databricks-solutions/databricks-dab-examples/blob/main/knowledge-base/azure-devops-cicd-example/Hello_World.ipynb&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Be sure to import it into the &lt;/SPAN&gt;&lt;STRONG&gt;hello_world&lt;/STRONG&gt;&lt;SPAN&gt; asset bundle folder (&lt;/SPAN&gt;&lt;SPAN&gt;not&lt;/SPAN&gt;&lt;SPAN&gt; the resources folder), as shown below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_17-1776187488097.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26018i9859F21B3D51CC35/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_17-1776187488097.png" alt="jim_thorstad_17-1776187488097.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;While still on the &lt;/SPAN&gt;&lt;STRONG&gt;job.yml&lt;/STRONG&gt;&lt;SPAN&gt; file, uncomment lines 8-19 in the job YAML file using the &lt;/SPAN&gt;&lt;STRONG&gt;Toggle line comment &lt;/STRONG&gt;&lt;SPAN&gt;key combination (you can get a list of keyboard shortcuts from the context menu, as shown below).&amp;nbsp; After uncommenting lines, make the two changes shown in yellow. Be aware that paths are case sensitive. You have renamed the first task in your job and pointed it to the notebook you just imported.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_18-1776187507876.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26019iB620B8079CB9EEDB/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_18-1776187507876.png" alt="jim_thorstad_18-1776187507876.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Open the &lt;STRONG&gt;Hello_World&lt;/STRONG&gt; notebook and note a couple of things. The first cell defines a widget called “catalog” with no default. The notebook you imported has rendered the catalog widget at the top, but it is empty, so you can fill in the catalog you want to write to. For this lab, we’ll create a catalog called &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_dev&lt;/FONT&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Enter your value for the “&lt;/SPAN&gt;&lt;STRONG&gt;catalog”&lt;/STRONG&gt;&lt;SPAN&gt; widget field as shown below. Notice that there is also a widget called “&lt;/SPAN&gt;&lt;STRONG&gt;job_run_id&lt;/STRONG&gt;&lt;SPAN&gt;” that has no default value.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_19-1776187530474.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26020i27EC6F5734977F37/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_19-1776187530474.png" alt="jim_thorstad_19-1776187530474.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Go ahead and run the notebook now by clicking the &lt;/SPAN&gt;&lt;STRONG&gt;Run all &lt;/STRONG&gt;&lt;SPAN&gt;button at the top. You should use &lt;/SPAN&gt;&lt;STRONG&gt;Serverless&lt;/STRONG&gt;&lt;SPAN&gt; compute for this article so you don't have to wait for a cluster to start.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_20-1776187551646.png" style="width: 542px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26021i0481264A64A5B549/image-dimensions/542x141?v=v2" width="542" height="141" role="button" title="jim_thorstad_20-1776187551646.png" alt="jim_thorstad_20-1776187551646.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Notice in the output and the Catalog Explorer that one row was inserted, including the time and the user who ran the code.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_21-1776187579945.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26022iE5850F7B4BE81881/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_21-1776187579945.png" alt="jim_thorstad_21-1776187579945.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;In the workspace, click the bundle &lt;/SPAN&gt;&lt;STRONG&gt;deploy &lt;/STRONG&gt;&lt;SPAN&gt;button (the “rocket ship”), wait until the &lt;/SPAN&gt;&lt;STRONG&gt;Bundle resources &lt;/STRONG&gt;&lt;SPAN&gt;list has finished loading, and then click the &lt;/SPAN&gt;&lt;STRONG&gt;Deploy&lt;/STRONG&gt;&lt;SPAN&gt; button.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_22-1776187600169.png" style="width: 635px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26023i70359989C08C0B69/image-dimensions/635x269?v=v2" width="635" height="269" role="button" title="jim_thorstad_22-1776187600169.png" alt="jim_thorstad_22-1776187600169.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Deploy&lt;/STRONG&gt;&lt;SPAN&gt; again to confirm your updated Job definition should be deployed.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_23-1776187631019.png" style="width: 501px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26024iB7BB67DC0AE32B20/image-dimensions/501x206?v=v2" width="501" height="206" role="button" title="jim_thorstad_23-1776187631019.png" alt="jim_thorstad_23-1776187631019.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Congratulations!&amp;nbsp; You should see a message that you successfully deployed to your dev target.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;STRONG&gt;Workspace&lt;/STRONG&gt; in the side navigation to see what got deployed and where.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_24-1776187657685.png" style="width: 191px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26025iB0A85D9C9170392F/image-dimensions/191x146?v=v2" width="191" height="146" role="button" title="jim_thorstad_24-1776187657685.png" alt="jim_thorstad_24-1776187657685.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Databricks deploys the asset bundle to your &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;Home/.bundle&lt;/FONT&gt; &lt;SPAN&gt;folder. This is represented by the &lt;/SPAN&gt;&lt;STRONG&gt;dev deployment environment&lt;/STRONG&gt;&lt;SPAN&gt; highlighted in blue below. At this point, nothing is in Azure DevOps version control.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_25-1776187687791.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26026iF0F72E8EEC2026DA/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_25-1776187687791.png" alt="jim_thorstad_25-1776187687791.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Jobs &amp;amp; Pipelines&lt;/STRONG&gt;&lt;SPAN&gt; in the side navigation.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Your bundle deployment also created a job. Notice that the job title is prepended with&lt;/SPAN&gt; &lt;FONT color="#3366FF"&gt;&lt;FONT face="andale mono,times"&gt;[dev&lt;/FONT&gt; &lt;I&gt;your_user_id&lt;/I&gt;]&lt;/FONT&gt;&lt;SPAN&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Open the job and click the &lt;/SPAN&gt;&lt;STRONG&gt;Tasks&lt;/STRONG&gt;&lt;SPAN&gt; tab. Review the information below.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_26-1776187714667.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26027iE92C20F3D313385D/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_26-1776187714667.png" alt="jim_thorstad_26-1776187714667.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Messages (1) and (4) state that this job was created by a bundle deployment and that you shouldn’t edit this job in the UI (you can edit it, but your edits will be wiped out the next time you deploy your bundle). The name of your notebook task (2) matches what you edited back in the &lt;FONT face="andale mono,times" color="#3366FF"&gt;Update Event Table.job.yml&lt;/FONT&gt; file. The notebook path (3) you specified in the job.yml file is being used. The job is set to run as you (5). Currently, no job parameters (6) are shown – we will work on this next. There is a &lt;/SPAN&gt;&lt;STRONG&gt;Disconnect from source&lt;/STRONG&gt;&lt;SPAN&gt; (7) button in the UI.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Source-linked deployment &lt;/STRONG&gt;&lt;SPAN&gt;is an optional feature of bundle deployment and is enabled by default for the dev deployment. This is a convenient feature because your dev job references the notebook from your &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;Home/bu1-team1/hello_world&lt;/FONT&gt;&lt;SPAN&gt; folder in the workspace. A copy isn’t pushed into the &lt;/SPAN&gt;&lt;STRONG&gt;bundle deployment folder&lt;/STRONG&gt;&lt;SPAN&gt; for dev (&lt;FONT face="andale mono,times" color="#3366FF"&gt;Home/.bundle/hello_world&lt;/FONT&gt;). What’s convenient about source-linked deployment in dev is that you can make iterative fixes to your notebook and re-run your Job from the Jobs UI &lt;/SPAN&gt;&lt;STRONG&gt;without having to redeploy your asset bundle&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Go back to the &lt;/SPAN&gt;&lt;STRONG&gt;Runs&lt;/STRONG&gt;&lt;SPAN&gt; tab and click the &lt;/SPAN&gt;&lt;STRONG&gt;Run now&lt;/STRONG&gt;&lt;SPAN&gt; button. Use &lt;/SPAN&gt;&lt;STRONG&gt;Serverless job compute&lt;/STRONG&gt;&lt;SPAN&gt; so you don’t have to wait for a job cluster to start.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_27-1776187740391.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26028iB1A82DFB1384E819/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_27-1776187740391.png" alt="jim_thorstad_27-1776187740391.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The job will fail because the notebook can’t find a value for the catalog variable. When you ran the notebook manually, you typed a value into the catalog widget, but when the notebook ran from a job, the catalog widget was empty, and there was no default value specified in the first cell either.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;We don’t want a default value for the catalog because we intend to run this notebook across dev, stage, and prod environments. We want to send specific catalog names to the job based on the environment it's running in. Let’s configure that next.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Parameterizing the Catalog Name Passed to Your Notebook&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;In this section, you’ll be working in two files, which you’ll download in a moment. But let’s first understand how they work together:&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Bundle configuration (databricks.yml) &lt;/STRONG&gt;&lt;SPAN&gt;- You’ll define a &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/bundles/reference#variables" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;custom variable&lt;/STRONG&gt;&lt;/A&gt; &lt;I&gt;&lt;SPAN&gt;catalog_var&lt;/SPAN&gt;&lt;/I&gt; &lt;SPAN&gt;and some environment-specific values for it (&lt;/SPAN&gt;&lt;STRONG&gt;bu1_dev&lt;/STRONG&gt;&lt;SPAN&gt;, &lt;/SPAN&gt;&lt;STRONG&gt;bu1_stg&lt;/STRONG&gt;&lt;SPAN&gt;, and &lt;/SPAN&gt;&lt;STRONG&gt;bu1_prd&lt;/STRONG&gt;&lt;SPAN&gt;). This will also involve defining our deployment environment &lt;/SPAN&gt;&lt;STRONG&gt;targets&lt;/STRONG&gt;&lt;SPAN&gt; (dev, stage, and prod).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Job configuration (job.yml)&lt;/STRONG&gt;&lt;SPAN&gt; - You’ll define a &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/jobs/job-parameters" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;job parameter&lt;/STRONG&gt;&lt;/A&gt;&lt;I&gt;&lt;SPAN&gt; catalog &lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt;to accept the value from the bundle variable during deployment, and we’ll configure a job task &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/bundles/job-task-types" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;base_parameter&lt;/STRONG&gt;&lt;/A&gt;&lt;SPAN&gt; so the job parameter is available to our notebook.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN&gt;For more information on these topics, click the links behind the terms above. Visually, the variable/parameter wiring looks like this:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_28-1776187794608.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26029i27577AF80F84B837/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_28-1776187794608.png" alt="jim_thorstad_28-1776187794608.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;As you can see, the bundle configuration file (&lt;FONT face="andale mono,times" color="#3366FF"&gt;databricks.yml&lt;/FONT&gt;) contains general setup information on lines 1-12 and environment &lt;/SPAN&gt;&lt;STRONG&gt;targets&lt;/STRONG&gt;&lt;SPAN&gt; starting on line 14. Each target (dev, staging, and prod) defines the bundle's characteristics for that environment. This includes how to access the Databricks workspace, which variable names/values to pass, and which &lt;/SPAN&gt;&lt;STRONG&gt;deployment&lt;/STRONG&gt; &lt;STRONG&gt;mode&lt;/STRONG&gt;&lt;SPAN&gt; to use for the environment.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;We define a bundle variable &lt;/SPAN&gt;&lt;STRONG&gt;catalog_var&lt;/STRONG&gt;&lt;SPAN&gt; and set it to &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_dev&lt;/FONT&gt; when deploying to the “dev” target environment. We’ll set it to &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_stg&lt;/FONT&gt; for the staging environment, and so on. These environmental targets are defined by you. You can have as many as you like and name them however you like. However, &lt;/SPAN&gt;&lt;STRONG&gt;the bundle target &lt;/STRONG&gt;&lt;STRONG&gt;&lt;I&gt;name&lt;/I&gt;&lt;/STRONG&gt;&lt;STRONG&gt; must match the value specified in your Azure DevOps pipeline &lt;/STRONG&gt;&lt;SPAN&gt;for the bundle validate and deploy steps, as you will see.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The deployment mode setting has two values: development and production. The dev target uses the &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;development&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; mode, whereas staging and prod both use the &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;production&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; mode. Development mode prefixes your deployed jobs with &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;[dev &amp;lt;your_user_name&amp;gt;]&lt;/FONT&gt; &lt;SPAN&gt;so that they are easier to distinguish in the event you and your colleagues are both working on separate copies of the same bundle/pipeline in dev. Development mode also enables &lt;/SPAN&gt;&lt;STRONG&gt;source-linked deployment&lt;/STRONG&gt;&lt;SPAN&gt; as previously described, making it easier to iterate on your bundle wiring and notebook code. Here’s a complete reference for the behavior of the bundle &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;&lt;STRONG&gt;mode: &lt;/STRONG&gt;&lt;/FONT&gt;&lt;SPAN&gt;setting.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_29-1776187864368.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26030i38BF44891AE302EE/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_29-1776187864368.png" alt="jim_thorstad_29-1776187864368.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;To save you time, here is the completed code for the example we are following. Copy these into your Event Table Job.yml and databricks.yml files.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;&lt;A href="https://github.com/databricks-solutions/databricks-dab-examples/tree/main/knowledge-base/azure-devops-example/resources/Update_Event_Table.job.yml" target="_blank" rel="noopener"&gt;https://github.com/databricks-solutions/databricks-dab-examples/tree/main/knowledge-base/azure-devops-example/resources/Update_Event_Table.job.yml&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;&lt;A href="https://github.com/databricks-solutions/databricks-dab-examples/tree/main/knowledge-base/azure-devops-example/databricks.yml" target="_blank" rel="noopener"&gt;https://github.com/databricks-solutions/databricks-dab-examples/tree/main/knowledge-base/azure-devops-example/databricks.yml&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;STRONG&gt;Home/bu1-team1/hello_world/resources/Update Event Table.job.yml&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Specify your email in the highlighted line below.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Note that the code includes a second parameter to capture the &lt;/SPAN&gt;&lt;STRONG&gt;job run ID&lt;/STRONG&gt;&lt;SPAN&gt; so we can write it into the event table. The syntax&lt;/SPAN&gt; &lt;FONT face="andale mono,times" color="#3366FF"&gt;{{job.run_id}} &lt;/FONT&gt;&lt;SPAN&gt;captures the run ID dynamically. We’re appending that to the string “job_run_id_”, which you will see when this parameter is written into the table. You can change the parameter definition and remove the prefix if you wish. Because this parameter is defined dynamically by the job, you do not need to create a bundle variable for it as you did with catalog_var.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN&gt;resources:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;jobs:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Update_Event_Table:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;name: Update Event Table&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;queue:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enabled: true&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parameters:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- name: catalog&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default: ${var.catalog_var}&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- name: job_run_id&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default: "job_run_id_{{job.run_id}}"&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tasks:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- task_key: notebook_task_1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;notebook_task:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;notebook_path: ../Hello_World.ipynb&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base_parameters:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catalog: ${var.catalog_var}&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;job_run_id: "job_run_id_{{job.run_id}}"&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;email_notifications:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;on_failure:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- &lt;/SPAN&gt;&lt;FONT color="#FF0000"&gt;&lt;SPAN&gt;your_email@example.com&lt;/SPAN&gt;&lt;/FONT&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;trigger:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;periodic:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;interval: 1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unit: DAYS&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H3&gt;&lt;STRONG&gt;Home/bu1-team1/hello_world/databricks.yml&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Edit the workspace URLs to match your environment and change the catalog names if necessary. Note that we’re using the same workspace for &lt;/SPAN&gt;&lt;STRONG&gt;dev&lt;/STRONG&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;STRONG&gt;staging&lt;/STRONG&gt;&lt;SPAN&gt; in this blog, but you can use three separate workspaces for dev/staging/prod if you wish. Just make the edits below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN&gt;# Declarative Automation Bundle (DAB) configuration; more info here:&amp;nbsp;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# https://docs.databricks.com/en/dev-tools/bundles/settings.html&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;bundle:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;name: "hello_world"&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;include:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;- resources/*.yml&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;- resources/*/*.yml&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# Define custom variables; more info here:&amp;nbsp;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# https://docs.databricks.com/en/dev-tools/bundles/reference#variables&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;variables:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;catalog_var:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;description: Custom variable containing the target catalog&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default: ""&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;targets:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;# TODO - adjust the catalog names and workspace URLs to match your deployment&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;# The "dev" target used by the bundle deploy feature&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;dev:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mode: development&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default: true&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;variables:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catalog_var: &lt;/SPAN&gt;&lt;SPAN&gt;bu1_dev&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;workspace:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;host: https://&lt;FONT color="#FF0000"&gt;adb-###########.#.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;azuredatabricks.net&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;# The "staging" target used by Azure DevOps&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;staging:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mode: production&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;variables:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catalog_var: &lt;/SPAN&gt;&lt;SPAN&gt;bu1_stg&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;workspace:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;host: https://&lt;FONT color="#FF0000"&gt;adb-&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT color="#FF0000"&gt;&lt;SPAN&gt;###########.#&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;&lt;FONT color="#FF0000"&gt;.&lt;/FONT&gt;azuredatabricks.net&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root_path: /Workspace/devops/staging/bu1-team1/.bundle/${bundle.name}&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;# The "prod" target used by Azure DevOps&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;prod:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mode: production&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;variables:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catalog_var: &lt;/SPAN&gt;&lt;SPAN&gt;bu1_prd&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;workspace:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;host: https://&lt;FONT color="#FF0000"&gt;adb-###########.#&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&lt;FONT color="#FF0000"&gt;.&lt;/FONT&gt;azuredatabricks.net&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root_path: /Workspace/devops/prod/bu1-team1/.bundle/${bundle.name}&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Important:&lt;/STRONG&gt;&lt;/U&gt; &lt;SPAN&gt;After updating the workspace URLs in your databricks.yml file, please click the &lt;/SPAN&gt;&lt;STRONG&gt;reload&lt;/STRONG&gt;&lt;SPAN&gt; button in your web browser.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;This is necessary because we sourced the file with placeholder text (##########) for the workspace URL, and the bundle UI sees it as soon as you make the edit. This confuses it in the next step, as it will think there are no valid targets to deploy to. So after making your edits and reloading the workspace UI in your web browser, continue to the next step.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click the bundle &lt;STRONG&gt;deploy &lt;/STRONG&gt;button and then click the &lt;STRONG&gt;Target&lt;/STRONG&gt; pulldown menu.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_0-1776191070143.png" style="width: 476px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26032i8738D90DFE383DA2/image-dimensions/476x294?v=v2" width="476" height="294" role="button" title="jim_thorstad_0-1776191070143.png" alt="jim_thorstad_0-1776191070143.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Notice the message saying that deployment to other workspaces is not supported. Actually, this means the bundle deploy feature is designed only to deploy locally, to the workspace you are in.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;We will only use the bundle deploy button to push the bundle locally to our &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;dev&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; target. We will use Azure DevOps to deploy our bundles to the &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;stage&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;prod&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; environments.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Press the &lt;/SPAN&gt;&lt;STRONG&gt;Escape (ESC) key &lt;/STRONG&gt;&lt;SPAN&gt;to close the drop-down menu and then click the &lt;/SPAN&gt;&lt;STRONG&gt;Deploy&lt;/STRONG&gt;&lt;SPAN&gt; button.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_1-1776191123230.png" style="width: 195px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26033i48EB32C184370EB2/image-dimensions/195x125?v=v2" width="195" height="125" role="button" title="jim_thorstad_1-1776191123230.png" alt="jim_thorstad_1-1776191123230.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Deploy&lt;/STRONG&gt;&lt;SPAN&gt; again and review the output messages below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_2-1776191146067.png" style="width: 766px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26034i53152BBBFB7132D8/image-dimensions/766x290?v=v2" width="766" height="290" role="button" title="jim_thorstad_2-1776191146067.png" alt="jim_thorstad_2-1776191146067.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;After your DAB deploys to dev, go to your Jobs page and click the run button to start your job. After you start it, you can click your job and see it running.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_3-1776191176189.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26035iEB09146C9FA33806/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_3-1776191176189.png" alt="jim_thorstad_3-1776191176189.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;When it finishes, click your job and notice that the catalog and job_id parameters were created and populated as expected, and your code added another row to the &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_dev.default.test_events&lt;/FONT&gt; table.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_4-1776191229954.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26036i0CB7EB0C7FCFD901/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_4-1776191229954.png" alt="jim_thorstad_4-1776191229954.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;With your code working in dev, let’s check it into Git.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click the Workspaces (the “folder”) button and take a few minutes to familiarize yourself with the new Workspace UI. Click the “All files” button and then go back to the “Folder” button next to it. Notice that this simply toggles whether you are in the DAB bundle folder. Also, notice the open file tabs on the right. It’s nice to be able to have multiple files open at one time, even in different folders/subfolders, and switch among them without having to navigate the folder structure on the left.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_5-1776191258090.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26037i840065325E0C22BC/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_5-1776191258090.png" alt="jim_thorstad_5-1776191258090.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;When you are ready, click the Git button next to your bundle folder.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_6-1776191292941.png" style="width: 332px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26038i85443CC80AB9F311/image-dimensions/332x151?v=v2" width="332" height="151" role="button" title="jim_thorstad_6-1776191292941.png" alt="jim_thorstad_6-1776191292941.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Go ahead and add some comments and click &lt;/SPAN&gt;&lt;STRONG&gt;Commit &amp;amp; Push&lt;/STRONG&gt;&lt;SPAN&gt; for your first DAB project!&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_7-1776191317552.png" style="width: 693px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26039iF8DE4DD5AEABEC4E/image-dimensions/693x566?v=v2" width="693" height="566" role="button" title="jim_thorstad_7-1776191317552.png" alt="jim_thorstad_7-1776191317552.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;In the message at the top of the screen, click the create a &lt;/SPAN&gt;&lt;STRONG&gt;pull request &lt;/STRONG&gt;&lt;SPAN&gt;link to create your pull request here, for convenience. This takes you right into Azure DevOps, where you can fill in the details for your Pull request!&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_8-1776191354102.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26040iF81045028EF2CD03/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_8-1776191354102.png" alt="jim_thorstad_8-1776191354102.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Create&lt;/STRONG&gt;&lt;SPAN&gt; to create your PR and then stop here.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Let’s go set up the Azure DevOps deployment pipeline. This way, when we go into DevOps to approve and merge your PR, we should see our new DevOps pipeline automatically deploy your initial hello world code to staging.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H1&gt;&lt;SPAN&gt;Part 3 - Creating the Azure DevOps Deployment Pipeline for CI/CD&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;SPAN&gt;As a review, our CI/CD requirements are:&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;SPAN&gt;Approved developer PRs should be merged into main and automatically deployed to staging.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;Here, the merged code can be tested in the broader context of the data platform, potentially alongside other approved changes awaiting promotion to prod.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN&gt;Then, after further approval, the main branch is deployed to prod.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN&gt;We’ll begin by setting up the staging process, which involves creating a DevOps &lt;/SPAN&gt;&lt;STRONG&gt;service connection&lt;/STRONG&gt;&lt;SPAN&gt;, mapping it to an Entra ID-managed Databricks &lt;/SPAN&gt;&lt;STRONG&gt;service principal &lt;/STRONG&gt;&lt;SPAN&gt;(SP), creating a workspace &lt;/SPAN&gt;&lt;STRONG&gt;deployment folder&lt;/STRONG&gt;&lt;SPAN&gt; for staging, and granting the SP permissions on the folder and the &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_stg&lt;/FONT&gt;&lt;STRONG&gt; catalog&lt;/STRONG&gt;&lt;SPAN&gt; in Unity Catalog. We’ll repeat this process for prod. Then we’ll create the DevOps &lt;/SPAN&gt;&lt;STRONG&gt;variable groups&lt;/STRONG&gt;&lt;SPAN&gt;, prod &lt;/SPAN&gt;&lt;STRONG&gt;environment&lt;/STRONG&gt;&lt;SPAN&gt; gate/approvers, and &lt;/SPAN&gt;&lt;STRONG&gt;pipeline&lt;/STRONG&gt;&lt;SPAN&gt; to pull it all together. After that, we can test it out!&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Here’s an overview of the steps that you’ll perform twice (once for staging and once for prod), except where noted:&lt;/SPAN&gt;&lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Step&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Where&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;What&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Why&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;1&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure DevOps &amp;gt; Project Settings&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Create the bu1-team1 Service Connection&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD rowspan="2"&gt;
&lt;P&gt;&lt;SPAN&gt;Facilitates a secure and flexible connection between DevOps and Azure Databricks for deploying bundles to the staging and prod.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;BR /&gt;
&lt;P&gt;&lt;SPAN&gt;For a comparison to the newer Databricks OIDC-based approach, see the topic at the end of this article.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;2&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure Portal&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Create the bu1-team1-cicd App Registration and Federated credential&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;3&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Databricks workspace &amp;gt; Settings&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Create the bu1-team1-cicd Service Principal&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;This will be the owner of the resources deployed by DevOps; you need to give this principal write access to the deployment folder and privileges in Unity Catalog&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;4&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Databricks workspace &amp;gt; Folders&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Create your SP and any admin group permissions on the /staging/bu1-team1 folder&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;By deploying into team-based folders, you have the ability to set permissions so each team can view their own deployed code if necessary&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;5&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Databricks workspace &amp;gt; Catalog&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Give the SP and other groups appropriate permissions in Unity Catalog.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Tables and schemas created by the SP are owned by the SP.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;6&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure DevOps &amp;gt; Library&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Create a Variable group for each stage&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;These hold the variable DATABRICKS_HOST with the URL to the workspace for the stage&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;7&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure DevOps &amp;gt; Environments&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;You will create this only for “prod”&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;This will be used to set up the approval gate for prod deployment&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;8&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure DevOps &amp;gt; Repo&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Create a root folder called “/.cicd” or similar for the pipeline code.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;This provides separation between your pipeline and bundle code. Consider requiring special approvers for code changes to files in this root folder.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;9&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure DevOps &amp;gt; Pipelines&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Create a release pipeline for your hello_world project&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;This will deploy your code to staging and prod after the required approvals.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;10&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Test it out!&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Check the messages written into your event table in the staging and prod catalogs&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;You can consider how to organize your bundles and deployment pipelines. A pipeline can deploy multiple bundles, or you can keep them 1:1 for finer control.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Create the Staging Service Connection and App Registration&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Go to your DevOps project’s&lt;/SPAN&gt;&lt;STRONG&gt; Project settings &amp;gt; Pipelines &amp;gt; Service connections&lt;/STRONG&gt;&lt;SPAN&gt; and click &lt;/SPAN&gt;&lt;STRONG&gt;Create service connection&lt;/STRONG&gt;&lt;SPAN&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Choose the &lt;/SPAN&gt;&lt;STRONG&gt;Azure Resource Manager&lt;/STRONG&gt;&lt;SPAN&gt; option and click &lt;/SPAN&gt;&lt;STRONG&gt;Next&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_9-1776191487263.png" style="width: 728px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26041iEFAEAC300A1C495E/image-dimensions/728x418?v=v2" width="728" height="418" role="button" title="jim_thorstad_9-1776191487263.png" alt="jim_thorstad_9-1776191487263.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color="#FF0000"&gt;&lt;STRONG&gt;Important! &lt;/STRONG&gt;&lt;/FONT&gt;&lt;SPAN&gt;&lt;FONT color="#FF0000"&gt;&amp;nbsp;&lt;/FONT&gt;For &lt;/SPAN&gt;&lt;STRONG&gt;Identity type,&lt;/STRONG&gt;&lt;SPAN&gt; you’ll see two options.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Choose the &lt;/SPAN&gt;&lt;STRONG&gt;App registration or managed identity (manual) &lt;/STRONG&gt;&lt;SPAN&gt;option highlighted below (&lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;do not choose&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; the one tagged as recommended).&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_10-1776191527970.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26042i64FE2F4A9422ABAA/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jim_thorstad_10-1776191527970.png" alt="jim_thorstad_10-1776191527970.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;This lets you clearly name the Azure &lt;/SPAN&gt;&lt;STRONG&gt;App Registration &lt;/STRONG&gt;&lt;SPAN&gt;backing your DevOps &lt;/SPAN&gt;&lt;STRONG&gt;Service Connection&lt;/STRONG&gt;&lt;SPAN&gt;. This is important because the name of your Azure App Registration is synchronized with the name of your Databricks &lt;/SPAN&gt;&lt;STRONG&gt;Service Principal, &lt;/STRONG&gt;&lt;SPAN&gt;and this is what your data team will be searching for when granting permissions on your Unity Catalog and Workspace resources.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;If you choose the other option, the App Registration name will be automatically generated by Azure as&lt;/SPAN&gt; &lt;FONT face="andale mono,times" color="#3366FF"&gt;&amp;lt;devops_org&amp;gt;-&amp;lt;project&amp;gt;-&amp;lt;GUID&amp;gt;&lt;/FONT&gt;&lt;SPAN&gt;, with no indication of whether it is for staging or prod. You cannot rename it, and this will make it hard to assign permissions later. The manual approach we recommend in this article involves a few more steps, but it is your best option as of April 2026.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Note: Both approaches involve creating an App registration in your Azure portal, so if you don’t have the permissions to do this, you’ll get an error and will need to work on these steps with someone who does.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;After choosing &lt;/SPAN&gt;&lt;STRONG&gt;App registration or managed identity (manual),&lt;/STRONG&gt;&lt;SPAN&gt; fill in the &lt;/SPAN&gt;&lt;STRONG&gt;Service Connection Name (e.g., &lt;/STRONG&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;&lt;SPAN&gt;bu1-team1-staging-svc-conn&lt;/SPAN&gt;&lt;/FONT&gt;&lt;STRONG&gt;)&lt;/STRONG&gt;&lt;SPAN&gt;, description, and your Directory (tenant) ID under the &lt;/SPAN&gt;&lt;STRONG&gt;Part 1: Basics&lt;/STRONG&gt;&lt;SPAN&gt; section, and then click &lt;/SPAN&gt;&lt;STRONG&gt;Next&lt;/STRONG&gt;&lt;SPAN&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;This takes you to &lt;/SPAN&gt;&lt;STRONG&gt;Part 2: App registration details&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Tip:&lt;/SPAN&gt;&lt;SPAN&gt; to find your tenant ID, click your user ID circle in the DevOps portal banner bar and then click the &lt;/SPAN&gt;&lt;STRONG&gt;Switch directory&lt;/STRONG&gt;&lt;SPAN&gt; link. The tenant ID will be the string under the current directory.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_11-1776191563270.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26043iAE1BB5F286D77756/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jim_thorstad_11-1776191563270.png" alt="jim_thorstad_11-1776191563270.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;At this point, you’ll need to keep the Part 2 screen open and open the Azure Portal in another tab. You can follow the steps below and see them illustrated in the image below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Create the &lt;/SPAN&gt;&lt;STRONG&gt;App Registration&lt;/STRONG&gt;&lt;SPAN&gt; (e.g., &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-team1-cicd-staging-app&lt;/FONT&gt;) in the Azure portal.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Copy the &lt;/SPAN&gt;&lt;STRONG&gt;Application ID&lt;/STRONG&gt;&lt;SPAN&gt; (formerly called client ID) and add it to your DevOps &lt;/SPAN&gt;&lt;STRONG&gt;service connection Part 2&lt;/STRONG&gt;&lt;SPAN&gt; field labeled &lt;/SPAN&gt;&lt;STRONG&gt;Application (client) ID.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;While you are there, fill in your &lt;/SPAN&gt;&lt;STRONG&gt;Subscription ID&lt;/STRONG&gt;&lt;SPAN&gt;. You can get the Subscription ID by searching Subscriptions in the Azure Portal.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Enter your &lt;/SPAN&gt;&lt;STRONG&gt;Subscription name&lt;/STRONG&gt;&lt;SPAN&gt; - do not click the Verify and save button yet.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Back in the Azure Portal on your App Registration page, click &lt;/SPAN&gt;&lt;STRONG&gt;Manage&lt;/STRONG&gt;&lt;SPAN&gt; on the left.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Then click &lt;/SPAN&gt;&lt;STRONG&gt;Certificates &amp;amp; secrets&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Click the &lt;/SPAN&gt;&lt;STRONG&gt;Federated credentials&lt;/STRONG&gt;&lt;SPAN&gt; tab.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Add Credentia&lt;/STRONG&gt;&lt;SPAN&gt;l.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Choose &lt;/SPAN&gt;&lt;STRONG&gt;Other issuer&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Copy the &lt;/SPAN&gt;&lt;STRONG&gt;Issuer URL&lt;/STRONG&gt;&lt;SPAN&gt; from your service connection under &lt;/SPAN&gt;&lt;STRONG&gt;Part 2&lt;/STRONG&gt;&lt;SPAN&gt; and paste it in the &lt;/SPAN&gt;&lt;STRONG&gt;Issuer&lt;/STRONG&gt;&lt;SPAN&gt; field.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Copy the &lt;/SPAN&gt;&lt;STRONG&gt;Subject identifier &lt;/STRONG&gt;&lt;SPAN&gt;and paste it in the &lt;/SPAN&gt;&lt;STRONG&gt;Value&lt;/STRONG&gt;&lt;SPAN&gt; field.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Enter a &lt;/SPAN&gt;&lt;STRONG&gt;name&lt;/STRONG&gt;&lt;SPAN&gt; for your credential (e.g. &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-team1-cicd-staging-fed-credential&lt;/FONT&gt;)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Add&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Back on the service connection screen, check the &lt;/SPAN&gt;&lt;STRONG&gt;Grant access permission to all pipelines&lt;/STRONG&gt;&lt;SPAN&gt; box. This is okay because it means all DevOps pipelines in our &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-team&lt;/FONT&gt; DevOps project. If you are organizing things differently, you can always grant access to this connection later on.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Don’t click Verify and save yet!&amp;nbsp; &lt;/STRONG&gt;&lt;SPAN&gt;You need to give your App Registration permission to read your Subscription. If you clicked it anyway, look carefully at the error message. You’ll see that your Part 1 work was saved as a draft. You can come back and complete Part 2 after you do the required steps.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_12-1776191605220.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26044i64DA3F4AA9C7F55B/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_12-1776191605220.png" alt="jim_thorstad_12-1776191605220.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Go to the &lt;/SPAN&gt;&lt;STRONG&gt;Azure Portal&lt;/STRONG&gt;&lt;SPAN&gt; and find your Subscription. Go to &lt;/SPAN&gt;&lt;STRONG&gt;Access control (IAM)&lt;/STRONG&gt;&lt;SPAN&gt; and click &lt;/SPAN&gt;&lt;STRONG&gt;Add role assignment&lt;/STRONG&gt;&lt;SPAN&gt;. Click &lt;/SPAN&gt;&lt;STRONG&gt;Reader&lt;/STRONG&gt;&lt;SPAN&gt; under Name and then click &lt;/SPAN&gt;&lt;STRONG&gt;Next&lt;/STRONG&gt;&lt;SPAN&gt;. Leave the &lt;/SPAN&gt;&lt;STRONG&gt;Assign access&lt;/STRONG&gt;&lt;SPAN&gt; to option set to &lt;/SPAN&gt;&lt;STRONG&gt;User, group, or service principal &lt;/STRONG&gt;&lt;SPAN&gt;and click the &lt;/SPAN&gt;&lt;STRONG&gt;Select members&lt;/STRONG&gt;&lt;SPAN&gt; link. Find your &lt;/SPAN&gt;&lt;STRONG&gt;service principal &lt;/STRONG&gt;&lt;SPAN&gt;(note: your App Registration previously created a service principal in the background with the same name, e.g., &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-team1-cicd-staging-app&lt;/FONT&gt;), pick it, and click &lt;/SPAN&gt;&lt;STRONG&gt;Select&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_13-1776191638184.png" style="width: 786px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26045i5F3A553B419647B8/image-dimensions/786x333?v=v2" width="786" height="333" role="button" title="jim_thorstad_13-1776191638184.png" alt="jim_thorstad_13-1776191638184.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Review + Assign&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Now return to Azure DevOps and your &lt;/SPAN&gt;&lt;STRONG&gt;Edit service connection Part 2&lt;/STRONG&gt;&lt;SPAN&gt; screen and click the &lt;/SPAN&gt;&lt;STRONG&gt;Verify and save&lt;/STRONG&gt;&lt;SPAN&gt; button.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Congratulations!&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN&gt;That’s a lot of steps, but it's necessary because you need to establish a trust relationship between your Azure DevOps project and your Azure Portal App Registration/Service Principal; these services do not all trust each other by default.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Now we are going to configure trust between our Azure App Registration/Service Principal and the Databricks Service Principal that will run the resources Azure DevOps deployed in your workspace.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Create the Databricks Service Principal for CI/CD Tasks&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Go to your staging workspace (in this article, we use the &lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-dev&lt;/FONT&gt; workspace). Go to Workspace &lt;/SPAN&gt;&lt;STRONG&gt;Settings&lt;/STRONG&gt;&lt;SPAN&gt; &amp;gt; &lt;/SPAN&gt;&lt;STRONG&gt;Identity and access&lt;/STRONG&gt;&lt;SPAN&gt; &amp;gt; &lt;/SPAN&gt;&lt;STRONG&gt;Service principals&lt;/STRONG&gt;&lt;SPAN&gt; and click &lt;/SPAN&gt;&lt;STRONG&gt;Manage&lt;/STRONG&gt;&lt;SPAN&gt;. Click &lt;/SPAN&gt;&lt;STRONG&gt;Add service principal &lt;/STRONG&gt;&lt;SPAN&gt;and then click the &lt;/SPAN&gt;&lt;STRONG&gt;Add new&lt;/STRONG&gt;&lt;SPAN&gt; button.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Under Management, choose &lt;/SPAN&gt;&lt;STRONG&gt;Microsoft Entra ID managed,&lt;/STRONG&gt;&lt;SPAN&gt; and then copy the &lt;/SPAN&gt;&lt;STRONG&gt;Application ID&lt;/STRONG&gt;&lt;SPAN&gt; from your Azure App Registration over.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Note: as of April 2026, the UI shown below for the Microsoft Entra ID managed option shows a field for entering the service principal name. While this field allows you to enter and save a value, it will not be retained, as you will see when you go to search for this service principal in the permissions UI throughout Databricks.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Give it any &lt;/SPAN&gt;&lt;STRONG&gt;name&lt;/STRONG&gt;&lt;SPAN&gt; like bu1-team1-cicd-staging-sp (but you’ll see it will be changed back to the name of your App Registration shortly) and click &lt;/SPAN&gt;&lt;STRONG&gt;Add&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_14-1776191753695.png" style="width: 811px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26046i68C7EF413DC21A71/image-dimensions/811x517?v=v2" width="811" height="517" role="button" title="jim_thorstad_14-1776191753695.png" alt="jim_thorstad_14-1776191753695.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Note: It’s possible to use a &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;single&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; Azure DevOps Service Connection, Azure App Registration, and Databricks Service Principal for all of your CI/CD processes (including both staging and production deployments). However, you’ll notice we’ve been including the term “staging” in the names of these CI/CD resources we’ve been creating, so you can later add the “prod” versions and have more precise governance over your CI/CD process.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click your Databricks SP after it's created. It will need the &lt;/SPAN&gt;&lt;STRONG&gt;Workspace Access&lt;/STRONG&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;STRONG&gt;SQL access&lt;/STRONG&gt;&lt;SPAN&gt; entitlements, depending on your code. I recommend using Serverless jobs, especially during development, to speed up your trial-and-error CI/CD testing. If you use Serverless jobs, you do not need to assign the &lt;/SPAN&gt;&lt;STRONG&gt;Allow unrestricted cluster creation&lt;/STRONG&gt;&lt;SPAN&gt; entitlement.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_15-1776191786351.png" style="width: 356px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26047i22CFA43286233E4E/image-dimensions/356x344?v=v2" width="356" height="344" role="button" title="jim_thorstad_15-1776191786351.png" alt="jim_thorstad_15-1776191786351.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Explore the &lt;/SPAN&gt;&lt;STRONG&gt;Permissions&lt;/STRONG&gt;&lt;SPAN&gt; tab. This lets you decide who can manage and use the SP, not what this SP can do in your workspace. You can consider whether a team in the staging environment needs to manually re-run a job for some reason. In this case, give that team the USE permission.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Explore the &lt;/SPAN&gt;&lt;STRONG&gt;Git integration&lt;/STRONG&gt;&lt;SPAN&gt; tab. This feature allows your SP to connect with a Git repo, which is needed when the job is configured to pull notebook code from Git at runtime. But we are not using that approach in this blog. We are configuring DevOps to push the notebook code and bundle resources to each environment. Leave Git integration unconfigured for the SP.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Create the Staging Deployment Folder&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;In the workspace, create a staging location where the Azure DevOps pipeline will deploy your code. Then right-click this folder and choose the &lt;/SPAN&gt;&lt;STRONG&gt;Share (Permissions) &lt;/STRONG&gt;&lt;SPAN&gt;menu. Search for your SP and grant it &lt;/SPAN&gt;&lt;STRONG&gt;Can&lt;/STRONG&gt; &lt;STRONG&gt;Manage&lt;/STRONG&gt;&lt;SPAN&gt; permissions, as shown below (remember, as mentioned previously, you are searching for the App Registration you created in the Azure portal, which is synced to the name of the Databricks service principal you just created).&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;If you would like your development team to see what is deployed here, grant them View permissions. Generally, developers, QA teams, and admins should not have write access to the staging bundle target deployment folder.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_16-1776191820288.png" style="width: 762px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26048iBB0F3794C0A25793/image-dimensions/762x238?v=v2" width="762" height="238" role="button" title="jim_thorstad_16-1776191820288.png" alt="jim_thorstad_16-1776191820288.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Assigning Unity Catalog Permissions to your Service Principal&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;There are a few strategies for creating and managing permissions on catalogs and schemas. In this blog, we create the catalogs manually and assign Data Editor permissions to our SP. We also grant the Manage permission so our SP can drop tables and manage permissions if we were to do that in our job code. Feel free to reconsider and evolve your choices as necessary.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Give your SP permission to create data assets in your &lt;/SPAN&gt;&lt;STRONG&gt;stage catalog&lt;/STRONG&gt;&lt;SPAN&gt; as shown below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_17-1776191855258.png" style="width: 688px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26049iDA5EE4105035AB13/image-dimensions/688x647?v=v2" width="688" height="647" role="button" title="jim_thorstad_17-1776191855258.png" alt="jim_thorstad_17-1776191855258.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Go into the default schema in your staging catalog and notice that many of these permissions are inherited as expected. Look at the permissions on your &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1_stg.default&lt;/FONT&gt; schema&lt;SPAN&gt;. Notice that your SP can read and write to this schema even though it is not the owner (you are the owner since it was created when you made the catalog).&lt;/SPAN&gt;&lt;/P&gt;
&lt;H1&gt;&lt;SPAN&gt;Create your Azure DevOps Pipeline (bu1-team1-hello-world-pipeline.yml)&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;SPAN&gt;We want our CI/CD pipeline to have two stages:&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;DeployStaging&lt;/STRONG&gt;&lt;SPAN&gt; - Runs automatically when code from a feature branch has been approved and merged into the main branch.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;DeployProd&lt;/STRONG&gt;&lt;SPAN&gt; - Runs after DeployStaging and after an approval that you can configure.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN&gt;We’ll use DevOps variable groups to store the workspace URLs and a DevOps environment to define the approval process that gates our prod deployment.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Go to your &lt;/SPAN&gt;&lt;STRONG&gt;DevOps project &amp;gt; Pipelines &amp;gt; Library&lt;/STRONG&gt;&lt;SPAN&gt; and click the &lt;/SPAN&gt;&lt;STRONG&gt;+ Variable group&lt;/STRONG&gt;&lt;SPAN&gt; button. Name it &lt;/SPAN&gt;&lt;STRONG&gt;stagingVariables&lt;/STRONG&gt;&lt;SPAN&gt; (you’ll reference this in the first stage of your pipeline) and add a variable for &lt;/SPAN&gt;&lt;STRONG&gt;DATABRICKS_HOST&lt;/STRONG&gt;&lt;SPAN&gt; along with a URL pointing to the hostname of your staging workspace (bu1-dev in the example for this article). Then click &lt;/SPAN&gt;&lt;STRONG&gt;Save&lt;/STRONG&gt;&lt;SPAN&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Repeat the process for another variable group called &lt;/SPAN&gt;&lt;STRONG&gt;prodVariables&lt;/STRONG&gt;&lt;SPAN&gt;, which you will reference in the second stage of your pipeline.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_18-1776191886815.png" style="width: 781px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26050i4725CE906CB12AB6/image-dimensions/781x300?v=v2" width="781" height="300" role="button" title="jim_thorstad_18-1776191886815.png" alt="jim_thorstad_18-1776191886815.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Go to your &lt;/SPAN&gt;&lt;STRONG&gt;DevOps project &amp;gt; Environments &lt;/STRONG&gt;&lt;SPAN&gt;and click the &lt;/SPAN&gt;&lt;STRONG&gt;Create environment&lt;/STRONG&gt;&lt;SPAN&gt; button. Name it &lt;/SPAN&gt;&lt;STRONG&gt;prod&lt;/STRONG&gt;&lt;SPAN&gt; (you’ll reference this in the second stage of your pipeline), leave Resource set to &lt;/SPAN&gt;&lt;STRONG&gt;None&lt;/STRONG&gt;&lt;SPAN&gt;, and click &lt;/SPAN&gt;&lt;STRONG&gt;Create&lt;/STRONG&gt;&lt;SPAN&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Next, click the &lt;/SPAN&gt;&lt;STRONG&gt;Approvals and checks&lt;/STRONG&gt;&lt;SPAN&gt; tab and click the &lt;/SPAN&gt;&lt;STRONG&gt;Approvals&lt;/STRONG&gt;&lt;SPAN&gt; check. For this article, we’ll just pick two approvers, but you can configure this as required by your organization.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_19-1776191913682.png" style="width: 800px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26051i5E359CD85BF19784/image-dimensions/800x279?v=v2" width="800" height="279" role="button" title="jim_thorstad_19-1776191913682.png" alt="jim_thorstad_19-1776191913682.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;You do not need to create a staging environment, as we plan to deploy automatically after merging to main with no conditions or approvals.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Go to your &lt;/SPAN&gt;&lt;STRONG&gt;DevOps project &amp;gt; Repos &amp;gt; Files&lt;/STRONG&gt;&lt;SPAN&gt; page and create a new folder (e.g., &lt;/SPAN&gt;&lt;STRONG&gt;.cicd&lt;/STRONG&gt;&lt;SPAN&gt;) and your Hello World pipeline inside it.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_20-1776191946563.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26052i69DF7CA4F0DF1C15/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jim_thorstad_20-1776191946563.png" alt="jim_thorstad_20-1776191946563.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Copy the following YAML into it and edit the &lt;/SPAN&gt;&lt;STRONG&gt;azureSubscription value on lines 33 and 102 &lt;/STRONG&gt;&lt;SPAN&gt;to match the name of your DevOps Service Connections (yes; its confusing that it needs the service connection name, but it asks for the subscription name). Review the comments and make any other necessary adjustments.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;You can also download the file from this link - &lt;/SPAN&gt;&lt;A href="https://github.com/databricks-solutions/databricks-dab-examples/blob/main/knowledge-base/azure-devops-cicd-example/bu1-team1-hello-world-pipeline.yml" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;https://github.com/databricks-solutions/databricks-dab-examples/blob/main/knowledge-base/azure-devops-cicd-example/bu1-team1-hello-world-pipeline.yml&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;PRE&gt;&lt;SPAN&gt;# This triggers the pipeline on a commit to the 'main' branch&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;trigger:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;branches:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;include:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- main&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;# Prevents the pipeline from triggering on Pull Requests; only on merges&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;pr: none&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;stages:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# -----------------------------------------------&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# Stage 1: Deploy to Staging (automatic on merge)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# -----------------------------------------------&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# TODO - In the bundle validate/deploy steps below, change "workingDirectory"&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# to the folder containing your databricks.yml and edit the target values if&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# your choice differs from "staging" used in the example below.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;- stage: DeployStaging&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;displayName: 'Deploy to Staging'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;variables:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- group: stagingVariables&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;condition: |&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;eq(variables['Build.SourceBranch'], 'refs/heads/main')&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;jobs:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;- job: deployStagingJob&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pool:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vmImage: ubuntu-latest&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- task: UsePythonVersion@0&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inputs:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;versionSpec: 3.11&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- task: AzureCLI@2&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Get Databricks Token (Staging)'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inputs:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# TODO - Change azureSubscription value to the name of your DevOps "staging" Service Connection&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;azureSubscription: &lt;/SPAN&gt;&lt;FONT color="#FF0000"&gt;&lt;SPAN&gt;bu1-team1-staging-svc-conn&lt;/SPAN&gt;&lt;/FONT&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scriptType: 'bash'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scriptLocation: 'inlineScript'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;failOnStandardError: true&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Set the token as a pipeline variable for subsequent steps; note that the "echo"&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# line does not print the token to the pipeline logs. The resource ID is the well-known&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Azure AD application ID for Databricks (same for all tenants).&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inlineScript: |&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set -e&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_TOKEN=$(az account get-access-token --resource 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d --query "accessToken" -o tsv)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo "##vso[task.setvariable variable=DATABRICKS_TOKEN]$DATABRICKS_TOKEN"&lt;BR /&gt;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Clone the repository so the bundle files are available to the pipeline agent&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- checkout: self&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Checkout repository'&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Install Python dependencies here if your bundle requires them&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# For example:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# - script: pip install -r requirements.txt&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# &amp;nbsp; displayName: 'Install Python dependencies'&amp;nbsp;&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- script: |&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;curl -fsSL &lt;A href="https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh" target="_blank" rel="noopener"&gt;https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh&lt;/A&gt; | sh&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;databricks --version&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Install Databricks CLI'&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- script: databricks bundle validate -t staging&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Validate bundle for the "staging" environment'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;env:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_HOST: $(DATABRICKS_HOST)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_TOKEN: $(DATABRICKS_TOKEN)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;workingDirectory: $(Build.SourcesDirectory)/hello_world&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- script: databricks bundle deploy -t staging&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Deploy bundle to the "staging" environment'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;env:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_HOST: $(DATABRICKS_HOST)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_TOKEN: $(DATABRICKS_TOKEN)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;workingDirectory: $(Build.SourcesDirectory)/hello_world&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;# -----------------------------------------------&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# Stage 2: Deploy to Production (requires approval in Azure DevOps)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# -----------------------------------------------&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# TODO - In the bundle validate/deploy steps below, change "workingDirectory"&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# to the folder containing your databricks.yml and edit the target values if&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;# your choice differs from "prod" used in the example below.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;- stage: DeployProd&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;displayName: 'Deploy to Prod'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;dependsOn: DeployStaging&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;condition: succeeded()&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;variables:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- group: prodVariables&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;jobs:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;# A "deployment:" job (rather than a regular "job:") is required to&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;# connect to an Azure DevOps Environment and enable the approval gate.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;- deployment: deployProdJob&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Deploy to Prod'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pool:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;vmImage: ubuntu-latest&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Setup the approval gate. The value for "environment" must match&amp;nbsp;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# the Azure DevOps Environment name where approvals are configured.&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;environment: 'prod'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;strategy:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;runOnce:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;deploy:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;steps:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- checkout: self&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- task: UsePythonVersion@0&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Use Python 3.11'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inputs:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;versionSpec: 3.11&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- task: AzureCLI@2&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Get Databricks Token (Prod)'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inputs:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# TODO - Change azureSubscription value to the name of your DevOps "prod" Service Connection&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;azureSubscription: &lt;/SPAN&gt;&lt;FONT color="#FF0000"&gt;&lt;SPAN&gt;bu1-team1-prod-svc-conn&lt;/SPAN&gt;&lt;/FONT&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scriptType: 'bash'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scriptLocation: 'inlineScript'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;failOnStandardError: true&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Set the token as a pipeline variable for subsequent steps; note that the "echo"&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# line does not print the token to the pipeline logs. The resource ID is the well-known&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Azure AD application ID for Databricks (same for all tenants).&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inlineScript: |&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set -e&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_TOKEN=$(az account get-access-token --resource 2ff814a6-3304-4ab8-85cb-cd0e6f879c1d --query "accessToken" -o tsv)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo "##vso[task.setvariable variable=DATABRICKS_TOKEN]$DATABRICKS_TOKEN"&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Install Python dependencies here if your bundle requires them&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# For example:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# - script: pip install -r requirements.txt&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# &amp;nbsp; displayName: 'Install Python dependencies'&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- script: |&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;curl -fsSL &lt;A href="https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh" target="_blank" rel="noopener"&gt;https://raw.githubusercontent.com/databricks/setup-cli/main/install.sh&lt;/A&gt; | sh&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;databricks --version&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Install Databricks CLI'&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- script: databricks bundle validate -t prod&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Validate bundle for the "prod" environment'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;env:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_HOST: $(DATABRICKS_HOST)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_TOKEN: $(DATABRICKS_TOKEN)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;workingDirectory: $(Build.SourcesDirectory)/hello_world&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- script: databricks bundle deploy -t prod&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;displayName: 'Deploy bundle to the "prod" environment'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;env:&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_HOST: $(DATABRICKS_HOST)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DATABRICKS_TOKEN: $(DATABRICKS_TOKEN)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;workingDirectory: $(Build.SourcesDirectory)/hello_world&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Commit&lt;/STRONG&gt;&lt;SPAN&gt; to save it to the main branch of your repo.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_21-1776192316430.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26053i2AD7E30B04C08767/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_21-1776192316430.png" alt="jim_thorstad_21-1776192316430.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Before making the DevOps pipeline and pointing it to this file, let’s approve and merge the initial Hello World DABs pull request so there is some code to deploy.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;In your Azure DevOps project, click &lt;/SPAN&gt;&lt;STRONG&gt;Repos &amp;gt; Pull requests&lt;/STRONG&gt;&lt;SPAN&gt; and select the pull request you created earlier from the Databricks Git integration UI.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_22-1776192352175.png" style="width: 687px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26054i2DEB18506BDF2838/image-dimensions/687x230?v=v2" width="687" height="230" role="button" title="jim_thorstad_22-1776192352175.png" alt="jim_thorstad_22-1776192352175.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Click &lt;/SPAN&gt;&lt;STRONG&gt;Complete&lt;/STRONG&gt;&lt;SPAN&gt; and then choose your merge options before clicking the &lt;/SPAN&gt;&lt;STRONG&gt;Complete merge &lt;/STRONG&gt;&lt;SPAN&gt;button.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_23-1776192375534.png" style="width: 644px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26055i3F8200E21D3E5CA3/image-dimensions/644x306?v=v2" width="644" height="306" role="button" title="jim_thorstad_23-1776192375534.png" alt="jim_thorstad_23-1776192375534.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;You can verify that your bundle code is now in the main branch.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Now let’s create the pipeline. Go to your &lt;/SPAN&gt;&lt;STRONG&gt;project &amp;gt; Pipelines &amp;gt; Pipelines&lt;/STRONG&gt;&lt;SPAN&gt; menu and click &lt;/SPAN&gt;&lt;STRONG&gt;Create Pipeline&lt;/STRONG&gt;&lt;SPAN&gt;. Choose &lt;/SPAN&gt;&lt;STRONG&gt;Azure Repos Git&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_24-1776192394894.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26056iCC7F5DAD5636E244/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_24-1776192394894.png" alt="jim_thorstad_24-1776192394894.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Choose your team repository and then click &lt;/SPAN&gt;&lt;STRONG&gt;Existing Azure Pipelines YAML file&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Enter the path to your pipeline file and click &lt;/SPAN&gt;&lt;STRONG&gt;Continue&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_25-1776192423890.png" style="width: 712px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26057i5CE1C9FAF4CF4867/image-dimensions/712x389?v=v2" width="712" height="389" role="button" title="jim_thorstad_25-1776192423890.png" alt="jim_thorstad_25-1776192423890.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Before you can run the pipeline, you need to either:&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Repeat the previous steps to create your prod service connection (&lt;FONT face="andale mono,times" color="#3366FF"&gt;bu1-team1-prod-svc-conn&lt;/FONT&gt;), your Databricks SP and deployment folder on the prod workspace, and the permissions for the prod catalog, or&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Comment out all Stage 2 lines in your pipeline to avoid validation errors.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;H2&gt;&lt;SPAN&gt;Deploying to Staging&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Once you have decided, click &lt;/SPAN&gt;&lt;STRONG&gt;Run&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_26-1776192461650.png" style="width: 801px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26058i072D2927AA7B964D/image-dimensions/801x226?v=v2" width="801" height="226" role="button" title="jim_thorstad_26-1776192461650.png" alt="jim_thorstad_26-1776192461650.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;You do not need to set or change anything on the next screen that comes up.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_27-1776192492961.png" style="width: 416px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26059iB771640F93A77180/image-dimensions/416x592?v=v2" width="416" height="592" role="button" title="jim_thorstad_27-1776192492961.png" alt="jim_thorstad_27-1776192492961.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Your Deploy to Staging job will run. The first time it runs, you will see a message asking for permission to access the staging variable group. Give it permission.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_28-1776192523578.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26060iD3EBE40A401D6767/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_28-1776192523578.png" alt="jim_thorstad_28-1776192523578.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_29-1776192550923.png" style="width: 668px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26061iBCDD286DAA16CEE8/image-dimensions/668x366?v=v2" width="668" height="366" role="button" title="jim_thorstad_29-1776192550923.png" alt="jim_thorstad_29-1776192550923.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;When the staging deployment finishes, go find your Job and run it.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_30-1776192577136.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26062i522C3E10E553544B/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_30-1776192577136.png" alt="jim_thorstad_30-1776192577136.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;See that the data was added by the service principal. Depending on the part of the UI, you will either see the App Registration’s App ID or Name as shown below.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_31-1776192598096.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26063i4ED82A11443C2B23/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_31-1776192598096.png" alt="jim_thorstad_31-1776192598096.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;While the code deployment, job execution, and data writing to the table were all performed by the Azure App Registration’s SP, it was the Workspace Admin who enabled it in Workspace Settings, and the Unity Catalog owner who granted it editor rights on the schema.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_32-1776192625054.png" style="width: 678px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26064i7E2F6CAC3C070DE3/image-dimensions/678x201?v=v2" width="678" height="201" role="button" title="jim_thorstad_32-1776192625054.png" alt="jim_thorstad_32-1776192625054.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Deploying to Production&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;When you are ready, click the Review button and approve running the prod deployment stage.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_33-1776192653029.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26065i7464395574BDC4DF/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_33-1776192653029.png" alt="jim_thorstad_33-1776192653029.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Your bundle should be deployed to the prod workspace. Find the job and run it, then check the prod catalog to see that it ran.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Congratulations!&amp;nbsp; &lt;span class="lia-unicode-emoji" title=":party_popper:"&gt;🎉&lt;/span&gt;.&amp;nbsp; &amp;nbsp; If you made it this far, you are now an Azure Databricks CI/CD champion.&amp;nbsp;&lt;span class="lia-unicode-emoji" title=":beaming_face_with_smiling_eyes:"&gt;😁&lt;/span&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Please share your thoughts about this article in the comments section. What concepts did you learn from this blog that were helpful? Is there anything you don’t understand or are unsure of? What aspects of the example shown do you think should be expanded on for an intro CI/CD best practice article? What other topics would you like to be expanded on in another Technical Blog?&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Comparing Two Approaches to Workload Identity Federation: Azure AD-Brokered Service Connections vs. Databricks OIDC Integration&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The approach taken for integrating Azure DevOps and Databricks in this blog uses App registration-backed Azure DevOps service connections. This is a well-established pattern for securely federating your pipeline workload between the two cloud services. But Databricks recently introduced an alternative OIDC-based approach. How do these compare, and which is the best option?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Both approaches use secure, token-based protocols (OIDC and OAuth). The difference is the issuer. In the blog, I use the DevOps service connection feature, which means the DevOps pipeline (via the AzureCLI@2 task) obtains an Azure AD access token and passes it to the Databricks CLI as DATABRICKS_TOKEN. This works well when your pipeline also needs access to other Azure resources (Storage, Key Vault, etc.) through the same service principal.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Databricks also supports a newer alternative: OAuth token federation (also called workload identity federation or OIDC). With this approach, the Azure DevOps pipeline authenticates directly to Databricks — no Azure AD intermediary, no service connections, and no explicit token retrieval step. You create a federation policy on the Databricks service principal that trusts your Azure DevOps organization's OIDC issuer, and the Databricks CLI handles the token exchange automatically using the pipeline's built-in System.AccessToken.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;This does result in a simpler pipeline (no &lt;FONT face="andale mono,times" color="#3366FF"&gt;AzureCLI@2&lt;/FONT&gt; task, no Azure service connections), but it only authenticates to Databricks — if you need access to other Azure resources, you'll still need the other service connection approach shown in this blog. To learn more, see &lt;A href="https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/provider-azure-devops" target="_blank" rel="noopener"&gt;https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/provider-azure-devops&lt;/A&gt; in the Databricks documentation.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_1-1776277670883.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26113iBCF0FEFBC8F723D2/image-size/large?v=v2&amp;amp;px=999" role="button" title="jim_thorstad_1-1776277670883.png" alt="jim_thorstad_1-1776277670883.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;TABLE&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;STRONG&gt;Aspect&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;STRONG&gt;Approach 1: &lt;/STRONG&gt;&lt;STRONG&gt;&lt;BR /&gt;&lt;/STRONG&gt;&lt;STRONG&gt;Azure AD-Brokered Authentication (This Blog)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;STRONG&gt;Approach 2: &lt;/STRONG&gt;&lt;STRONG&gt;&lt;BR /&gt;&lt;/STRONG&gt;&lt;STRONG&gt;Databricks-Native OIDC Federation (Alternate Option)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Doc link&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/devops/pipelines/release/configure-workload-identity?view=azure-devops&amp;amp;tabs=managed-identity" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Connect to Azure using App registration with workload identity federation&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/databricks/dev-tools/auth/provider-azure-devops" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Enable workload identity federation for Azure DevOps Pipelines&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Maturity&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Well-established pattern&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Newer (Databricks OAuth federation)&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Protocols used&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;OIDC, OAuth 2.0, bearer token&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;OIDC → Databricks OAuth 2.0&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Auth intermediary&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure AD (token broker)&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;None (direct OIDC)&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Token acquisition&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Explicit&amp;nbsp; &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;&lt;SPAN&gt;az account get-access-token&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Automatic by Databricks SDK/CLI&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure CLI in pipeline&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Required&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Not needed&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure service connections&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Required (one per env)&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Not needed&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Federation policy&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;On Azure AD (trusts Azure DevOps)&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;On Databricks SP (trusts Azure DevOps)&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Complexity&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Two hops; 8 pipeline steps per stage&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;One hop; 2-3 pipeline steps per stage&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Azure resource access&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;The same SP can access other Azure resources (key vault, etc.).&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Only authenticates to Databricks&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Better when&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;The pipeline also needs to interact with other Azure resources (storage, Key Vault, etc.) using the same service principal&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Your org already has Azure AD service connections established and governed&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;You want the well-trodden, battle-tested path that most Azure shops already understand&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/TD&gt;
&lt;TD&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;The pipeline only needs Databricks access&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;You want the simplest possible pipeline YAML&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;You want to eliminate Azure AD as a dependency/intermediary&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;You're on a non-Azure cloud but still using Azure DevOps&lt;/SPAN&gt; &lt;SPAN&gt;(the OIDC issuer is Azure DevOps itself, not Azure AD)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;You want the Databricks SDK to handle the token lifecycle automatically&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;What’s different&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;--&lt;/TD&gt;
&lt;TD&gt;
&lt;P data-unlink="true"&gt;&lt;SPAN&gt;Skips Azure AD entirely. A federation policy is created directly on the Databricks service principal that trusts the Azure DevOps OIDC issuer (&lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;&lt;SPAN&gt;https://vstoken.dev.azure.com/&amp;lt;org_id&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;). The pipeline YAML is&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Minimal:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jim_thorstad_0-1776277460580.png" style="width: 463px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/26112iB58A4B23E9344CE9/image-dimensions/463x139?v=v2" width="463" height="139" role="button" title="jim_thorstad_0-1776277460580.png" alt="jim_thorstad_0-1776277460580.png" /&gt;&lt;/span&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
&lt;P&gt;&lt;SPAN&gt;Requires&lt;/SPAN&gt;&lt;/P&gt;
&lt;/TD&gt;
&lt;TD&gt;--&lt;/TD&gt;
&lt;TD&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;A Databricks service principal with a federation policy configured via &lt;/SPAN&gt;&lt;SPAN&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;&lt;SPAN&gt;databricks account service-principal-federation-policy create&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;- Three environment variables + &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;&lt;SPAN&gt;$(System.AccessToken)&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;- No Azure AD, no Azure service connections, no &lt;/SPAN&gt;&lt;FONT face="andale mono,times" color="#3366FF"&gt;&lt;SPAN&gt;AzureCLI@2&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; task&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;</description>
    <pubDate>Thu, 16 Apr 2026 09:23:21 GMT</pubDate>
    <dc:creator>jim_thorstad</dc:creator>
    <dc:date>2026-04-16T09:23:21Z</dc:date>
    <item>
      <title>Azure DevOps with Databricks DABs: Step-by-Step Integration Guide</title>
      <link>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/ba-p/141451</link>
      <description>&lt;P&gt;&lt;SPAN&gt;Establishing a trusted &lt;/SPAN&gt;&lt;I&gt;Continuous Integration/Continuous Deployment (CI/CD)&lt;/I&gt; &lt;SPAN&gt;process is crucial for effectively managing the lifecycle of your data and AI workloads in Azure Databricks. However, with numerous setup options and a constantly evolving platform, the big question is, "Where do I even start?" This comprehensive blog cuts through the complexity to outline a &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/dev-tools/ci-cd/best-practices"&gt;&lt;STRONG&gt;recommended CI/CD approach&lt;/STRONG&gt;&lt;/A&gt; &lt;SPAN&gt;for Azure Databricks.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 16 Apr 2026 09:23:21 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/ba-p/141451</guid>
      <dc:creator>jim_thorstad</dc:creator>
      <dc:date>2026-04-16T09:23:21Z</dc:date>
    </item>
    <item>
      <title>Re: Azure DevOps with Databricks DABs: Step-by-Step Integration Guide</title>
      <link>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/bc-p/155001#M1005</link>
      <description>&lt;P&gt;Amazing work on this&amp;nbsp;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/38005"&gt;@jim_thorstad&lt;/a&gt;&amp;nbsp;- exactly what I needed to get going!&amp;nbsp; What an epic!&lt;/P&gt;</description>
      <pubDate>Tue, 21 Apr 2026 00:21:30 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/bc-p/155001#M1005</guid>
      <dc:creator>SamGreene</dc:creator>
      <dc:date>2026-04-21T00:21:30Z</dc:date>
    </item>
    <item>
      <title>Re: Azure DevOps with Databricks DABs: Step-by-Step Integration Guide</title>
      <link>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/bc-p/155073#M1009</link>
      <description>&lt;P&gt;A M A Z I N G with all details..&lt;/P&gt;</description>
      <pubDate>Tue, 21 Apr 2026 11:45:48 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/bc-p/155073#M1009</guid>
      <dc:creator>h_h_ak</dc:creator>
      <dc:date>2026-04-21T11:45:48Z</dc:date>
    </item>
    <item>
      <title>Re: Azure DevOps with Databricks DABs: Step-by-Step Integration Guide</title>
      <link>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/bc-p/163794#M1129</link>
      <description>&lt;P&gt;Amazing content! Thanks a lot!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 22 Jul 2026 17:22:05 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/azure-devops-with-databricks-dabs-step-by-step-integration-guide/bc-p/163794#M1129</guid>
      <dc:creator>mrrickyno</dc:creator>
      <dc:date>2026-07-22T17:22:05Z</dc:date>
    </item>
  </channel>
</rss>

