Webinar · Oct 20: The migration takes 2 weeks. Deciding to do it takes 6 months.

EKS to AKS: How to Migrate Kubernetes Workloads When You Move to Azure for Better Enterprise Pricing

A step-by-step runbook for migrating Kubernetes workloads from Amazon EKS to Azure AKS: what actually breaks (IRSA, load balancer annotations, EBS storage classes, ECR, DNS, egress), how to validate the Azure enterprise discount before you move, and how to run both clouds in parallel during cutover.

Mélanie Dallé
Senior Marketing Manager
OCT 19, 2026 · 8 MIN
EKS to AKS: How to Migrate Kubernetes Workloads When You Move to Azure for Better Enterprise Pricing

Key Points:

  • An EKS to AKS move is a platform migration, not a Kubernetes migration. Deployments, Services, ConfigMaps and Helm charts move unchanged. IAM Roles for Service Accounts, EBS/EFS storage classes, AWS Load Balancer Controller annotations, Route 53 records, ECR pull credentials and Secrets Manager wiring all have to be rebuilt against Azure equivalents. Budget roughly 80% of the effort for that glue layer.
  • The only structural cost difference between the two managed services is the control plane. EKS charges about $0.10 per cluster-hour, roughly $73/month per cluster. The AKS Free tier charges nothing for the control plane but carries no financially backed SLA. Nodes, disks, load balancers and egress are priced per resource on both clouds, so a single 200-node cluster sees almost no structural saving.
  • Enterprise Azure savings come from commitments and licensing, not from AKS. An Enterprise Agreement or Microsoft Customer Agreement, Azure Reserved VM Instances, the Azure savings plan for compute, and Azure Hybrid Benefit for Windows Server and SQL Server are where the discount lives. Validate that quote against your remaining AWS Savings Plans first, because stranded commitments routinely erase year-one savings.
  • The lowest-risk sequence is eight steps: inventory and dependency map, Azure landing zone, replatform manifests, move images, replicate data, parallel run behind weighted DNS, traffic shift, then decommission EKS after 2 to 4 weeks warm.
  • Stateful workloads set the timeline. Stateless services cut over in hours. Databases need logical replication or a dual-write window plus a tested rollback. Plan 6 to 14 weeks end to end for a mid-size estate, and expect the dual-infrastructure overlap to cost more than the engineering time.
  • Qovery provisions and operates AKS inside your own Azure subscription (and EKS in your AWS account, GKE in GCP, Scaleway, or your existing Kubernetes cluster), so one application definition runs on both clouds during the cutover and the Azure invoice plus your commitment discount stay in your name. Qovery does not migrate your data or convert RDS to Azure Database for you.

Qovery · Agentic Infrastructure Platform
Kubernetes, operated through one governed API
Learn more

The Kubernetes part of an EKS to AKS migration is the easy part. Your Deployments, Services and Helm charts move almost untouched. What eats the quarter is everything around them: IRSA, load balancer annotations, EBS storage classes, the image registry, and the CI pipeline that has to learn a second cloud.

I have spent years operating Kubernetes clusters across AWS, GCP, Azure and Scaleway at Qovery, and I have talked to more than 200 CTOs about why they move. The pattern for an Azure move is almost always the same. Finance or procurement negotiates an Azure Enterprise Agreement that beats current AWS spend, and then the platform team gets handed the job of moving production without breaking it. This is the runbook for that job. It is written for 2026 pricing, and every price here was last checked in October 2026.

Is AKS actually cheaper than EKS, or does the saving come from your Azure enterprise agreement?

AKS is not intrinsically cheaper than EKS. The only structural difference between the two managed services is the control plane: EKS bills about $0.10 per cluster-hour (roughly $73/month) under standard support, while the AKS Free tier bills nothing for the control plane and carries no financially backed SLA. Every meaningful enterprise saving comes from commitments, licensing and a negotiated EA or MCA, not from the Kubernetes service itself.

Do the arithmetic out loud and the point lands. The control plane delta is a fixed fee per cluster. For a fleet of 40 small clusters that is roughly $2,900 a month of pure control plane that AKS Free can zero out. For one 200-node cluster, $73 a month is a rounding error against the node bill. On AWS, running an old Kubernetes version past standard support adds an extended support surcharge of about $0.50 per cluster-hour (so $0.60/hour total), which is a real reason to keep clusters current on either cloud.

Nodes are the bill on both clouds, and they are priced per resource either way. Compare equivalent families (AWS m7i/c7i against Azure Dsv5/Fsv2) at your real node shapes and your real region, using the EC2 on-demand pricing and the Azure Linux VM pricing pages, not the list price of a single VM in us-east-1. The enterprise discount is applied on top of those node prices through commitments.

Here is where the Azure savings actually come from, and it is worth naming each instrument so your finance team models the right one:

Line itemAmazon EKSAzure AKSNotes
Control plane fee~$0.10 per cluster-hour (~$73/mo)Free tier: $0. Standard tier: per-cluster-hour feeOnly structural control-plane difference between the two
Uptime SLA99.95% with EKSFree: best-effort, no SLA. Standard/Premium: 99.95% with availability zones, 99.9% withoutAKS Free trades the SLA for a $0 control plane
Old-version surchargeExtended support ~$0.50/cluster-hour extraPremium tier for 24-month Long Term SupportBoth penalize running behind on versions
Node pricingPer-instance, on-demand or committedPer-VM, on-demand or committedThe dominant line item on both clouds
Commitment instrumentsCompute Savings Plans, up to 66% offReserved VM Instances, up to 72% off; savings plan for compute, up to 65% offThis is where the EA/MCA discount lives
Windows/SQL licensingLicense-included or BYOLAzure Hybrid Benefit reuses existing licensesLarge swing if you run Windows Server or SQL Server
Data egressPer-GB, free when leaving AWS on requestPer-GB bandwidth pricingOne-time migration cost, not steady-state
Support planBusiness/Enterprise, % of spendStandard/Professional DirectBoth priced as a percentage of spend

Two things routinely wipe out year-one savings. The first is stranded AWS commitments: unused Savings Plans and Reserved Instances keep billing until term end regardless of usage, so if you move off AWS while a one-year Savings Plan still has eight months to run, you pay for both clouds. Model that overlap explicitly. The second is the dual-run period itself, which I cover at the end.

The one-time migration cost is smaller than people fear. AWS waives data transfer out charges when you are leaving AWS, on request to AWS Support, with 180 days to complete the move for non-EU customers and the EU Data Act addendum for EU customers. So the decision rule is simple: get a priced Azure quote for your actual estate (node shapes, disks, egress, managed databases), plus a TCO model that includes the dual-run overlap, before a single manifest is edited.

What actually breaks when you move a Kubernetes workload from EKS to AKS?

Your Kubernetes objects are portable. The cloud integration layer is not. Eight things break in practice: pod identity (IRSA), ingress annotations, the CNI and pod IP plan, storage classes, ReadWriteMany volumes, the image registry and pull secrets, the secrets driver, and every AWS SDK call in your application code.

Pod identity is the one that surprises teams. IAM Roles for Service Accounts (IRSA) becomes Microsoft Entra Workload ID, which is a federated credential on a user-assigned managed identity plus the azure.workload.identity/use: "true" label on the pod. The old AAD Pod Identity project was deprecated in October 2022 and archived in September 2023, with the managed add-on supported only through September 2025, so do not build anything new on it.

The silent blocker is application code. Every SDK call to S3, SQS, DynamoDB, Kinesis or STS keeps pointing at AWS after the pods move to Azure. Grep the codebase for those calls before you plan anything else, because they decide whether you can cut a service over cleanly or whether it has to keep talking back to AWS over a VPN during the overlap.

AWS componentAzure equivalentWhat changes in manifests or codeOwnerDifficulty
IRSA (pod identity)Microsoft Entra Workload IDFederated credential on a managed identity; add azure.workload.identity/use label; annotate the service accountPlatformHigh
AWS Load Balancer ControllerAzure Load Balancer, Application Gateway for Containers, or ingress-nginxRewrite every service.beta.kubernetes.io/aws-* annotationPlatformMedium
VPC CNI (one VPC IP per pod)Azure CNI OverlayNew max-pods-per-node and subnet sizing planPlatformMedium
gp3 EBS CSIAzure Disk CSI (Premium SSD v2)New IOPS/throughput provisioning model in the StorageClassPlatformMedium
EFS (ReadWriteMany)Azure Files CSI or Azure NetApp FilesSwap RWX backend; check NFS vs SMBPlatformMedium
ECRACR via az acr importNew pull secrets or managed identity attachPlatformLow
Secrets Manager / SSMAzure Key Vault + Secrets Store CSI driverRepoint External Secrets or CSI SecretProviderClassPlatformMedium
CloudWatch Container InsightsAzure Monitor managed Prometheus, or keep Prometheus/Grafana/OTelRepoint exporters, or stay cloud-neutralApp + PlatformLow to Medium
Cluster Autoscaler / KarpenterAKS cluster autoscaler + Node Autoprovisioning; KEDA managed add-onNew autoscaler config and node poolsPlatformMedium
AWS SDK calls (S3, SQS, DynamoDB, Kinesis, STS)Blob, Service Bus, Cosmos DB, Event Hubs, EntraRewrite SDK calls or keep calling AWS over VPNAppHigh

A note on the parts you can choose not to port. If you already run Prometheus, Grafana and OpenTelemetry instead of CloudWatch, your observability layer moves with the manifests and you never pay this tax again. The same logic applies to ingress: a cloud-neutral ingress-nginx is less work over two migrations than rewriting ALB annotations once and Application Gateway annotations later.

What are the steps to migrate from EKS to AKS, in order?

The safe order is eight steps: inventory, Azure landing zone, replatform manifests, move images, replicate data, parallel run, traffic shift, decommission. Reordering it, especially moving data before the landing zone is proven, is the single most common reason a six-week project becomes a quarter.

The discipline that makes this work is a validation gate after every step. You do not start the next step until a named, measurable thing is green. That is what keeps a migration from turning into a big-bang cutover with no way back.

StepWhat you doToolingValidation gateDurationRollback if the gate fails
1. InventoryMap namespaces, CRDs, PVCs, secrets, cron jobs, and every AWS API call; record p95 latency, error rate and cost per servicekubectl, repo grep, cost explorerBaseline metrics captured and signed off1 to 2 weeksN/A (no changes yet)
2. Landing zoneSubscription, VNet and subnet sizing for your CNI mode, AKS with Workload ID and Azure RBAC, ACR, Key Vault, Log AnalyticsTerraform/Bicep, az CLIA smoke-test pod runs, pulls from ACR, reads a Key Vault secret1 to 2 weeksTear down and rebuild the zone
3. Replatform manifestsPush env-specific config into Helm values or Kustomize overlays; replace annotations, storage classes, service accountsHelm, KustomizeSame chart deploys clean on a scratch AKS namespace2 to 6 weeksRevert chart changes in Git
4. Move imagesaz acr import from ECR, or re-push from CI; add ACR to the pipelineaz acr, CIBoth registries hold the same tags for every serviceDays, in parallelKeep pulling from ECR
5. DataLogical replication to Azure Database, Azure DMS online mode, AzCopy for S3 to Blob, Velero for PVsDMS, AzCopy, VeleroRow counts and checksums match source1 to 4 weeksStop replication; AWS stays source of truth
6. Parallel runBoth clusters live; weighted split via Route 53, Traffic Manager or Front Door; compare against the step 1 baselineWeighted DNSError rate and p95 on AKS within baseline tolerance2 to 4 weeksShift weight back to EKS
7. CutoverDrop DNS TTL to 60s days ahead; define the numeric rollback trigger; shift 100%Weighted DNSError budget intact for an agreed windowHoursFlip weight back (EKS still warm)
8. DecommissionDelete node groups, reconcile remaining AWS commitments, confirm the Azure invoice matches the quoteeksctl, billingEKS deleted, invoice reconciledDays, after 2 to 4 weeks warmN/A

Step 1 is the one teams rush and regret. The baseline you capture here (p95 latency, error rate, cost per service) is the only objective way to answer "is the AKS version actually as good?" during the parallel run. Without it, the go/no-go decision becomes a vibe.

How do you migrate stateful workloads and databases from AWS to Azure without downtime?

Stateless services cut over in hours. Stateful ones set the whole timeline. Only two patterns reliably avoid downtime: logical replication with a replica promotion, or a dual-write window. Both require a tested rollback plus a verified row-count or checksum comparison before you touch DNS.

Be honest about the hard case up front. There is no zero-downtime path for a ReadWriteOnce volume with a single writer. EBS snapshots cannot restore natively to Azure Disks, so a cross-cloud volume move goes through Velero File System Backup (Kopia or restic), which means a restore window and downtime. Budget a maintenance window for those volumes and tell stakeholders early, in week one, not the night before.

Workload typeRecommended toolExpected downtimeRollback difficultyMain gotcha
RWO persistent volumeVelero File System Backup (Kopia/restic)Minutes to hours (restore window)MediumSingle writer means no live sync; snapshots are provider-specific
RWX persistent volumeAzure Files CSI or Azure NetApp FilesMinutesMediumMatch the access mode and performance tier to EFS
PostgreSQLLogical replication or Azure DMS onlineSeconds (write freeze at promotion)Low to MediumSequences, extensions and large objects need checking
MySQLBinlog replication or Azure DMS onlineSeconds (write freeze)Low to MediumVerify binlog format and GTID consistency
MongoDB / DocumentDBAzure Cosmos DB for MongoDBShort cutover windowMediumAPI and index compatibility is not 1:1
DynamoDBAzure Cosmos DB for NoSQLDual-write or export/importHighPartition-key and consistency-model redesign, not a config change
S3 objectsAzCopy or Azure Data FactoryNone with dual-readLowKeep a dual-read window so the app tolerates either backend

For relational databases the clean pattern is native logical replication (PostgreSQL) or binlog replication (MySQL), or Azure Database Migration Service in online mode, which supports RDS and Aurora as sources. You replicate continuously, then promote the Azure replica during a short write freeze. NoSQL is harder and I will not pretend otherwise: moving DynamoDB to Cosmos DB for NoSQL means rethinking partition keys and the consistency model, which is real engineering work.

During the overlap, workloads on AKS often still need to reach data that is still on AWS. That means a Site-to-Site VPN or ExpressRoute plus Direct Connect, and it means a round-trip latency tax on every cross-cloud query. Factor that into the parallel-run metrics so you do not mistake network latency for an application regression.

Your cutover checklist for each stateful service is the same every time: freeze writes, drain queues and in-flight jobs, verify row counts and checksums, flip the weighted DNS record, then watch the error budget for 60 minutes with the rollback trigger agreed in advance.

Ship faster on infrastructure you control.
Qovery gives your team self-service deployments on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.

Should you lift-and-shift, build your own platform layer, or use a platform that already runs on both clouds?

There are three realistic options. Lift-and-shift with hand-rolled Terraform or Bicep is fastest to a running AKS cluster but leaves you maintaining two sets of cloud-specific glue forever. Building your own abstraction with Crossplane or Backstage is clean but means funding a platform team to run it. Adopting a platform that already provisions both EKS and AKS in your own accounts is the shortest path to a genuine side-by-side parallel run.

The reason this choice matters for a migration specifically is the parallel run. Steps 6 and 7 above require both clusters live from the same application definition. If your CI/CD only knows how to deploy to EKS, you are rebuilding the pipeline for AKS before you can even start comparing the two, and you are maintaining both pipelines for the length of the overlap.

ApproachTime to first workload on AKSOngoing ops burdenParallel-run supportWho owns the cloud billLock-in riskSuits
Lift-and-shift IaC (Terraform/Bicep)Days to weeksHigh (two sets of glue, forever)Manual, you wire itYou, directlyLow to cloud, high to your scriptsTeams with a strong platform team
Build your own (Crossplane, Backstage, OpenTofu modules)Weeks to monthsHigh (you run a platform product)You build itYou, directlyLowLarge orgs funding a platform team
IDP / multi-cluster control planeHours to daysLow to mediumBuilt inYou (runs in your account)Varies by vendorTeams without a dedicated platform team

The Microsoft-native route for the third option is Azure Arc plus AKS Fleet Manager, which is a reasonable fit if you are standardizing everything on Azure and do not need the AWS side to stay first-class. The independent platforms in this space include Qovery, Northflank, Porter, Humanitec, Rafay and Spectro Cloud Palette, and they differ mainly in how much of the cloud account they run inside and how even their support is across clouds.

Here is where Qovery fits, and I will be specific because the migration case is where it earns its place. Qovery provisions and operates AKS inside your own Azure subscription, and it also runs EKS in your AWS account, GKE in GCP, Scaleway, or your existing Kubernetes cluster. Because the cluster lives in your subscription, the Azure commitment discount and the invoice stay in your name. One application definition drives git-push deployments, preview environments per pull request, environment auto-stop for non-production, managed cluster upgrades and per-environment RBAC, and all of that survives the move.

For the cutover that means you run the EKS and AKS environments side by side from the same definition instead of rebuilding the pipeline twice, then delete the AWS side once traffic has shifted. I want to be equally clear about the limits. Qovery does not migrate your data, does not convert RDS to Azure Database for you, and does not remove the work of mapping managed services or rewriting AWS SDK calls. Those stay on your plate regardless of which approach you pick.

How long does an EKS to AKS migration take and what does it really cost?

Plan 6 to 14 weeks for a mid-size estate: assessment 1 to 2 weeks, landing zone 1 to 2 weeks, replatforming 2 to 6 weeks, and a parallel run of 2 to 4 weeks per tranche. The dual-infrastructure overlap, not the engineering hours, is usually the largest line item on the invoice, because for the length of the parallel run you are paying two clouds for the same traffic.

ProfileServicesAssessmentLanding zoneReplatformParallel runTotalBiggest cost line
Small, statelessA handfulDaysDays to 1 week1 weekDays2 to 3 weeksEngineering time
Mid-size, 2 to 3 databasesDozens1 to 2 weeks1 to 2 weeks2 to 6 weeks2 to 4 weeks6 to 14 weeksDual-run compute and storage overlap
Regulated enterpriseMany, with data residency2 to 4 weeks2 to 4 weeksSeveral weeksWeeks per trancheOne to two quartersDual-run overlap plus stranded AWS commitments

The cost lines to budget are duplicate compute and storage during overlap, AWS egress (often free on exit, as noted above), engineering time, the Azure support plan, cross-cloud VPN or ExpressRoute, and any stranded AWS commitment running to term. On funding, ask your Microsoft account team about Azure Migrate and Modernize and partner-led migration credits, and get the amount in writing before you sign the EA. Migration funding that was verbally promised and never materialized is a classic way a "cheaper" move ends up flat.

The risk controls are boring and they work. Migrate the least critical namespace first. Keep one rollback-tested canary service through the whole project. Never migrate a database and shift traffic in the same change window. And budget time for the three things teams underestimate every single time: CI/CD rework, DNS and certificate management, and re-tuning autoscaling and resource requests for a different VM family, because a pod sized for an m7i node is not sized for a Dsv5 node.

How do I run the EKS to AKS move from Claude Code or Cursor?

You can drive the Azure side of the migration from the coding agent you already use. Install the Qovery Agent Skills once, and your agent can connect your Azure subscription, provision AKS and deploy workloads, asking you to approve every change before it runs.

Install globally for any compatible agent (Claude Code, Cursor, Codex, OpenCode, Gemini CLI):

BASH
curl -fsSL https://skill.qovery.com/install.sh | bash

Or scope it to a single project instead of installing globally:

BASH
curl -fsSL https://skill.qovery.com/install.sh | bash -s -- --project

Add the MCP Server to Claude Code, which uses OAuth and is read-only by default:

BASH
claude mcp add --transport http qovery https://mcp.qovery.com/mcp --callback-port 4242

Enable write access only when you want the agent to change things, which also requires turning on write access in the Qovery Console:

BASH
claude mcp add --transport http qovery "https://mcp.qovery.com/mcp?read_write=true" --callback-port 4242

Each skill owns a phase of the move. qovery-onboard connects the Azure subscription and creates the cluster, qovery-deploy ships the workload, qovery-terraform handles the IaC side, qovery-preview sets up per-PR environments, and qovery-troubleshoot and qovery-optimize cover the post-cutover phase. The MCP Server operates what already exists.

Then you ask in plain language, for example "deploy this service to my Azure subscription with Qovery and keep the AWS environment running," and the agent proposes each change and waits for your approval. The full walkthrough is in the AI agent quickstart and the Claude Code integration page.

Frequently asked questions
Is AKS cheaper than EKS?

Not on the Kubernetes service itself in general. The only structural difference is the control plane: EKS charges about $0.10 per cluster-hour (roughly $73/month), while the AKS Free tier charges nothing for the control plane but gives up the financially backed SLA. That delta matters for many small clusters and is noise for one large cluster. Real enterprise savings come from commitments and licensing (Reserved Instances, the savings plan for compute, Azure Hybrid Benefit) negotiated in your EA or MCA, not from AKS.

Can I use the same Helm charts and Kubernetes manifests on AKS that I used on EKS?

Mostly yes. Deployments, Services, ConfigMaps and plain Helm charts move unchanged. What you rewrite is the cloud-specific glue: AWS Load Balancer Controller annotations become Azure Load Balancer or Application Gateway for Containers settings, EBS storage classes become Azure Disk CSI classes, IRSA service-account wiring becomes Microsoft Entra Workload ID, and ECR references become ACR references. Push that env-specific config into Helm values or Kustomize overlays so one chart targets both clouds.

What replaces IAM Roles for Service Accounts (IRSA) on AKS?

Microsoft Entra Workload ID replaces IRSA. You create a federated credential on a user-assigned managed identity, annotate the Kubernetes service account with the identity's client ID, and add the azure.workload.identity/use: "true" label to the pod spec. The older AAD Pod Identity was deprecated in 2022 and its add-on supported only through September 2025, so do not use it for new clusters.

How do I migrate persistent volumes from EBS to Azure Disks?

Use Velero File System Backup (Kopia or restic) for the cross-cloud copy, because EBS snapshots are provider-specific and cannot be restored natively to Azure Disks. Expect a restore window and plan downtime for any ReadWriteOnce volume with a single writer, since there is no live cross-cloud sync for it. Target Azure Disk CSI with Premium SSD v2 and set the IOPS and throughput to match your old gp3 baseline.

Do I have to pay AWS egress fees to move my data to Azure?

Usually not for the migration itself. AWS waives data transfer out to the internet when you are leaving AWS, on request to AWS Support, with 180 days to complete the move for non-EU customers and the EU Data Act addendum covering EU customers. You still pay normal egress for ongoing cross-cloud traffic during the parallel run, so minimize how much AKS has to call back to AWS-hosted data.

Can I run EKS and AKS in parallel during the migration, and for how long?

Yes, and running two clusters in parallel is a mainstream pattern, not an exotic one. Keep EKS warm for 2 to 4 weeks after you shift traffic to AKS so you have a fast rollback path, then decommission it once the Azure metrics hold against your baseline. A platform that deploys the same application definition to both clouds, such as Qovery, makes the parallel run a weighting change rather than a second pipeline build.

Mélanie Dallé
About the author
Mélanie Dallé

Melanie leads content at Qovery. She covers platform engineering trends, Kubernetes operations, FinOps, and the tools that help engineering teams ship faster.

Next step

Ship faster on infrastructure you control.

Qovery gives your team self-service deployments on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.