DEV Community

Cover image for Fixing Power Platform Pipelines
david wyatt
david wyatt Subscriber

Posted on

Fixing Power Platform Pipelines

Although Microsoft really didn't plan (or probably want you to) most organisations understood the benefits of application lifecycles and instigated a Dev / Test / Prod environment strategy.

With all of the benefits unfortunately came a big negative, and that is the overhead of deploying solutions.

This lead the the launch of Power Platform pipelines, but back to the first sentence, this was implemented quite right. And that's because a big part of lifecycle management includes segregation of duty, ago the developer should not have access to test or prod. The standard pipeline requires that the developer has full maker access to test and prod, which in the real world leads to developers editing in prod.

Microsoft again listened and released delegated deployments, using either a application account (SPN) or a normal but non-human account (Service Account). But again there were issues:

SPN Issues

  • Requires the developer who creates the pipeline to own the SPN in Azure, not good security practice
  • Uses the developers connections, so although they don't have access to test/prod environment, they have access to test/prod data

Service Account

  • Cant deploy connectors (yep you heard me, only solutions with no connections!)

Luckily there is a workaround to the issues, to get Power Platform Pipelines fit for use.

  1. Design
  2. Implementation
  3. Flows

1. Design

The workaround works on 3 key facts:

  • Delegated Service Accounts can create their own connections
  • SPNs can have connections shared with them
  • Solutions have a config json included

So the workaround is a little bit of hot potato, with the connections being passed around.

design

  • First we update the config json with the Service Accounts connections
  • The Pipeline then deploys using the Service Accounts connections
  • After deployment the SPN swaps the connections (and the components) to the new owner

2. Implementation

Unfortunately then implementation is a little more complex, as we need to have some prior setup and extra admin.

Extra Setup

What's great about the pipeline is it allows you to create the connection in the target environment when you trigger the run. But that can't be done if not using the developers connections, so we have to set them up before.

In every target environment we need to create all possible connections that the Service Account could use.
Additionally we have to setup the solutions new owners connections, and share them with the SPN.

Extra Admin

As we have add extra complexity we need a way to administer this, and the key data we need is:

  • Solution
  • New Owning Service Account

as without that data we wont know which account to change to after import.

The easy way is to create a Dataverse table and Model Driven app (I call it the Pipeline Register), and while we are doing all that work we might as well add in some useful data like:

  • Approval
  • Documentation Link
  • Change Number
  • Developer team (so we can share read only access)

And once all that is done we end up with something like this:

full design
Better resolution version here

3. Flows

Power Platform Pipelines have a very important feature, Gated Extensions.

gated extensions

So we going to leverage these gates to run flows to action our required updates.

OnApprovalStarted

These flow will create the Solution config json file which will update the connection references to use the delegated deployment service account.

  • First we get the deployment stage run details run stage info
  • Next we parse the json config from the table (@{outputs('Get_a_row_by_ID')?['body/deploymentsettingsjson']})
  • Then we need to find the connections for the Service Account in the target environment using Get Connections as Admin and filtering
  • Then from the parse we loop over each connection reference and find the exact connection in the target environment
and(
  contains(item()?['id']
,
  split(items('For_each')?['ConnectorId'],'/apis/')[1])
,
  equals(
    item()?['properties/displayName']
  ,
    parameters('Pipeline-DelegatedAccount (ia_PipelineDelegatedAccount)')
  )
)
Enter fullscreen mode Exit fullscreen mode
  • Next is to set the property of a holding array variable to the new connection reference
setProperty(
  items('For_each')
,
  'ConnectionId'
, 
  body('Filter_array_connections')[0]?['name']
)
Enter fullscreen mode Exit fullscreen mode
  • Finally we update the deployment stage run detail item will found at the beginning update run item We get the environment variables from the parse JSON so not to wipe them

full flow

As this is also prior to import this is where I would add additional checks and approvals:

  • Is it in the Pipeline Register
  • If its to prod is it approved

OnDeploymentCompleted

After the solution is imported we need to change everything over from the delegated service account to the owning account.

The 2 key steps are:

You must do it in above order as the new owner must have access to the connection used

And like pre approval there are other actions you can take:

  • Share any flows with dev team
  • Back up solution to external repository
  • Share App url's

process


As you can see there is definitely added complexity, especially around pre setting up connections. I tried the Power Automate Management action, Create Connection but always get errors. The other option is our trust Power Automate Desktop to do it through the UI, but I really wish there was some sort of credential bank for admins to manage them.

But if your org follows good practice like true separation of duty and application lifecycle management, then you can at least now use the inbuild Pipelines.


 
😎 Subscribe to David Wyatt

Top comments (11)

Collapse
 
brynhh profile image
James Holland-Hart

Hi David, interesting article if people must use PP pipelines. However, I feel this is a very maintenance heavy way of achieving it and is why we have the options of both PPP and build tools. Build tools in ADO do this out of the box via deployment settings json files easily. We’ve had it for 2 years and are now migrating over from classic releases to full yaml, as its standardised ALM with the coding world and PPP don’t really make anything simpler.

We had a session with Nick Doelman recently and although PPP have improved, they still very much fit a different purpose to me.

Collapse
 
wyattdave profile image
david wyatt

Hi James, you are not the only one to say this, but both sides have complexity, And in my experience keeping it in one platform and one skill set is more scalable and stable. Also I prefer my Devs being able to do everything from inside the platform. And for me the biggest part of complexity is swapping connection, which both needs external setup. Also how do you swap owner from the spn with ADO, something I could never figure out.

Collapse
 
brynhh profile image
James Holland-Hart

Excuse my ignorance, but you'll have to explain what you mean by swapping the connection. As far as I'm aware, all connections have to be owned by someone, regardless if they use interactive (service) accounts like Outlook, or service principals like say Oracle. We do those as the single service account (with MFA tied to it), share them with the Azure App Registration that imports solutions in ADO and use the IDs in the deployment settings JSON to set the connection reference. If we want to change the connection the reference points at, we simply change the ID and re-release that solution.

I do understand what you mean about 1 platform, but for me it's more about pick the right/better tool for the job and people just have to learn. Software has always adapted, as have the people with it. For us, trying to implement sustainable and enterprise level ALM via PP Pipelines is a total no-go. The PAC CLI is ever growing and build tools will with it (as they are just a front end). However, it's a fantastic tool for maybe smaller, localised or other types of deployments. Different tools for very different purposes.

Thread Thread
 
wyattdave profile image
david wyatt

For compliance we ensure that there is different owners of connections in dev/test/prod (ef that sensitive data in SharePoint should not be accessed by dev or test). The only way to swap is for the spn to have the connection shared in advance, and also created in advance. Which takes a lot of effort (as you will should be using different accounts for each solution). Additionally the spn shouldn't really own the solution in the target environment, as it can't have a premium license etc. so we need to deploy, change connections (pre created and shared) and change owner.

Thread Thread
 
brynhh profile image
James Holland-Hart

Got you, we have a live and non-live account that own connections (we may segregate more in the future) and deployment settings is fine for that. The file doesn't contain the actual IDs (or env var values), but placeholders and we store the ID/values in ADO variable groups, then a task replaces the placeholder values with those for each environment individually. You're right in that we need to create the connection as the interactive users, share them and get the IDs, but that's by design to use the deployment settings json for the build tools. It's a one time thing and took hardly any time to setup.

We've also never had an issue with the app user (azure app reg, what I'm assuming you're referring to as service principal) being the owner of our flows, and they use multiple premium connectors like word mail merge, dataverse, sql server. We use per user licensing for now (aware this has performance limitations, but it's fine for us) rather than per flow and the references point to the service account.

I've got a guide on my blog, but it's a bit long and I'll be redoing it for the fully yaml approach soon. But I'm happy to share the files on how we've done it if you like.

Thread Thread
 
wyattdave profile image
david wyatt

Makes sense, nice setup, unfortunately with our volumes and the $200 per month licences cost it was not sustainable. Hopefully Microsoft allows spn license like a user license soon

Thread Thread
 
brynhh profile image
James Holland-Hart • Edited

Not sure why it would cost that much per user. You have stakeholder access, which is free for limited work item features. You can have any number of pipelines totally free:

Are there limits on who can use Azure Pipelines?

You can have as many users as you want when you're using Azure Pipelines. There's no per-user charge for using Azure Pipelines. Users with both basic and stakeholder access can author as many builds and releases as they want.

Are there any limits on the number of builds and release pipelines that I can create?

No. You can create hundreds or even thousands of pipelines for no charge. You can register any number of self-hosted agents for no charge.

https://learn.microsoft.com/en-us/azure/devops/pipelines/licensing/concurrent-jobs?view=azure-devops&tabs=ms-hosted#faq

You can also use git (to store your json, yaml, unmanaged backups, etc) for 5 people, then it's only $6 each.

azure.microsoft.com/en-us/pricing/...

Thread Thread
 
wyattdave profile image
david wyatt

The per flow license is $200 per month (though been a while since I checked so maybe less but compared to free or premium per user its expensive), its the only way you can have an spn as owner of a flow (as you cant assign user license to them) and you mentioned thats how you license them. I know there is no limits on who uses Azure pipelines, but creating them does require ADO and storage (no matter how small). Yep they scale really well, but if you are using them for hundreds or thousands then thats very expensive (from the license side, as each solution will have a per flow license). If Micrsoft fixed this with a SPN license it would be great, but at the moment I suspect a lot of orgs are techincally in breach of license as they dont assign any license to the spn.
For Apps its a different matter as there is no license issue, but Power Platform pipelines can just use a service account with no extra steps as there are no connections (so all complexity has gone there too).

Thread Thread
 
brynhh profile image
James Holland-Hart

No we license using per user, which is our interactive service account. The owner is still the azure app registration used to import via ADO. Per user in my last job used to be £60 for a pack of 5, but that’s academic and even if it was 240 (the most we get is 25% of full retail) that’s still not 200 each.

Thread Thread
 
wyattdave profile image
david wyatt

I just checked and its $150 USD (microsoft.com/en-us/power-platform...), with 250k power platform api calls versus premium user 40k it was always going to be more expensive, plus now they rolled in PAD as well.
If the owner is a App and not a service account then technically you are unlicensed. Thouugh Microsoft knows that this is rediculous as they provide guides to use SPN but no license to purchase, so they dont enforce it. But its a grey area and something some legal depts wont do just to be 100% compliant.