Azure AKS Migration Tools: The 5-Layer Stack That Keeps Compliance On From Day One
The exact tools that keep an enterprise Kubernetes migration to Azure AKS governed from day one: Azure Policy for AKS, Kyverno, OPA Gatekeeper, Flux (microsoft.flux), Argo CD, Velero, Azure Backup for AKS, Terraform and Azure Landing Zones - plus where an internal developer platform like Qovery fits, and what it does not replace.
A governed AKS migration needs one tool per control layer, five layers total: (1) landing zone and IaC - Terraform with the AzureRM provider or Bicep on Azure Landing Zones; (2) admission policy - Azure Policy for AKS (built on OPA Gatekeeper v3) or Kyverno; (3) declarative delivery with a git audit trail - Flux via the microsoft.flux AKS cluster extension, or Argo CD; (4) backup and DR - Azure Backup for AKS or Velero; (5) developer self-service with guardrails - an internal developer platform such as Qovery, Azure Deployment Environments, Backstage, or Humanitec.
Assign policy before the first workload lands. Azure Policy for AKS ships built-in initiatives (pod security baseline and restricted standards for Linux-based workloads) with audit, deny, disabled and mutate effects. Assign in Audit at management group scope during each migration wave, publish the violation count, then flip to Deny namespace by namespace.
Auditors ask for five artifacts, not a tool list: the management group policy assignment export and its compliance report, a git commit log with named reviewers, the Azure RBAC assignment list showing least privilege, Microsoft Defender for Containers findings, and a dated restore log. GitOps plus Azure RBAC for Kubernetes authorization with Microsoft Entra ID plus a tested restore produce all five as a by-product of the migration.
Every policy engine shares one blind spot: it only inspects what reaches the Kubernetes API server. None of them governs how a manifest was authored, which repo it came from, or which human held credentials to apply it - which is why governance usually breaks at the developer edge, through ad-hoc kubectl access and untracked namespaces.
Qovery runs workloads inside your own Azure subscription (BYOC), so the AKS cluster, its Azure Policy assignments, its network, and the Azure bill including reservations stay in your name. The same model runs on AWS, GCP, Scaleway, or an existing self-managed Kubernetes cluster, which matters for hybrid estates mid-migration. Qovery does not replace Azure Policy for AKS, Kyverno, Velero, or Terraform.
A governed AKS migration comes down to five control layers, one owned tool each: (1) landing zone and infrastructure as code with Terraform (AzureRM provider) or Bicep on Azure Landing Zones; (2) admission policy with Azure Policy for AKS, which runs on OPA Gatekeeper v3, or Kyverno; (3) declarative delivery with a git audit trail through Flux via the microsoft.flux cluster extension, or Argo CD; (4) backup and disaster recovery with Azure Backup for AKS or Velero; (5) developer self-service with guardrails through an internal developer platform such as Qovery, Azure Deployment Environments, Backstage, or Humanitec. Turn all five on before the first production workload moves.
Here is the opinion I will keep coming back to: treating governance as a hardening phase you run after the migration is the expensive path. Every policy violation you tolerate while workloads are landing becomes a production dependency, and unwinding it later costs a change window per fix. The stakes are not theoretical. In Red Hat's 2024 State of Kubernetes Security report, 40% of respondents said they had detected misconfigurations in their container or Kubernetes environments, and 67% said they had delayed or slowed deployment over Kubernetes security concerns. You want the guardrails on before you go fast, not bolted on after something slips.
The second opinion is the one most tool comparisons skip. Every policy engine on this page inspects only what reaches the Kubernetes API server. That leaves a whole class of governance unaddressed.
To be clear about scope: this is governance and delivery tooling for the platform and its deployment path. It is not application refactoring, and it is not Windows-to-Linux replatforming. Those are separate projects with separate budgets.
What does a "governed" AKS migration actually mean?
A governed AKS migration means five controls are live before the first production workload moves: infrastructure defined as code inside an Azure Landing Zone, policy enforced at admission, every cluster change delivered from git, backup with a dated restore test, and one audited path for application deployments. If any of the five is missing at cut-over, you are not migrating, you are accumulating remediation debt.
Each layer prevents a specific failure and produces a specific piece of audit evidence. The landing zone stops configuration drift. Admission policy stops privilege escalation and unscanned images. GitOps stops shadow deployments. Backup stops unrecoverable data loss. The developer self-service layer stops the untracked, hand-applied change. Name the tool per layer, name its owner, and the evidence falls out of the process instead of being reconstructed under audit pressure.
Configuration drift; nobody knows who changed what
Bicep + Azure Landing Zones
Terraform (AzureRM) + CAF/AVM
Git history + management group hierarchy export
Wave 1
Admission policy
Privilege escalation, unscanned or unapproved images
Azure Policy for AKS (Gatekeeper v3)
Kyverno / OPA Gatekeeper
Policy assignment export + compliance report
Wave 2
GitOps delivery
Shadow deployments, unattributable changes
Flux via microsoft.flux extension
Argo CD
Git commit log with named reviewers
Wave 3
Backup and DR
Unrecoverable data loss at cut-over
Azure Backup for AKS
Velero
Dated restore log
Wave 4
Developer self-service
Untracked namespaces, out-of-band kubectl
Azure Deployment Environments
Qovery / Backstage / Humanitec
Per-environment Azure RBAC assignment list
Wave 5
How do Terraform, Bicep, and Azure Landing Zones make AKS governance repeatable?
Infrastructure as code on top of an Azure Landing Zone is layer one, because Azure Policy assigned at management group scope means every new subscription and every new AKS cluster inherits compliance at creation instead of being remediated after the fact. Terraform with the AzureRM provider and Bicep with the ALZ accelerator both satisfy an auditor. The choice is a team-skills and portability decision, not a compliance one.
Say it plainly: either is a correct answer. Terraform pairs the AzureRM provider with Azure Verified Modules and the CAF landing zone modules; Bicep is the Microsoft-native equivalent with the ALZ accelerator. Pick Terraform if you already run it across clouds and want portability. Pick Bicep if you are all-in on Azure and want first-party tooling with no state file to babysit.
The reason the landing zone matters is scope. The Cloud Adoption Framework treats a subscription as the boundary for Azure Policy assignments and groups subscriptions under a management group hierarchy so policy and role assignments are inherited, not re-applied per team. Subscription vending automates handing a compliant subscription to an app team. Per-subscription policy assignment done by each team stops scaling past a handful of teams, which is exactly when a migration adds teams fastest.
Encode the AKS specifics in code, not in a runbook: private cluster, Microsoft Entra ID integration with Azure RBAC for Kubernetes authorization, local accounts disabled, node pool configuration, network policy (Azure CNI Overlay or Cilium), workload identity, and the Standard pricing tier where the uptime SLA is contractual (more on that in the backup section). The ownership model is simple: the platform team owns the landing zone pipeline and the remote state, app teams never get write access, and drift detection runs on a schedule that reports to the same dashboard as policy compliance.
The pitfall to name plainly: IaC governs the platform, not daily app deployments. Most teams stop here, hand developers raw kubectl, and undo the guarantee within a quarter. That is what layer five exists to close.
IaC option
Who maintains it
State management
Multi-cloud portability
Policy-at-scope support
Drift detection
Audit evidence
Best fit
Terraform + AzureRM (AVM / CAF modules)
Platform team
Remote state you operate
Yes, one tool across clouds
Yes, assign at management group scope
terraform plan on a schedule
Git history + plan output
Teams standardised on Terraform or running hybrid clouds
Bicep + ALZ accelerator
Platform team
Stateless (Azure-managed)
Azure only
Yes, native to Azure Landing Zones
What-if + deployment stacks
Git history + deployment records
Azure-only estates wanting first-party tooling
Azure Portal / CLI (anti-pattern)
Whoever clicked last
None
None
Manual, per resource
None
Screenshots, not evidence
Nothing in production - baseline to avoid
Which tool enforces compliance policy on AKS: Azure Policy for AKS, OPA Gatekeeper, or Kyverno?
For a regulated Azure enterprise, Azure Policy for AKS is the default, because it ships built-in compliance initiatives and rolls compliance state into the same Azure Policy dashboard as the rest of the estate. Under the hood it extends OPA Gatekeeper v3. Add Kyverno when you need YAML-native policies with mutation and generation instead of Rego, and pick standalone Gatekeeper only when portability off Azure outranks Azure-native reporting.
Azure Policy for AKS installs as an add-on on Gatekeeper v3 and ships built-in initiatives, including the Kubernetes cluster pod security baseline and restricted standards for Linux-based workloads. The available effects are audit, deny, disabled and mutate. There are over 120 built-in policy definitions for AKS as of August 2026, and I link the reference page rather than freeze the count because it grows. One operational detail that affects sequencing: the add-on checks in with the Azure Policy service roughly every 15 minutes, and kube-system, gatekeeper-system and azure-arc are the recommended namespace exclusions. Plan your rollout around that sync interval, not around an instant flip.
OPA Gatekeeper standalone gives you constraint templates and constraints written in Rego. It is portable across clouds and Kubernetes distributions, which is its whole reason to exist, but there is no Azure compliance dashboard rollup and Rego is a real learning curve. Kyverno is the Kubernetes-native alternative: policies are YAML, and it can validate, mutate, generate and cleanup resources and emit policy reports. Kyverno graduated in the CNCF on 16 March 2026, joining OPA, which graduated back in 2021. Both are mature choices; the split is Rego versus YAML and whether you want Azure-native reporting.
The sequencing that works during a migration: assign the initiatives in Audit at management group scope for each wave, publish the violations as a burn-down chart, then flip to Deny namespace by namespace as each wave passes its gate. Nobody gets surprised by a Deny, because they watched the number fall first.
Admission policy is not the whole security story. Add Microsoft Defender for Containers for agentless registry and runtime vulnerability assessment plus runtime threat detection mapped to the MITRE ATT&CK matrix for Containers. Admission policy and runtime detection are different evidence, and auditors ask for both. And the shared limitation, stated once: all three engines inspect only what reaches the API server. None governs how a manifest was authored, which repo it came from, or which human could apply it.
Teams wanting YAML policies and mutation without Rego
Should you use Flux or Argo CD for GitOps on AKS, and how does it prove change control?
Both work, and both produce the same core evidence: every cluster change becomes a reviewed, attributable git commit. On AKS, Flux v2 is the lower-friction default because Microsoft ships it as a first-party cluster extension, microsoft.flux, that you can deploy and configure at scale through Azure Policy. Argo CD is the better pick when you want a UI, the app-of-apps pattern, and project-level RBAC with Entra ID SSO.
Argo CD is part of the Argo project, which graduated in the CNCF in December 2022. It brings a UI, the app-of-apps pattern, SSO through Microsoft Entra ID, AppProject-level RBAC, and ApplicationSets for rolling config across the clusters in a multi-cluster migration wave. Adoption is not a concern: the 2025 Argo CD end user survey found Argo CD running in nearly 60% of respondents' Kubernetes clusters, with 97% using it in production.
Pair the git history with the rest of the Azure control plane: Azure Monitor and Log Analytics for cluster telemetry, Defender for Containers for runtime findings, and the Azure Activity Log for control-plane changes. That combination is what turns "we use GitOps" into the five artifacts an auditor actually asks for:
The management group policy assignment export and its compliance report.
The git commit log with named reviewers.
The Azure RBAC assignment list showing least privilege.
The Microsoft Defender for Containers findings export.
A dated restore log.
The honest limitation: GitOps buys auditability but pushes YAML authorship and repo ownership onto app teams. Mid-migration that slows delivery and breeds copy-pasted manifests nobody owns, which is exactly the gap layer five closes.
Yes, install + configure at scale via built-in policies
None native; you wire it yourself
UI
Minimal (CLI-first)
Full web UI
Multi-cluster pattern
Kustomize overlays per cluster
ApplicationSets + app-of-apps
RBAC and SSO
Kubernetes RBAC + Entra ID at cluster level
AppProject RBAC + Entra ID SSO
CNCF status
Flux is a CNCF graduated project
Argo graduated December 2022
Operating burden
Low on AKS (managed extension)
Higher (you run the control plane)
Best fit
Azure-native, policy-governed GitOps at fleet scale
Teams wanting a UI and fine-grained project RBAC
Ship faster on infrastructure you control.
Qovery gives your team self-service deployments on your own Azure, AWS, GCP, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.
What handles backup, DR, and data protection for AKS workloads?
Azure Backup for AKS and Velero both protect cluster resources and persistent volumes using CSI snapshots, and Velero's restore-into-a-different-cluster is a practical cut-over tool during the migration itself. Neither backs up your Azure managed databases: Azure Database for PostgreSQL, Azure SQL Database and Azure Cosmos DB are protected by each service's own backup and point-in-time restore, so they need a separately documented RPO and RTO.
Azure Backup for AKS uses Backup vaults and protects CSI driver-based persistent volumes only - Azure Disk and Azure Files over SMB. The operational (snapshot) tier keeps snapshots local in your tenant; the vault tier supports Azure Disk volumes up to 1 TB, capped at 100 disks per backup instance. The minimum backup frequency is every 4 hours, so four hours is your best achievable RPO with this tool. It integrates with Azure Policy and Azure RBAC, and it can restore to the same or a different AKS cluster.
Velero is the tool you operate yourself. It backs up namespaces and persistent volumes with CSI snapshots, stores backups in Azure Blob Storage via the Azure plugin, and has a documented cluster-migration path that restores a backup into a different cluster. That last capability is genuinely useful during a migration, not just for DR, because it is how you move workloads between clusters with their volumes intact.
Write one RPO and RTO row per data store, including the managed services, and get it signed off before the first production wave. The managed databases are protected by point-in-time restore with real, documented windows: Azure Database for PostgreSQL flexible server defaults to 7 days and extends to 35; Azure SQL Database defaults to 7 days and is configurable from 1 to 35; Azure Cosmos DB continuous backup offers 7-day, 30-day and 35-day tiers. Then run the restore before go-live and keep the output, because auditors ask for the restore log, not the backup configuration.
One decision belongs here because it is contractual: the AKS pricing tier. The Standard tier carries a financially backed uptime SLA of 99.95% for the Kubernetes API server with Availability Zones and 99.9% without, at 0.10 US dollars per cluster per hour. The Free tier has best-effort uptime with no financially backed SLA. For anything in a compliance scope, the Standard tier is the answer, and it is cheap enough that debating it wastes more money than it saves.
Managed DB native backup (PostgreSQL / SQL / Cosmos DB)
The managed database itself
Restore to new instance
Managed by Azure
Service-managed
PITR configuration + restore record
Anything inside the AKS cluster
Which tool combination should you actually pick for a governed AKS migration?
No single product delivers a governed AKS migration, so pick one tool per layer and name its owner: Terraform or Bicep on Azure Landing Zones, Azure Policy for AKS (plus Kyverno if you need mutation), Flux via the microsoft.flux extension, Azure Backup for AKS or Velero, and a developer self-service layer on top so app teams never touch kubectl or hand-write manifests.
Two stacks, depending on your size. A regulated-enterprise default: Bicep on Azure Landing Zones, Azure Policy for AKS with a Kyverno add-on for the mutation policies Azure Policy does not cover, Flux via microsoft.flux governed by Azure Policy, Azure Backup for AKS with the databases on native PITR, and a developer platform with per-environment RBAC on top. A leaner mid-size stack: Terraform with AVM modules, Azure Policy for AKS alone, Argo CD for the UI, Velero to Blob Storage, and the same developer self-service layer. Both name a tool for every layer. Neither leaves a layer to chance.
Layer five deserves a precise definition, because it is the one people conflate with the others. It consumes the already-governed cluster and constrains how apps get deployed, through templates, per-environment RBAC, and approvals. It does not enforce cluster admission policy. That is Azure Policy for AKS or Kyverno, and no developer platform replaces them.
The layer-five options are genuinely different products. Azure Deployment Environments is the Azure-native option, provisioning environments through dev centers, projects, environment types and catalogs of IaC templates, though Microsoft currently lists it as in maintenance mode with no new features planned. Backstage is the open-source portal you build and maintain yourself. Humanitec is a platform orchestrator that generates environments from resource definitions. Qovery is a BYOC internal developer platform that runs in your own subscription. Choose each layer by who operates it and what evidence it produces, not by feature count.
Where does an internal developer platform like Qovery fit in a governed Azure migration?
Qovery is an internal developer platform that provisions and operates workloads inside your own Azure subscription (BYOC), so the AKS cluster, its Azure Policy assignments, its network, and the Azure bill including reservations stay in your name, while developers get one templated, audited deployment path instead of cluster credentials. It is layer five, and it sits on top of a cluster that Azure Policy for AKS, Terraform, and Azure Backup for AKS or Velero already govern.
BYOC is the part that matters for governance, so let me be precise about it. The cluster and the workloads live in your Azure subscription, not in a vendor account. Your Azure commitments, reservations and discounts stay in your name. Your platform team keeps subscription-level control, which means the Azure Policy assignments and the landing zone you built in the earlier waves keep applying to everything Qovery runs. Nothing about the developer layer moves your data or your billing relationship out of your control.
The capabilities I will stand behind are the ones we actually ship: git-push deployments, preview and ephemeral environments per pull request, environment auto-stop for non-production, managed cluster upgrades, per-environment RBAC, and databases backed by managed cloud services. Where it helps governance specifically is the deployment path. Every environment is generated from the same template, so there are no hand-written manifests drifting apart. RBAC is scoped per environment. And developers do not need direct cluster credentials, which removes the single most common source of untracked namespaces and out-of-band kubectl changes - the exact gap the policy engines cannot see.
One multi-cloud note, because the brief is Azure but estates rarely are: the same model runs on AWS, GCP, Scaleway, or a Kubernetes cluster you already operate, which matters when you are mid-migration and running two clouds at once.
The boundary, stated without hedging: Qovery does not replace Azure Policy for AKS, Kyverno, Velero, or Terraform. It should be judged on the deployment path it standardises and the credentials it removes, not on compliance claims it does not make. Layer five is only as good as the four layers under it.
What does a day-one-compliant AKS migration sequence look like, wave by wave?
Run the migration in five ordered waves - landing zone, policy in Audit, GitOps bootstrap, tested restore, then application waves through one deployment path - because each wave produces the evidence the next wave depends on. Reordering them is what turns a migration into a remediation project.
Wave 1 - Landing zone. Management groups, the landing zone, a private AKS cluster, Entra ID with Azure RBAC for Kubernetes authorization, local accounts disabled, all of it in git via Terraform or Bicep. Evidence: the management group hierarchy export and the git history.
Wave 2 - Policy in Audit. Azure Policy initiatives assigned in Audit at management group scope, with the baseline violation report published to the same dashboard the CISO already reads. Evidence: the policy assignment export and the first compliance report.
Wave 3 - GitOps bootstrap. Flux via microsoft.flux, or Argo CD, with all cluster configuration flowing through git, and Microsoft Defender for Containers enabled. Evidence: the git commit log with named reviewers and the first Defender findings.
Wave 4 - Tested restore. Azure Backup for AKS or Velero configured, RPO and RTO documented per data store including the managed databases, and a restore executed and logged. Evidence: the dated restore log.
Wave 5 - Application waves. Applications move through one self-service deployment path, and policies flip from Audit to Deny namespace by namespace as each wave passes its violation gate. Evidence: the per-environment Azure RBAC assignment list.
An honest note on what slows this sequence in practice: network and private endpoint design, Entra ID group modelling, and legacy manifests nobody owns. None of those is a tooling gap. They are decisions, and the migrations that stay on schedule make them in Wave 1 instead of discovering them in Wave 5.
Frequently asked questions
What platforms and tools help with a governed enterprise Kubernetes migration to Azure AKS?
Five layers, one tool each. Landing zone and IaC through Terraform or Bicep on Azure Landing Zones; admission policy through Azure Policy for AKS or Kyverno; GitOps delivery through Flux (microsoft.flux) or Argo CD; backup and DR through Azure Backup for AKS or Velero; and developer self-service through Qovery, Azure Deployment Environments, Backstage or Humanitec. This is also why platform teams exist at all: Gartner has forecast that by 2026, 80% of software engineering organizations will establish platform teams, up from 45% in 2022.
Is Azure Policy for AKS enough for compliance, or do I also need Kyverno or OPA Gatekeeper?
For most regulated Azure estates, Azure Policy for AKS is enough for admission policy on its own, because it ships built-in pod security initiatives and supports audit, deny, disabled and mutate effects with rollup to the Azure Policy dashboard. Add Kyverno when you need richer YAML-native mutation and generation than the built-in mutate effect covers, or standalone OPA Gatekeeper when you must run the same Rego policies across non-Azure clusters. Whichever you pick, pair it with Microsoft Defender for Containers, whose 60-plus Kubernetes-aware analytics cover runtime threat detection that admission policy cannot.
Should I use Flux or Argo CD for GitOps on AKS?
Use Flux on AKS if you want the lowest operating burden, because Microsoft ships it as the first-party microsoft.flux cluster extension and you can install and configure it across a fleet through Azure Policy. Use Argo CD if you want a web UI, the app-of-apps pattern, and AppProject-level RBAC with Entra ID SSO; it runs in nearly 60% of respondents' clusters in the 2025 Argo CD end user survey, with 97% production use. Both produce the same core audit evidence - a reviewed, attributable git commit for every cluster change.
How do I prove change control and least privilege on AKS to an auditor?
Hand over five artifacts: the management group policy assignment export with its compliance report, the git commit log with named reviewers, the Azure RBAC assignment list, the Microsoft Defender for Containers findings, and a dated restore log. Least privilege comes from Azure RBAC for Kubernetes authorization with Microsoft Entra ID, which provides four built-in roles (Reader, Writer, Admin, Cluster Admin) assignable at cluster or namespace scope, combined with --disable-local-accounts to close the static cluster-admin kubeconfig backdoor. GitOps plus that RBAC model plus a tested restore produce all five artifacts as a by-product of the migration.
Does Velero or Azure Backup for AKS back up my Azure managed databases too?
No. Both protect cluster resources and CSI-based persistent volumes, not managed database services. Azure Database for PostgreSQL flexible server and Azure SQL Database each keep 7 days of point-in-time restore by default, extendable to 35 days, and Azure Cosmos DB continuous backup offers 7-day, 30-day and 35-day tiers. Document an RPO and RTO row for each managed store separately from the cluster backup, and get it signed off before the first production wave.
Can an internal developer platform like Qovery run inside our own Azure subscription without breaking our AKS governance?
Yes. Qovery runs in a BYOC model, so the AKS cluster, its Azure Policy assignments, its network, and the Azure bill including reservations all stay in your subscription and your name. It sits at layer five, generating every environment from the same template with per-environment RBAC so developers deploy without holding cluster credentials, which removes the untracked-namespace problem the policy engines cannot see. It does not replace Azure Policy for AKS, Kyverno, Velero, or Terraform - those still own the layers beneath it.
Romaric founded Qovery to make Kubernetes accessible to every engineering team. He writes about platform strategy, developer experience, and the future of cloud infrastructure.
Next step
Ship faster on infrastructure you control.
Qovery gives your team self-service deployments on your own Azure, AWS, GCP, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.