How to deploy Power Apps Solutions using Azure Pipelines

Niels Swimberghe

Niels Swimberghe - - Dynamics

Follow me on Twitter, buy me a coffee

Azure Pipelines and Power Apps logo next to title: How to deploy Power Apps Solutions using Azure Pipelines

You can manually export Power Apps solutions from one environment and import them to another environment, but you can now also automate this using Azure Pipelines and the Power Platform Build tools.
In this tutorial, you will take the following steps to set up automated solution deploys:

  1. Create an Azure Active Directory (AAD) App Registration with access to your Dataverse
  2. Create a system user in Dataverse linked to your AAD App Registration
  3. Create an Azure Pipeline with Power Platform Build Tools to pack and import solution

Create an Azure Active Directory (AAD) App Registration with access to your Dataverse #

To access your Azure Active Directory, you can go straight to the Azure Portal and look up "Azure Active Directory" in the search bar at the top. Click on the "Azure Active Directory" link listed under services.

There's also a shortcut in the admin center. Browse to admin.microsoft.com, and in the side-navigation click on "Show all". Now, all available admin centers are listed. Click on the "Azure Active Directory" link under "Admin centers". This will take you to a specific Azure dashboard for Azure Active Directory.

Click on "Azure Active Directory" in the side navigation and then click on "App Registrations". Click on the "New registration" button.

Screenshot of Azure Active Directory App Registration screen. Cursor clicks on the "New registration" button.

Give your app a name (fe. AdoToDataverse) and click on "Register".

Screen to register an application in Azure Active Directory.

Navigate to your App registration when it is created. On the overview page, take note of the "Application (client) ID" and the "Directory (tenant) ID". You will need these later!

Overview page of the AAD app registration with the Application ID and Directory ID circled in red.

Navigate to the API permissions screen and click on Add permission.

AAD App Registration API Permissions Screen with cursor clicking on the "Add a permission" button.

Click on the APIs my organization uses and search for Dataverse. Click on the Dataverse item.

Screen to add new permissions to AAD app registration and the Dataverse permission is selected.

On the next screen click on the Delegated permissions box and check the box for user_impersionation.
Click on Add permissions.

Details screen for request Dataverse permission for AAD App Registration

While you are still on the API permission screen, click on Grant admin consent for your_tenant_name.

Grant AAD App Registration admin consent

Navigate to the Certificates & secrets screen and click on New client secret.

AAD App Registration screen to add new client secret

Enter a description that will help you identify what this secret is for in the future. For example Client secret for Azure DevOps.
Select when the secret expires. When the secret expires, you can create a new client secret and stop using the old one.

Screenshot of the new client secret entry in AAD App registration

Make sure you copy the secret "Value". You will need this secret and it will never be shown again.

Create a system user in Dataverse linked to your AAD App Registration #

Browse to the Power Platform admin center and click on your environment. 
In your environment settings, click on the See all link for Users.

Power Platform Admin center with the cursor clicking on See all users link

On the Users screen, click on the Manage users in Dynamics 365 button.

Power Platform Admin Center screen to manage users, but the cursor is clicking on "Manager users in Dynamics 365" button.

Switch to the Application Users view and click on the New button.

Dynamics 365 user management view, but the cursor is swapping to the "Application Users" view.

This will open a new window with a form to create the user.

Image of two screens, before and after creating the new application user.

Make sure you are on the Application User form. If not, switch to the Application User form.
Past in the App Registration Application ID from Azure Active Directory into the Application ID field and click on Save.

It takes a second to save, but once saved, the other fields will automatically populate as you can see in the screenshot above on the right side.

Go back to the Application Users view and select your new user using the checkbox at the beginning of the row. 
While the user is selected, click on Manage Roles and give the user the necessary role to import solutions. If you don't have a role specifically for those permissions, you can use System Administrator role for now.

Modal to manage user roles

Create an Azure Pipeline with Power Platform Build Tools to pack and import solution #

You need to install the Power Platform Build Tools extension from the Visual Studio Marketplace before you can perform any Power Platform operations from Azure DevOps. Browse to the extension and press the Get it free button. On the next page select the Azure DevOps organization you want to add the extension to.

This extension will add a new type of service connection name Power Platform and a whole bunch of Azure Pipeline tasks.

Navigate to your Azure DevOps project, or create a new one if you don't have any. Click on the Project Settings button on the bottom left.

Azure DevOps project settings screen for service connections. Cursor clicks on "New service connection".

Navigate to Service Connections and click on the New service connection button.
You need to enter the following data into the modal:

  • Server URL: this is the URL of your Dynamics CRM instance. You can find this URL by going to your Power Apps environment and clicking on the settings cog. A pane on the right will appear where you can click on the Session details link.
    This will show a modal with details about your session including the Dynamics CRM URL which you can find after the label Instance url. Copy this URL and paste it into the Server URL back in Azure DevOps.
    Modal of the Power Apps Session details
  • Tenant ID: Enter the ID you took note of earlier from your AAD App Registration that was labeled as Directory (tenant) ID
  • Application ID: Enter the other ID you took note of earlier from your AAD App Registration that was labeled as Application (client) ID.
  • Client secret of Application ID: Enter the Value from the client secret you created in your AAD App Registration.
  • Service connection name: Enter 'Power Platform', or any other meaningful name
Modal asking for details to create service connection to Power Platform

Navigate to the Pipelines > Pipelines section of your project, and click on the New pipeline button. Azure DevOps will now ask where your code is hosted. You could host your code in any source control server (git, TFVC, or SVN) and integrate it using Azure Pipelines. You will have to set up your own source control and use it to track your unpacked Power Apps solutions inside. This tutorial assumes you have already done this.

Since you're already in Azure DevOps, let's assume you use Azure Repos Git.

Select your git repository with which tracks your unpacked Power Apps solutions.

Click on Starter pipeline.

In the last step, replace the YAML code with the following YAML.

trigger: none

  vmImage: windows-latest

  - task: PowerPlatformToolInstaller@0
      DefaultVersion: true
  - task: PowerPlatformWhoAmi@0
      authenticationType: 'PowerPlatformSPN'
      PowerPlatformSPN: 'Power Platform'

If you gave your service connection a different name, make sure to change the PowerPlatformSPN property to your service connection name.

The YAML will do the following:

  • The pipeline is not automatically triggered, which means you will have to trigger it manually
  • When it is triggered, the pipeline will use a Windows machine to do the following two steps:
    • The PowerPlatformToolInstaller step will install the Power Platform Build Tools on the machine
    • The PowerPlatformWhoAmi step will send a WhoAmI request to Dynamics CRM which will return a bunch of information about the user authenticated against your Dynamics CRM instance.
      This is a great first step to verify that your connection works as expected.

Note: Power Platform Build tools are only supported on Windows.

Click on Save and run and let's see the result.

On the run details page, click on Job under Jobs to see more details about the tasks that are being executed.
Click on the PowerPlatformWhoAmi task and if all goes well, you should see details about your Power Apps environment.

Now that you have verified the connection works, let's add some more tasks.

Navigate back to the Pipelines > Pipelines section of your project and click on your new pipeline. Click on the Edit button and update the YAML code with the following:

trigger: none

  vmImage: windows-latest

  - task: PowerPlatformToolInstaller@0
      DefaultVersion: true
  - task: PowerPlatformWhoAmi@0
      authenticationType: 'PowerPlatformSPN'
      PowerPlatformSPN: 'Power Platform'
  - task: PowerPlatformPackSolution@0
      SolutionSourceFolder: 'solution'
      SolutionOutputFile: 'solution.zip'
  - task: PublishPipelineArtifact@1
      targetPath: 'solution.zip'
      artifact: 'Solution Archive'
      publishLocation: 'pipeline'
  - task: PowerPlatformImportSolution@0
      authenticationType: 'PowerPlatformSPN'
      PowerPlatformSPN: 'Power Platform'
      SolutionInputFile: 'solution.zip'
      AsyncOperation: true
      MaxAsyncWaitTime: '60'
  - task: PowerPlatformPublishCustomizations@0
      authenticationType: 'PowerPlatformSPN'
      PowerPlatformSPN: 'Power Platform'

In addition to the first two steps, the pipeline now does the following steps:

  • In source control, the solution folder holds the unpacked Power Apps solution. The PowerPlatformPackSolution step will pack the unpacked solution and produce a solution.zip file.
  • The PublishPipelineArtifact step isn't a Power Platform step, but a built-in Azure Pipelines step. This step will publish the solution.zip file to the pipeline so you can download it at a later point.
    This could be useful for debugging or to quickly deploy an older solution if you need to.
  • The PowerPlatformInportSolution step will upload your solution.zip file and import it into your Power Apps environment.
  • The PowerPlatformPublishCustomizations step will publish all customization in your Power Apps environment.
    Unfortunately, there's no way to publish customization of just a single solution. If there were other customizations pending to be published from outside your solution, those will be published too.

Hit Save and run and verify everything is working as expected.

Summary #

In this tutorial, you learned how to 

  • Create an Azure Active Directory App Registration and linked it to a Dynamics CRM user.
  • Used the App Registration to allow Azure DevOps to connect to your Power Apps environment as the Dynamics CRM user you created.
  • Create an Azure pipeline to pack and import a Power Apps solution and publish all customizations. 

Of course, everyone's source control structure is different and your process for deploying solutions to Power Apps may also be different.
Hopefully, this is a useful reference for you to build your own process.

Related Posts

Related Posts

CRM and PowerShell logo

Use PowerShell to communicate with Dynamics CRM using the .NET XRM SDK

- Dynamics
If you've developed client applications or plugins for Dynamics CRM before, you are familiar with the CRM/XRM DLL's. You may have gotten those DLL's from the CRM installation, the SDK zip, or the NuGet package. Another way to interact with the CRM DLL's is through PowerShell. PowerShell is built upon .NET meaning you can call exactly the same CRM libraries from PowerShell as from .NET applications.
CRM and PowerShell logo

PowerShell snippet: Get optionset value/labels from Dynamics CRM Entity/Attribute

- Dynamics
Instead of having to use the CRM interface to copy all the labels and values manually, you can save yourself a lot of time using this PowerShell script. Using the following script file named "GetOptionSet.ps1", you can list all the value/label pairs for a given Entity + OptionSet-Attribute:
.NET Bot, Azure, and Discord are together in a Discord server

How to create a Discord Bot using the .NET worker template and host it on Azure Container Instances

- Azure
Learn how to develop a Discord bot using the .NET worker template, containerize it using Docker, push the container image to Azure Container Registry, and host it on Azure Container Instances.
MS Paint drawn Cloudflare logo

Setting up Cloudflare Full Universal SSL/TLS/HTTPS with an Azure App Services

- Azure
Using Cloudflare's Universal SSL/TLS service, we can provide our website over a safe HTTPS connection. This post walks you through setting up the SSL/TLS encrypted connection from client to Cloudflare, to your Azure Web Application using the Full (strict) option and Cloudflare's origin certificates.