Pets vs. Cattle – How to manage your Power App Environments

A situation I see very frequently is where there is a ‘special’ PowerApps environment that holds the master unmanaged customizations. This environment is looked after for fear of losing the ability to deploy updates to production since with managed solutions you can’t re-create your unmanaged environment. Sometimes, a new partner starts working with a customer only to find that they have managed solutions in production with no corresponding unmanaged development environment.

I’m not getting into the managed/unmanaged debate – but let’s assume that you are following the best practices outlined by the PowerApps team themselves “Managed solutions are used to deploy to any environment that isn't a development environment for that solution”[1]+[2]

There is a phrase that I often use (adapted from its original use [3]):

“Treat your environments like cattle, not pets”

This really resonates with the new PowerApps environment management licensing where you pay for storage and not per-environment. You can create and delete environments (provided you are not over DB storage capacity) with ease.

If you store your master unmanaged solution in an environment – and only there – then you will start to treat it like a pet. You’ll stroke it and tend to its every need. Soon you’ll spend some much time in pet-care that you’ll be completely reliant on it, but it’ll also be holding you back.

There is another principle I am very vocal about:

“Everything as code”

This is the next logical step from “Infrastructure as code” [4]

In the ‘everything as code’ world, every single piece of the configuration of your development environment is stored as code in source control, such that you can check-out and build a fully functioning unmanaged development environment that includes:

  1. Solution Customisations as XML
  2. Canvas Apps as JSON
  3. Flows as JSON
  4. Workflows as XAML
  5. Plugins as C#
  6. JS Web resources as TypeScript
  7. Configuration data as Xml/JSON/CSV
  8. Package Deployer Code
  9. Test Proxy Stub Code for external integrations
  10. Scripts to deploy incremental updates from an older version
  11. Scripts to extract a solution into its respective parts to be committed to source control
  12. Scripts to set up a new development environment
    1. Deploy Test Proxy Stub Services
    2. Build, Pack and deploy a solution to a new environment
    3. Deploy Reference Data
    4. Configure Environment Variables for the new environment

There are still areas of this story that need more investment by the PowerApps teams such as connector connection management and noisy diffs – but even if there are manual steps, the key is that everything is there in source control that is needed. If you lose an environment, it’s not a disaster – it’s not like you have lost your beloved pet.

The advantages of combining these two principles are that every single time you make a change to any aspect of an environment, it is visible in the changeset and Pull Request

If you are working on a new feature, the steps you’d take would be:

  1. Create a new branch for the Issue/Bug/User Story
  2. Checkout the branch locally
  3. Create a new development PowerApps environment and deploy to it using the build scripts
  4. Develop the new feature
  5. Use the scripts to extract and unpack the changes
  6. Check that your changeset only contains the changes you are interested in
  7. Commit the changes
  8. Merge your branch into the development/master branch (depending on the branching strategy you are using)
  9. Delete your development environment

Using this workflow, you can even be working on multiple branches in parallel provided there won’t be any significant merge conflicts when you come to combine the work. Here is an example of a branching strategy for a hotfix and two parallel feature development branches:

The most common scenario I see where there are merge conflicts are RibbonXml, FormXml, and ViewXml – the editing of both of these elements is now supported – and so you can manage merge conflicts inside your code editor! CanvasApps and Flows are another story – there really isn’t an attractive merge story at this time and so I only allow a single development branch to work on Canvas Apps, Flows, and Workflows at any one time.

If you think you have pet environments, you can still keep them around until you feel comfortable letting go, but I really recommend starting to herd your environments and get everything extracted as code. You’ll not look back.



[1] ALM Basics -

[2] Solution Concepts -

[3] Pets vs Cattle -

[4] Infrastructure as Code -

[5]  ALM with the PowerPlatform -

[6] ALM for Developers -

[7] Supported Customization Xml Edits -

[9] Healthy ALM -

Pingbacks and trackbacks (2)+

Comments are closed