| name | powerplatform-alm |
| description | Power Platform Application Lifecycle Management best practices. Covers environment strategy, solution architecture, source control, CI/CD pipelines, managed deployments, environment variables, connection references, data migration, and operational governance. Produces ALM strategy documents, pipeline definitions, and operational guidance. Triggers on "ALM", "application lifecycle management", "environment strategy", "solution architecture", "CI/CD", "deployment pipeline", "managed solution", "unmanaged solution", "solution checker", "power platform pipelines", "pac cli", "source control", "git integration", "environment variables", "connection references", "deployment strategy", "managed environments", "solution layering", "active layers". |
| user-invocable | true |
Power Platform ALM Skill
Expert guidance for healthy Application Lifecycle Management on the Microsoft
Power Platform — from environment strategy and solution architecture through
source control, automated deployment, and operational governance.
This skill produces ALM strategy documents, pipeline definitions, and operational
guidance. It does NOT write application code.
The ALM Golden Rules
These are non-negotiable. Enforce them on every engagement.
- Never customize outside a development environment. Test and production receive
managed solutions only.
- Always work in the context of solutions. Never create components in the Default
Solution.
- Use a custom publisher and prefix. Define the publisher first (2–8 lowercase chars),
then create solutions bound to it.
- Export unmanaged from dev, import managed to downstream. Unmanaged = active
development. Managed = distribution/deployment.
- Use environment variables for environment-specific config. Never hard-code URLs,
connection strings, or feature flags. Remove current values before export so they
don't overwrite target values on import.
- Use connection references for connectors. Connections must be reconfigurable per
environment without code changes.
- Automate deployments. Manual export/import is acceptable for learning. Production
releases go through pipelines, Azure DevOps, or GitHub Actions.
- Source control is the source of truth. Not maker environments. Environments can be
rebuilt from source at any time.
Workflow
Step 1 — Assess Current State
Before recommending changes, understand what exists:
- How many environments? What types (sandbox/production/developer)?
- Are solutions in use? Custom publisher? Default Solution components?
- Is source control in place? PAC CLI unpack to Git, or none?
- How are deployments done? Manual, Power Platform Pipelines, Azure DevOps, GitHub Actions?
- Are there active layers? Unmanaged customizations on top of managed solutions in non-dev?
- Environment variables and connection references? Used consistently or hard-coded?
Step 2 — Environment Strategy
- Define environment topology: Dev → Test (→ UAT/SIT) → Pre-prod → Production.
- At minimum: separate Dev and Production. Recommended: Dev, Test, Production.
- Dev environments should be sandbox type. Production environment is production type.
- Secure every environment with Entra Security Groups to limit access to members.
- Consider short-lived dev environments that can be rehydrated from source control —
reduces storage costs and configuration drift.
- Enable Managed Environments on all pipeline target environments (required for
pipelines, solution checker enforcement, and enhanced governance).
Step 3 — Solution Architecture
- Single solution for small–medium projects; modular segmented solutions when
components deploy on independent cadences.
- Use table segmentation to keep solution size manageable and reduce import times.
- Never add components to the Default Solution — always include the
MSCRM.SolutionUniqueName header at creation time.
- Version systematically using
Major.Minor.Build.Revision. Increment on every change.
- Set managed properties before exporting as managed to control what downstream
consumers can customize (display names yes, new columns no, etc.).
- Understand solution layering: unmanaged (Active layer) > managed (latest installed) >
system. Never create unmanaged customizations on top of managed solutions in non-dev
environments — this creates active layers that block future managed updates.
- Separate solutions only when you need independent deployment cadences (e.g., a shared
component library consumed by multiple apps).
Step 4 — Source Control & Git Integration
- PAC CLI (recommended for code-first solutions):
pac solution clone,
pac solution export, pac solution unpack / pac solution pack. This is the
recommended approach for solutions that contain Code Apps, Power Pages code sites,
or plugin assemblies — these code-first artifacts require a build step (npm, dotnet)
that the native Git integration cannot orchestrate.
- Workflow: export unmanaged zip from dev → unpack to repo folder → commit to Git →
in the pipeline: pack from repo → build code artifacts → push to dev → re-export →
import managed to downstream.
- Adopt a Git branching strategy (trunk-based or feature branches) and enforce pull
request reviews before merging to main.
- Use source control for security scanning (integrate your scanning tool in Azure
DevOps).
Note on Dataverse native Git integration: The built-in Git integration
(make.powerapps.com → Solutions → Git settings) stores solution objects as YAML in
Azure DevOps repos. While convenient for low-code solutions, it does not support
code-first artifacts well — Code App source, Power Pages code site source, and plugin
assembly source all live outside the solution and require build toolchains. Until native
Git integration supports the full code-first lifecycle, use PAC CLI for solutions that
include these components.
Step 5 — CI/CD & Deployment Pipelines
- Power Platform Pipelines (in-product): low-code, citizen-developer-friendly.
Admins configure in minutes. Makers deploy with a click from their development
environment. Supports approvals, service principals, up to 7 stages.
- Target environments must be Managed Environments.
- Default import behavior is Upgrade without overwrite customizations.
- Supports redeployment of previous solution versions from run history.
- Azure DevOps Build Tools: Power Platform Build Tools tasks for export, pack,
import, solution checker, environment management. Best for enterprise CI/CD with
gated pipelines, parallel stages, and approval workflows.
- GitHub Actions for Power Platform:
powerplatform-actions marketplace actions.
Same capabilities, GitHub-native.
- PAC CLI commands:
pac solution export, pac solution import,
pac solution check, pac solution create-settings, pac pipeline deploy,
pac pipeline list.
- Run Solution Checker (static analysis) as a quality gate before deployment.
Managed Environments can block or warn on import if critical violations are found.
Step 6 — Solution Import Strategy
- Upgrade (default): adds, updates, AND deletes components not in the new version.
Use for standard deployments — ensures target matches source exactly.
- Stage for Upgrade: creates a holding solution; you migrate data, then apply.
Use when deleting tables that contain production data.
- Update: adds and updates only; does NOT delete missing components. Use only when
you deliberately need to keep divergent components in the target. Avoid by default.
Step 7 — Data Migration
- Solution export/import does NOT include data — only schema and configuration.
- Never recreate reference/master data manually (generates new GUIDs, breaks code
references).
- Use the Configuration Migration tool (Power Platform SDK) for reference data.
- For simpler cases, use Excel export/import.
- Plan data migration as a first-class concern, not an afterthought.
- Use versioned data migrations for schema-dependent data changes. When a schema
change requires data backfill, transformation, or seeding, manage it via ordered,
idempotent migration scripts tracked by a SchemaVersion table — the same pattern as
Entity Framework migrations, Flyway, or Liquibase. The migration runner runs
after solution import in the deployment pipeline, detects the environment's
current version, and applies all pending migrations in order. A failure stops the
pipeline. See
../dataverse-solution-web-api/resources/schema-migration.md →
"Versioned Data Migrations" for the full framework, manifest format, runner script,
migration rules, and pipeline integration example.
Step 8 — Environment Variables & Connection References
- Define environment variables for every setting that differs across environments
(API endpoints, feature flags, tenant-specific values).
- Remove current values from environment variables before exporting — current values
travel with managed solutions but do NOT overwrite existing values on import, which
can cause confusion.
- Use connection references so connectors can be repointed per environment without
modifying the solution.
- For secrets, use Azure Key Vault environment variables (secret type).
Deployment Settings File (pac solution create-settings)
Use pac solution create-settings to generate a JSON settings file from a solution
zip. This file maps environment variables and connection references to target-specific
values, enabling automated deployments without manual post-import configuration.
Generate the settings template:
pac solution create-settings --solution-zip ./export/YourSolution_managed.zip --settings-file ./deploy/settings-test.json
This produces a JSON file with placeholders for every environment variable and
connection reference in the solution:
{
"EnvironmentVariables": [
{
"SchemaName": "cnt_ApiBaseUrl",
"Value": ""
},
{
"SchemaName": "cnt_FeatureFlag_EnableBeta",
"Value": ""
}
],
"ConnectionReferences": [
{
"LogicalName": "cnt_SharedDataverseConnection",
"ConnectionId": "",
"ConnectorId": "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps"
}
]
}
Create one settings file per target environment:
deploy/
settings-test.json ← values for Test environment
settings-production.json ← values for Production environment
Fill in the values for each environment:
- Environment variables: set
Value to the target-specific string
- Connection references: set
ConnectionId to the GUID of the connection
in the target environment (find via pac connection list or the Power Platform
admin center)
Use the settings file during import:
pac solution import --path ./export/YourSolution_managed.zip --settings-file ./deploy/settings-test.json --activate-plugins
In Azure DevOps / GitHub Actions:
- task: PowerPlatformImportSolution@2
inputs:
authenticationType: PowerPlatformSPN
PowerPlatformSPN: $(ServiceConnection)
SolutionInputFile: $(Build.ArtifactStagingDirectory)/YourSolution_managed.zip
UseDeploymentSettingsFile: true
DeploymentSettingsFile: $(Build.SourcesDirectory)/deploy/settings-$(Environment).json
- uses: microsoft/powerplatform-actions/import-solution@v1
with:
environment-url: ${{ secrets.ENV_URL }}
solution-file: ./export/YourSolution_managed.zip
deployment-settings-file: ./deploy/settings-${{ matrix.environment }}.json
Rules:
- Store settings files in source control alongside the solution source — they are
environment configuration, not secrets.
- Never hardcode secrets in settings files. For Azure Key Vault environment variables,
set the
Value to the secret reference URI, not the secret itself.
- Regenerate the template when the solution changes. If you add new environment
variables or connection references, re-run
create-settings to get the updated
template, then merge the new entries into each environment's settings file.
- Connection IDs are environment-specific. The same connector type has different
connection GUIDs in each environment — you must look them up per target.
- Settings files eliminate post-import manual steps. Without them, someone must
manually set environment variable values and fix connection references after every
managed import — this is the #1 reason "it works in dev but breaks in test."
Step 9 — Service Principals & Automation
- Use
pac admin create-service-principal to create an Entra app + application user.
- Service principals enable unattended pipeline deployments without interactive login.
- Assign minimal security roles to service principals (principle of least privilege).
- Service principals own deployed solution objects in delegated deployments —
plan ownership carefully.
Step 10 — Operational Governance
- Run Solution Checker regularly, not just at deployment time.
- Enforce solution checker in Managed Environments to block imports with critical
violations.
- Monitor deployments via the Power Platform Admin Center Deployment page — visibility
into all pipeline runs, approval requests, and troubleshooting.
- Maintain rollback capability: keep solution artifacts versioned, use pipeline run
history to redeploy previous versions, or restore from Git.
- Set retention policies for pipeline run data (bulk delete jobs in the pipelines host).
- Use point-in-time environment restore as a last-resort rollback mechanism.
Step 11 — Testing Strategy
- Validate solution imports in a dedicated test environment before production.
- Run automated tests: Power Apps Test Engine for canvas apps, Playwright for Code Apps
and Power Pages, integration tests for Dataverse operations.
- Conduct UAT in a separate environment that mirrors production.
- The test environment proves that both the app and the deployment itself work.
Output Format
Environment Strategy Assessment
ENVIRONMENT: [Dev / Test / UAT / Pre-prod / Production]
Type: [Sandbox / Production / Developer]
Managed: [Yes / No — REQUIRED for pipeline targets]
Security: [Entra Security Group assigned? Y/N]
Purpose: [What happens here]
Drift Risk: [Low / Medium / High — explain]
Solution Architecture Assessment
SOLUTION: [Unique Name]
Publisher: [prefix — customizationprefix]
Strategy: [Single / Segmented / Modular]
Versioning: [Current version, increment policy]
Managed Properties: [Configured? Y/N]
Env Variables: [Count, any with current values that should be removed]
Connection Refs: [Count, any hard-coded connections?]
Deployment Pipeline Assessment
PIPELINE: [Name / Type]
Method: [PP Pipelines / Azure DevOps / GitHub Actions / Manual]
Stages: [Dev → Test → Prod (list)]
Automation: [Full / Partial / Manual]
Quality Gates: [Solution Checker / Tests / Approvals]
Rollback: [Strategy — redeploy previous, Git restore, env restore]
Gaps: [What's missing or at risk]
Priority: [Critical / High / Medium / Low]
ALM Health Check (for existing projects)
ALM HEALTH CHECK
Golden Rule Violations:
[ ] Components in Default Solution
[ ] Unmanaged customizations in non-dev environments
[ ] Missing publisher prefix
[ ] No source control
[ ] Manual deployments to production
[ ] Hard-coded connection strings / no env variables
[ ] No solution checker in pipeline
[ ] Active layers blocking managed updates
Maturity Level: [1-Ad Hoc / 2-Basic / 3-Standard / 4-Advanced / 5-Optimized]
Top Priority: [Single most impactful improvement]
Anti-Patterns to Flag
- "We just export and import manually" — works for 2 people, breaks at 5. Automate.
- "We customize directly in production" — creates unmanaged active layers that block
all future managed updates. Stop immediately.
- "Everything is in the Default Solution" — cannot be exported, versioned, or deployed
as a unit. Move to a custom solution.
- "We use unmanaged solutions in production" — deleting an unmanaged solution leaves
all components behind. Use managed.
- "We recreate reference data manually" — generates new GUIDs every time. Use
Configuration Migration tool.
- "We don't need source control, we have backups" — backups don't give you branching,
history, code review, or merge. Use Git.
- "One big solution with everything" — fine for small projects, but consider
segmentation when import times grow or teams need independent cadences.
- "We'll set up ALM later" — technical debt compounds. Set up publisher, solution,
environments, and source control before writing the first component.