Search This Blog

Saturday, June 15, 2024

Azure DevOps with Power Apps deployment

 

Microsoft Power Apps are extremely popular with organisations who needs a reliable platform to make business applications.

In this blog I will walk you through how to use Azure DevOps to enable CI/CD for Microsoft PowerApps.

Prerequisites

  • Microsoft PowerPlatform Account
  • An Azure DevOps Account
  • Azure Account
  • Bitbucket Account

You will learn

  • How to use Azure DevOps to enable CI/CD for Microsoft PowerApps.

Blog Outline

  1. Create PowerApp Environments
  2. Create PowerApp in Dev Environment
  3. Create Service Principals with PowerPlatform Permission
  4. Create Power Platform Service Connections in Azure DevOps
  5. Create Bitbucket Service Connection in Azure DevOps
  6. Create Azure DevOps Build Pipeline
  7. Create Azure DevOps Release Pipeline
  8. Test the CI/CD Flow
  9. Summary
  10. References

Azure DevOps Architecture


  1. Once developer has finished the development and wants to deploy to UAT & Production, developer will manually trigger the Build Pipeline.
  2. DevOps Build Pipeline will export the PowerApps Solution from PowerApp Dev Environment and Commit to Bitbucket.
  3. DevOps Build Pipeline will create the Build Artifact.
  4. When Build Artifact is created, this will automatically trigger the Release PipeLines for UAT and Production.
  5. Once Approvers approve the UAT release and the deployment will be completed for UAT environment.
  6. After UAT testing, Approvers will approve the Production release and the deployment will be completed for the Production environment.

Let’s go step by step to create this process.

1. Create PowerApp Environments

We will have following environments,

  • DEV Environment — PowerApp will be developed in this environment.
  • UAT Environment — PowerApp will be tested by the testing team in this environment.
  • Production Environment — PowerApp production environment.

Go to PowerPlatform Admin Portal and create environments. I have already setup environments for Dev, UAT and Production.

2. Create PowerApp in Dev Environment

Let’s create a sample PowerApp.

  1. Go to this Link to Create Power App.
  2. Make sure Dev environment is selected.

3. Create a new Solution (“TestAppSolution” in this example) under Dev environment.

Inside the solution create a New Power App (“TestApp” in this example).

Now we have the below setup,

Dev (Environment) -> TestAppSolution (Solution) -> TestApp
UAT (Environment)
Production (Environment)

3. Create Service Principals with PowerPlatform Permission

1. Create 3 Azure app registrations for the 3 environments. Make sure to create a client secret for each of them and copy them. Please follow this guid to create Azure App Registrations.

2. Go to PowerPlatform Admin Portal and select the Dev Environment.

3. In your environment settings, Switch to the Application Users view as below.

4. Add the UAT Azure App Registration (App name in my case is “azure-devops-agent”) as an application user and provide the security role — System Customizer

Please follow this guide for above steps.

Now this Application User will have the necessary permissions required to export or import the PowerApps Solution.

Similar to this, assign 2 Azure app registrations as Application Users for UAT and Production environment as well. These Azure App Registrations will be used to create Azure DevOps Service connection for each environment.

4. Create Power Platform Service Connections in Azure DevOps

Here we will configure the service principals created for each environment as service connections.

1. Go to Visual Studio Market place and add Power Platform Build Tools to your Azure DevOps Organization.

2. Go to Azure DevOps Service Connection and create new Service Connection with Type — Power Platform.

3. Configure the details required for the service connection.

In order to get the Server URL, Go to PowerPlatform Admin Portal and select the environment as below.

Tenant Id — Your Azure Subscription Tenant ID

Application Id — Application Client ID of the Azure App Registration created in Step 3.1. You can find this in the Overview section of the Azure App Registration.

Client secret of Application Id — Copy the client secret generated in Step 3.1 here.

Configure 3 service connections for each environment as below.

5. Create Bitbucket Service Connection in Azure DevOps

Follow this Documentation and create Bitbucket service connection as below.

6. Create Azure DevOps Build Pipeline

1. Create a Bitbucket Repository to store the Power App package. In this example I have created “PowerAppTest”.

2. Go to Azure DevOps Pipelines and select Bitbucket Cloud as below. Select the repository afterwards.

3. Select “Starter pipeline”.

4. Use below Azure Pipeline YAML configuration. I have renamed the pipeline file as “azure-build-pipeline.yml”. This can be any name you want.

5. Click “Save and Run”. Make sure to give a commit message in the next window and click “Save and Run”.

This file will be committed to the Bitbucket repository. Azure DevOps will utilise this file whenever the developer wants to start a build to be deployed to UAT and Production.

This will trigger the Build Pipeline as below.

After the Build pipeline is completed, go the Bitbucket repository to see it is updated with the Power App solution code and “azure-build-pipeline.yml” file as below.

There are 8 steps in this Azure Pipeline file.

1. Checkout Step — This step configures how Pipeline check out the Bitbucket repository. This step is used to make sure Bitbucket credentials are persevered throughout all the steps with “persistCredentials” property.

2. CmdLine@2 Task — This command line step sets the Bitbucket username in Git configurations and checks out the repository.

3. PowerPlatformToolInstaller@2 Task — This task installs a set of Power Platform–specific tools required by the agent to run the Microsoft Power Platform build tasks. This task doesn’t require any more configuration when added.

4. PowerPlatformWhoAmi@2 Task — Verifies a Power Platform environment service connection by connecting and making a WhoAmI request. This task can be useful to include early in the pipeline, to verify connectivity before processing begins.

Note Dev environment service connection is used here since we need to connect to the Dev environment of the Power App to export the solution.

5. PowerPlatformExportSolution@2 Task — Exports the solution from the Dev environment and saves to “SolutionOutputFile” location as a Zip file.

6. PowerPlatformUnpackSolution@2 Task — Takes a compressed solution file and decomposes it into multiple XML files so that these files can be more easily read and managed by a source control system such as Bitbucket. In this case “SolutionTargetFolder” will contain the decomposed project files.

7. PublishBuildArtifacts@1 Task — Use this task to publish build artifacts to Azure Pipelines so it can be used by Azure Release Pipelines.

8. CmdLine@2 Task — This command line step commits the Power App solution to Bitbucket.

Committing the Power App solution to Bitbucket can also be done directly via Power Platform as well. There’s a feature in PowerApps to connect to a Git Repository and have the code automatically commit to Repository. Please refer to below Link.

So there is an option to have PowerApp configured with Bitbucket and use that Bitbucket repository from Azure Devops to trigger the Release Pipelines. At the time of the writing, this is a Preview feature.

7. Create Azure DevOps Release Pipeline

Now we need to create a Release pipeline to deploy the Power App to UAT environment.

1. Create New Release PipeLine and Start with Empty Job.

2. Rename the Release Pipeline as UAT.

3. Go to Tasks and Add Power Platform Tool Installer.

4. Add Power Platform Who Am I Task and configure as below. Make sure to select UAT Service Connection since we need to deploy into the UAT environment.

5. Add Artifact of the Build Pipeline we have previously created.

6. Add Power Platform Pack Solution and configure as below. Notice for “Source Folder of Solution to Pack” is the location of the PowerPlatformUnpackSolution@2 Task output file. Unpacked solution needs to be Packed again before deploying to Power App environment.

7. Add Power Platform Import Solution and configure as below. Note “Solution Input File” is the output from Power Platform Pack Solution Task.

8. Add Power Platform Publish Customizations and configure as below.

9. Add approvers for the UAT Release Pipeline.

10. Enable continuous trigger to make sure Release Pipeline is automatically triggered for every new Artifact build.

11. Click Save.

12. Similar to UAT, create another Release Stage for Production Environment as well using Production Service Principal as below.

8. Test the CI/CD Flow

1. Go to Power App in Dev Environment and add a new label as below.

2. Go to Azure DevOps Build Pipeline and run it manually.

3. Check the Build Pipeline logs successfully completes all the tasks.

4. Check Bitbucket Repository is updated with new Build After Build Pipeline.

5. Check to see Production and UAT Release Pipelines are triggered with pending approval.

6. Approve UAT first. Once UAT Deployment is succeeded go to the PowerApp UAT environment and verify the change is there.

7. After UAT change verification, approve the Production Release Pipeline. Once Production Deployment is succeeded go to the PowerApp Production environment and verify the change is there.

9. Summary

Azure DevOps is extremely flexible to design a proper CI/CD flow for each requirement in a project and a organisation. The purpose of this blog is to show that flexibility.

As you can imagine this can be customised further to support more complex flows!

Cheers!

10. References


Detail Step-By-Step - Power Platform ALM with Azure DevOps

 Introduction

 

  • Azure DevOps Repositories can be used as Source Control for Power Platform Solutions
  • CI/CD can be implemented using Azure DevOps Pipelines
  • We can use Microsoft Power Platform Build Tools to automate common build and deployment tasks related to apps built on Microsoft Power Platform . There are 2 versions of Build tools – older based on PowerShell and latest version based on Power Platform CLI

 

Power Platform ALM with Azure DevOps Process Flow

 

To implement CI/CD process with Azure DevOps Pipelines, we can store the Power Platform solution in the source control. There are two main Paths –

  1. Export the unmanaged solution and place it as unpacked in the source control system. The build process imports the packed solution as unmanaged into a temporary build environment , then export the solution as managed and store it as a build artifact in your source control system.
  2. Export the solution as unmanaged and also export the solution as managed, and place both in the source control system.

suparnabanerje_0-1674123826749.png

 

Fig 1

 

In this article, we will show the steps to achieve the Option above 2 above, and Fig 1 depicts the process.

 

1.Setup source and Target environment

 

Create source and target environments. Both should have Dataverse database enabled. Create an unmanaged Solution in the source environment

 

2.Set up Azure DevOps

 

  1. Create Azure Dev Ops Organization
  2. Create the Project within it
  3. Create the Repository to hold the source code
  4. Install Microsoft Power Platform Build Tools into your Azure DevOps organization from Azure Marketpl...
  5. Request parallelism if using Azure DevOps pipelines for first time using the link https://aka.ms/azpipelines-parallelism-request.
  6. Within the Project, navigate to Project Settings> Repositories>Security Tab. Under user Permissions, make sure that for Project Collection Service Accounts under Azure DevOps Groups and <ProjectName> Build Service <OrgName> under users Contribute Permission is set to allow

suparnabanerje_1-1674123826755.png

 

suparnabanerje_2-1674123826760.png

 

 

3a. Create Azure DevOps Pipelines with Application ID and Client Secret

 

Create Azure AD App Registration

 

  1. Go to https://portal.azure.com
  2. Search for App Registration, click New Registration
  3. Provide the name, keep other fields with default value and click Register
  4. Once the App is created, go to API Permissions, click Add a Permission>Select Dynamics CRM>Add Permission >Grant Admin Consent for <tenant>suparnabanerje_3-1674123826766.png
  5. Go to Overview>Client credentials>New Secret. Copy the value into a notepad as this will be needed later and you won’t be able to get it once navigate away from this page.
  6.  Come back to overview, and copy the Application (client) ID and Directory (tenant) ID in the same notepad. You will need these 3 values while creating service connection

 

Add the service principal as App user into Power Platform source and destination environment.

 

  1. Go to Power Platform Admin Center>Environments
  2. Select your Source Environment
  3. From right navigation, Users >See All>App users list
  4. Click New App user>search for the App created in Previous step>Add it and provide System Customizer or System Administrator role.
  5. Repeat all the steps above for the destination environment

 

Create Service Connection with Application ID and Client Secret

 

  1. Go to your Azure DevOps Project, click Project Settings.
  2. Under Pipelines, click Service Connections >New Service Connection>Select Power Platform
  3. Select Authentication method as Application ID and client secret
  4. Go to make.powerapps.com> Select your Source environment >Go to Settings>Session details>copy the Instance url and paste it under Server Url
  5. Paste Tenant Id, Application Id and Client Secret as saved earlier
  6. Save the Service Connection with the name “Dev Service Principal”
  7. Follow the steps ii to vi above , this time get the destination environment url, create the service connection and save as “Prod Service Principal”

 

Create Pipeline – Export from Source

 

i.  From the left navigation within the Project, click on Pipelines >New Pipeline>Use the Classic Editor

ii.  Select the Source as Azure Repos Git, select your Project, Repository and Branch and click continue

suparnabanerje_4-1674123826768.png

 

iii.  Under select template, start with Empty job

suparnabanerje_5-1674123826769.png

 

 

iv.  Click Agent Job 1 and make sure Allow Scripts to access OAuth token is checked

suparnabanerje_6-1674123826770.png

 

 

v.  Add the task Power Platform Tool Installer with task version 2

suparnabanerje_7-1674123826776.png

 

 

vi.  Add the task Power Platform Export Solution. We are adding the task to export the solution as unmanaged here

suparnabanerje_8-1674123826778.png

 

 

suparnabanerje_9-1674123826789.png

 

 

For Service Connection, Select Service Principal> Select Dev Service Principal from Dropdown

Provide your Solution Name (not the display name)

Solution output file name $(Build.ArtifactStagingDirectory)\<SolutionName>.zip

Uncheck export as Managed Solutin

 

vii.  Copy the above task . This time we are exporting managed solution. Keep all settings same, only check the box Export as Managed solution and the Solution Output file name to $(Build.ArtifactStagingDirectory)\<SolutionName>_managed.zip

 

viii.  Add the task Power Platform Unpack Solution

suparnabanerje_10-1674123826801.png

 

 

Solution Input File -$(Build.ArtifactStagingDirectory)\<SolutionName>.zip

Target Folder to Unpack Solution - $(Build.SourcesDirectory)\<SolutionName>

Type of Solution – Both

 

ix.  Add a task Command Line script, and paste the below script

 

echo commit all changes

git config user.email “<email>”

git config user.name "<user name>"

git checkout -B main

git add --all

git commit -m "code commit"

git push --set-upstream origin main

 

x.  Save and queue the Pipeline and wait it to be finished

xi.  Check the repository for the unpacked source code

 

suparnabanerje_11-1674123826803.png

 

 

Create Deployment Settings File

 

  1. Open Visual Studio Code
  2. Install PAC CLI
  3. Run the below command to export the solution in your local machine

 

pac solution export --name <solutionname> --path .\ --managed false

 

     iv.  Run below command to create Deployment Settings file

 

pac solution create-settings --solution-zip .\<SolutionName>.zip --settings-file <SolutionName>.json

    v.  Update values in the Deployment Settings file for the target environment

    vi.  In the Repository, create a Folder named Settings, create a file <SolutionName>.json within it, copy the text from the Deployment Settings File

suparnabanerje_12-1674123826808.png

 

 

Create Build Pipeline

 

  1.             Create a new Pipeline with Classic Editor>Empty Job
  2.             Add the task Power Platform Tool Installer
  3.             Add a task Power Platform Pack Solution

suparnabanerje_13-1674123826818.png

 

Source Folder of Solution to Pack -Select Folder by clicking 3 dots

Solution Output File -<SolutionName>.zip

Type of Solution -Both

  iv.     Add a task -Copy Files

suparnabanerje_14-1674123826827.png

 

Source Folder -Settings

Contents -**

Target Folder - $(Build.ArtifactStagingDirectory)

 

  v.   Add a task Publish Artifact

 

suparnabanerje_15-1674123826835.png

 

 

Path to publish - $(Build.ArtifactStagingDirectory)

Artifact Name – drop

 

  vi.   Save and Queue the Build Pipeline

 

Create Release Pipeline

 

  1.             From Left navigation, click Releases >New Release Pipeline >Start with Empty Job
  2.             Add the Artifact created in the Build pipeline

suparnabanerje_16-1674123826845.png

 

Select your project and build pipeline

Source alias -drop

  1.             Under Stages>Stage 1>Click Job
  2.             Add the task Power Platform Tool installer
  3.             Add the task Power Platform Import Solution

 

suparnabanerje_17-1674123826855.png

 

      iv.   Service Connection – Select the service connection you created for Prod.

       v.   Solution Input File – Select clicking 3 dots, select the managed zip file for Prod

suparnabanerje_18-1674123826859.png

      vi.   Check Use Deployment Settings File and select the Deployment settings file by clicking 3 dots.

      vii.  For Prod, under Advanced, check Import Managed Solution

       viii.  Save the pipeline and create a Release

       ix.  Check the Solution has been deployed properly to Production

 

3b. Create Azure DevOps Pipelines with Managed Identity

 

    1. Create VMScaleSet and assign Managed Identity
    2. Create Self hosted Agent pool and point to the VMscale set
    3. Add the managed identity as App user into Power Platform source and destination environment.
    4. Create Service Connection with managed identity.
    5. Create Build Pipelines- Export from Source and Build Solution. Create Release Pipeline – Deploy to Destination . Use previously created self-hosted agent pool.