1 - How is PPAC different from LCS

The twilight of LCS

How This Is Different from LCS

If you've been building and deploying D365 Finance and Operations using Lifecycle Services, you already know the rhythm: write X++ in Visual Studio, build on a dedicated build VM, upload the deployable package to LCS, click through the portal to apply it to an environment. It works, but every step requires a human clicking buttons in a browser or something similar. It worked but its clunky.

This series replaces that workflow with something fundamentally different. Before we get into the how, let's understand the why.

The LCS Paradigm

With LCS, the infrastructure looks like this:

  • Build VM - A dedicated virtual machine (often a Tier 1 cloud-hosted environment) that compiles your X++ code. You pay for it whether it's building or sitting idle. Cloud builds in Azure DevOps have been available for a while but I still see a fair amount of build VMs being used.
  • Manual package upload - You download the deployable package from the build VM, upload it to LCS, then apply it through the portal. We have an API for this but its fairly new considering LCS's age and uptake of it has been slow.
  • Portal-driven deployments - Almost every deployment is a human clicking "Apply" in a browser, waiting, and hoping nothing fails. To LCS's credit, it would communicate well what it was doing - or not doing - almost to a fault. I filter nearly all LCS emails that don't contain words like "error" or "failure".
  • Environment provisioning - Need a new sandbox? Submit a request, wait for it, pay for the SKU monthly. Environments are long-lived and expensive. We can spin up dev tier environments but those came with some additional items to manage because of infrastructure differences between tier 1 and 2.

This model works for small teams with infrequent releases. But it doesn't scale, it's error-prone, and it can't enforce quality gates automatically. In the past I've written about TFVC gated check-ins, various pipeline automations that can be done and other strategies to improve delivery of code but those are band aids on a far more fundamental problem. X++ development is specialized with unique constraints with limited APIs, hooks or other technologies to support scale and automation that our .net colleague have had for a while.

The PPAC Paradigm

The Power Platform Admin Center (PPAC) APIs give you a completely different model:

  • Hosted build agents - Microsoft-managed VMs that spin up for your build and disappear afterward. No idle costs. About $40/month for 1 parallel job. There are free options as well that work for just builds but not-so-much for deployments or releases. We've had this as an option for a while but combining hosted build agents with Git's available orchestration hooks and we have powerful new options.
  • API-first everything - Provisioning, deployment, database copy, tear down - all done through REST APIs, not portal clicks. For the most part, if there is a UI for a feature in PPAC, there is also an API for it so automation possibilities are nearly limitless.
  • Environments on demand - Need a dev/sandbox for a feature branch? The pipeline provisions one, copies your database, and has it ready in about 5-6 hours. When the branch is deleted, a daily cleanup pipeline tears it down automatically. Also creating environments can be done with various automation so if you don't want to use PowerShell, you could use a pipeline if you prefer.
  • Push-to-deploy - Push code to a release branch and the pipeline chain fires automatically: build, deploy to UAT, get approval, deploy to DM, get approval, release to GOLD, then finally release to production (with approval gates).

The Key Mental Model: Infrastructure as Code

The biggest shift is philosophical. In the LCS world, your deployment process lives in your head (or maybe a wiki page): "first do this, then click that, then wait for this.". Potentially lots of manual steps to get a final result of a package going to a particular environment. In the PPAC world, your deployment process lives in YAML files checked into your repository. Your pipeline YAML defines what happens, when it happens, and in what order. It's reviewable, version-controlled, and repeatable. If someone asks "how do we deploy to production?" the answer is: read the YAML file. The entire process is codified in source code so your code is what deploys your code. This scales, executes based on events, gets approvals when needed and does nothing when those approvals aren't provided. 

What Stays the Same

Not everything changes. Your X++ code is still X++ code. You still write models, build deployable packages, and apply them to environments. The difference is who does the work. Instead of you clicking through LCS, a service principal (a "robot user" - more on that in the next article) does it programmatically, every time, the same way, without mistakes. So development is about the same for developers, but how we get environments and data changes - for the better. We still have deployments to F&O with downtime and the experience for F&O users is about the same meaning servicing for F&O still is a down time event in all environment types. We still will deploy packages from builds to all non-dev sandboxes and through approval gates, we won't be directly deploying to PROD.

What's Different

PPAC environments take a new kind of package. The build process is the same for x++ but the package that gets generate is a "cloud" package. An LCS style package is called a regular package. The new cloud package presents a zip folder containing a DLL and from that, instructions on how to deploy the package are derived. This doesn't effect the specific outcome but PPAC hosted environments can only accept the newer "cloud" style package so if you try to deploy a regular package, you'll get an error. You can convert from regular package to a cloud package if you'd like manually.

A Visual

Now that you understand how this approach differs from LCS, the next article will explain the concept of a service principal - the automated identity that makes all of this possible.