Webinar replay: Heroku to AWS in one command, with an agent doing the work.

Outgrowing Your PaaS: The Kubernetes Migration Tools That Actually Plug Into Your CI/CD

A practical, answer-first guide to the Kubernetes migration tools that integrate with existing CI/CD pipelines and automate infrastructure - Terraform, Velero, Argo CD, cloud-native migration services, and internal developer platforms like Qovery.

Romaric Philogene
CEO & Co-founder
SEP 30, 2026 · 7 MIN
Outgrowing Your PaaS: The Kubernetes Migration Tools That Actually Plug Into Your CI/CD

Key Points:

  • No single tool migrates a PaaS app to Kubernetes end to end. A working stack has four layers: infrastructure provisioning (Terraform/OpenTofu, Pulumi, Crossplane, or the cloud's own IaC), container packaging (Docker, Buildpacks, Helm/Kustomize), delivery (your existing GitHub Actions, GitLab CI, or Jenkins plus Argo CD or Flux), and data and state migration (Velero, managed database services, or dump-and-restore).
  • Your CI/CD pipeline usually does not need to be replaced. Keep GitHub Actions, GitLab CI, or Jenkins for build and test, and add a GitOps controller (Argo CD or Flux) or an internal developer platform so deploys become declarative instead of scripted kubectl calls.
  • The hyperscalers each ship a first-party path - AWS App2Container with EKS, Azure Migrate with AKS, Google Migrate to Containers with GKE - and they are the cheapest option to try first if you are committed to one cloud. They stop at the cluster boundary and give your developers no self-service.
  • The part teams underestimate is day 2. After the cutover you own cluster upgrades, RBAC, autoscaling, secrets, ingress, observability, and the developer experience your PaaS used to hand you for free.
  • Qovery is for teams that want the Kubernetes destination without rebuilding the PaaS experience. It provisions and operates clusters in your own AWS, GCP, Azure, or Scaleway account (or adopts your existing cluster), keeps git-push deploys and preview environments per pull request, and calls your existing CI/CD rather than replacing it.

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

I have spent a lot of the last two years talking to CTOs and platform leads who are leaving a PaaS. The story is almost always the same. They picked Heroku, Render, Fly.io, Railway, Platform.sh, or Elastic Beanstalk because it let a small team ship without hiring an infrastructure person, and it worked right up until it didn't: a pricing cliff, a missing region, a compliance box they could not tick, or a workload the platform would not run. So they decide to move to Kubernetes on a hyperscaler, and then they find out the real cost of leaving was never the migration. It was day 2.

The question I get asked most is the right one. What Kubernetes migration tools actually plug into the CI/CD pipeline we already have, and automate the infrastructure, instead of forcing us to rebuild everything by hand?

What Kubernetes migration tools actually integrate with an existing CI/CD pipeline?

Start with the good news: the CI/CD system you already run almost never needs to change. GitHub Actions, GitLab CI, and Jenkins build and test your code exactly as they do today. What changes is the last step. Instead of pushing to a PaaS, the pipeline builds a container image and hands off to something that deploys it to Kubernetes. Here is the shortlist, grouped by the job each tool does.

  • Layer 1, infrastructure provisioning. Terraform, and its open-source fork OpenTofu, is the de facto standard and runs in any CI system. Pulumi if you want real code instead of HCL. Crossplane if you want to manage infrastructure from inside Kubernetes. Or the cloud's own IaC: AWS CDK, Azure Bicep, Google Config Connector.
  • Layer 2, container packaging. A Dockerfile, or Cloud Native Buildpacks if you want to skip writing one, then Helm or Kustomize to template the Kubernetes manifests.
  • Layer 3, delivery. Keep your existing CI for build and test. Add a GitOps controller, Argo CD or Flux, both mature CNCF projects, with Argo CD alone running in nearly 60% of surveyed Kubernetes clusters (CNCF, 2025). GitOps declares the cluster state in git and syncs it automatically, instead of firing scripted kubectl apply calls from a pipeline.
  • Layer 4, state and data. Velero for cluster backup, restore, and namespace-level migration. A managed database migration service (AWS DMS and the managed database offerings on each cloud) for the database itself. Plain dump-and-restore for small datasets.
  • Layer 5, the layer nobody sells you. Developer self-service: environments on demand, a preview environment per pull request, and RBAC. Your PaaS gave you this for free. Raw Kubernetes does not have it, and this is where an internal developer platform fits.

The trap is expecting one tool to cover all five layers. Terraform provisions but does not deliver. Argo CD delivers but does not provision. Velero backs up but does nothing for developer experience. You assemble them, or you use a platform that owns several layers at once.

How do the main options compare for a team leaving a PaaS?

Pick by who owns day 2, not by feature count. If you already have a platform engineer who wants full control, hyperscaler-native tooling plus Terraform and Argo CD is the right stack. If you want maximum portability and are willing to own the glue, GitOps plus Terraform across clouds. If your real problem is developer velocity and you do not want to hire a platform team, an internal developer platform gives you the PaaS experience back on Kubernetes.

ToolWhat it actually doesPlugs into your CI/CD?Automates infra?Handles day-2 ops?Dev self-service / PR previews?Cloud coverageCost model
Terraform / OpenTofuProvisions cloud infra as codeYes, runs in any CIYes, this is its jobNo, it provisions but does not operateNoEvery major cloudOpen source; paid HashiCorp Cloud
Argo CD / FluxGitOps delivery, syncs cluster to gitYes, complements CINoPartial (drift, rollouts)NoAny KubernetesFree, open source
VeleroBackup, restore, namespace migrationYes, scriptableNoPartial (backup and DR only)NoAny KubernetesFree, open source
AWS App2Container + EKSContainerizes apps, runs them on EKSYesPartial (EKS setup)Cluster onlyNoAWS onlyTool free; pay EKS + nodes
Azure Migrate + AKSAssesses and migrates workloads to AKSYesPartialCluster onlyNoAzure onlyTool free; pay AKS + nodes
Google Migrate to Containers + GKEConverts VMs to containers on GKEYesPartialCluster onlyNoGoogle Cloud onlyTool free; pay GKE + nodes
GitHub Actions / GitLab CI / JenkinsBuild, test, shipThis is your CI/CDWith IaC stepsNoNoAnyFree tiers to paid
QoveryIDP: provisions and operates clusters, git-push deploy, PR previewsYes, calls your CIYes (Terraform under the hood)Yes (managed upgrades, RBAC)YesAWS, GCP, Azure, Scaleway, existing K8sFree tier; paid plans

One honest caveat on that last row. Qovery is opinionated, and it manages the cluster for you. That is exactly what you want if you are leaving a PaaS to get away from operations, and exactly what you do not want if your goal is to hand-roll every Kubernetes primitive yourself. If that is you, raw Terraform plus Argo CD is the more honest fit, and Velero stays in your stack either way because Qovery does not replace it.

Should you migrate to a single hyperscaler's native tooling or stay cloud-agnostic?

If you are certain about one cloud for the next three to five years, start with the first-party tooling. AWS App2Container inventories your app and produces container artifacts and EKS deployment scaffolding. Azure Migrate assesses and moves workloads into AKS. Google Migrate to Containers turns VMs into GKE workloads. All three are free or near-free, and they are the fastest way to a running cluster.

They all stop at the same place: the cluster boundary. They assess, containerize, and create the cluster. None of them give your developers a way to spin up an environment, none give you preview environments per pull request, and none manage the day-2 workflow your PaaS used to.

The lock-in question deserves an honest answer. Kubernetes itself is portable, and a Deployment manifest runs anywhere. The glue around it is not. IAM, load balancers, secrets managers, managed databases, and the Terraform modules that wire them together are cloud-specific. Commit to App2Container plus EKS and you have committed your platform layer to AWS, even though the containers could run anywhere.

That matters because most teams do not stay on one cloud. In the 2023 CNCF Annual Survey, 56% of organizations reported using multiple cloud solutions, averaging 2.3 providers each (CNCF, 2023), and Kubernetes is now in production for 82% of container-using organizations (CNCF, 2025). This is the case for keeping your platform layer cloud-agnostic. Qovery gives you the same git-push workflow whether you deploy to AWS, GCP, Azure, Scaleway, or an existing Kubernetes cluster, and because it runs bring-your-own-cloud, the account, the bill, the committed-use discounts, and the Savings Plans all stay in your name.

What does a realistic PaaS-to-Kubernetes migration sequence look like?

Here is the sequence I would run, with the tool named at each step.

  1. Inventory. List every service, environment variable, add-on, cron job, background worker, and stateful dependency. The things that bite you are the ones the PaaS hid: managed add-ons, egress rules, and scheduled jobs.
  2. Containerize. Write a Dockerfile, or use Cloud Native Buildpacks to skip it, and get parity running locally before you touch the cloud.
  3. Provision. Stand up the cluster with a Terraform or OpenTofu module or a managed provisioner: VPC, node groups, IAM, and an ingress controller.
  4. Move data. Stand up a managed database first (RDS, Cloud SQL, Azure Database), replicate into it, and cut over during a maintenance window. Use Velero for cluster-level and namespace-level state.
  5. Wire the pipeline. Your existing CI builds and pushes the image, then Argo CD syncs the manifests or the IDP runs the deploy. Run both platforms in parallel behind DNS weighting so you can shift traffic gradually.
  6. Cut over and decommission. Shift DNS, watch error rates and latency, and keep the old PaaS warm for a rollback window before you tear it down.

The work teams forget is not in that list, which is the point: secrets management, the log and metrics pipeline, autoscaling policies, PodDisruptionBudgets, and cost alerts. None of it existed for you on the PaaS. All of it is yours now.

How much does running Kubernetes yourself really cost after the migration?

The cluster bill is the small number. Each hyperscaler charges roughly the same for the managed control plane: EKS is $0.10 per cluster per hour (AWS EKS Pricing), AKS Standard tier is about $0.10 per cluster per hour, roughly $72 a month, with a Free tier that waives the control-plane fee entirely (Azure AKS Pricing), and GKE is $0.10 per cluster per hour with one zonal or Autopilot cluster free per billing account (Google Cloud GKE Pricing). Call it around $75 a month per cluster before you run a single pod. Add nodes, load balancers, egress, and an observability stack, and a modest production setup lands in the hundreds to low thousands per month.

The expensive line is the person who operates it. A DevOps engineer in the US has a median total compensation of $170,620 (Levels.fyi), and Kubernetes is a real part of that job. It ships around three minor releases a year (Kubernetes), each maintained for about 14 months (Kubernetes patch policy), so upgrades are a permanent recurring task, not one-time setup. Let a version fall out of support on EKS and you pay $0.60 per cluster per hour for extended support, six times the standard rate (AWS EKS Pricing).

And most of what you provision, you waste. Across tens of thousands of clusters, Cast AI found average CPU utilization of 8% and memory utilization of 20% (Cast AI, 2026). You pay for the rest.

Line itemManaged PaaSSelf-managed KubernetesKubernetes + IDP
Control planeIncluded~$75/mo per cluster~$75/mo per cluster
ComputePremium per instanceCloud list price, right-sizeableList price, right-sized + auto-stop
Load balancer / egressBundled, opaqueCloud list priceCloud list price
Engineering timeNear zero0.5 to 1+ platform engineerFraction of one
Preview environmentsUsually extra or limitedBuild it yourselfIncluded
Who owns upgradesThe providerYouThe platform

Illustrative, list prices only; your numbers will differ. The point is where the savings come from. The reason to run your own Kubernetes is not a cheaper control plane, it is control: right-sizing, spot and preemptible nodes, committed-use discounts that stay in your own account, and auto-stopping non-production environments overnight. Whether you capture those savings comes down to whether someone has the time to, which is the real decision behind tooling versus platform.

Can AI agents or automation do the migration for you?

AI coding agents are genuinely good at the mechanical parts now. Point one at your repo and it will write a passable Dockerfile, generate Helm charts and Terraform modules, and translate a Procfile into Kubernetes Deployments and Services faster than you can. For scaffolding, use them.

Where they are unreliable is exactly where a migration goes wrong: stateful data cutover, network topology, security posture, and anything that depends on knowing your real traffic patterns. An agent will confidently grant an over-broad IAM role to get past an error, and it does not own the decision to point production DNS at the new cluster.

The guardrails that make agent-assisted migration safe are the same ones that make any deploy safe: scoped credentials instead of cloud-admin keys, policy checks in the pipeline, plan-then-apply review on every change, an audit trail, and a preview environment per pull request where an agent's output can be tested before it goes near production. Preview environments and per-environment RBAC give agent-generated changes a safe place to fail, which is the one thing raw kubectl access does not.

When is an internal developer platform the better answer than assembling the tools yourself?

Choose an internal developer platform when your bottleneck is developer velocity and headcount, not Kubernetes expertise. Run the checklist: do you have a dedicated platform engineer, how many environments does your team need each week, do you need a preview environment on every pull request, how many clouds, any regulated workloads? The more of those that hurt, the more a platform earns its keep.

Be clear about the alternatives, because they are good. If you want a developer portal over infrastructure you already run, Backstage or Port. If you want to orchestrate a platform your team builds, Humanitec or Kratix. If you are happy on a PaaS and just outgrew one specific limit, another PaaS like Render, Fly.io, or Railway may be a shorter move than Kubernetes at all. And if you want to own every primitive, Terraform plus Argo CD.

Where Qovery fits is narrow and specific: teams that want the Kubernetes destination and the PaaS experience at the same time. It provisions and upgrades clusters in your own AWS, GCP, Azure, or Scaleway account, or adopts your existing Kubernetes cluster, and on top of that gives you git-push deploys, ephemeral environments per pull request, auto-stop for non-production environments, per-environment RBAC, and databases backed by the managed services of your cloud. Your existing GitHub Actions, GitLab CI, or Jenkins pipeline stays where it is and calls Qovery for the deploy, and the first deploy takes under 10 minutes.

Velocity is worth paying for because it is measurable. In the 2019 Accelerate State of DevOps report, elite teams deployed 208 times more frequently and shipped changes 106 times faster than low performers (DORA, 2019). Most of that gap is the friction between a developer and a running environment, which is exactly what a PaaS removed and what raw Kubernetes puts back.

If you are leaving a PaaS because you outgrew it, do not leave the developer experience behind with it: start deploying on Qovery on your own cloud in under 10 minutes.

Frequently asked questions
What Kubernetes migration tools integrate best with GitHub Actions, GitLab CI, or Jenkins?

All of them, because those systems stay in place. Your CI keeps building and testing, and you add a deploy target. The common combinations are Terraform or OpenTofu for infrastructure, Helm or Kustomize for packaging, and Argo CD or Flux for GitOps delivery, or an internal developer platform that owns the deploy step. None of these replace your pipeline; they attach to it.

Do I have to replace my CI/CD pipeline when I move from a PaaS to Kubernetes?

No, and you usually should not. GitHub Actions, GitLab CI, and Jenkins are perfectly good at build and test. What changes is the final step: instead of pushing to a PaaS you build a container image and hand off to a GitOps controller or a platform that deploys it to the cluster.

What is the difference between Velero, Terraform, and Argo CD in a migration?

They do three different jobs. Terraform, or OpenTofu, provisions the cloud infrastructure such as the VPC, cluster, and IAM. Argo CD, or Flux, delivers your application by syncing the cluster to manifests in git. Velero backs up, restores, and migrates cluster state and namespaces. You typically use all three, and none of them replaces the others.

Is AWS App2Container, Azure Migrate, or Google Migrate to Containers enough on its own?

For getting a workload onto a cluster on one cloud, they are a good and cheap start. They assess, containerize, and create the cluster. They stop at the cluster boundary: no developer self-service, no preview environments, no cross-cloud portability. You will still assemble the delivery and day-2 layers yourself, or use a platform for them.

How long does a PaaS to Kubernetes migration usually take?

It depends far more on state than on code. A stateless service with a clean Dockerfile can move in days. The long poles are data cutover, secrets, networking, and the day-2 setup such as observability, autoscaling, and upgrades, which is work that continues after the cutover. Plan for the migration to be the short part and day-2 operations to be permanent.

What is the cheapest way to keep a PaaS-like developer experience on Kubernetes?

The managed control plane is cheap, about $0.10 per cluster per hour on EKS, AKS Standard, and GKE. The expensive part is building and running the developer experience yourself. If you have the platform-engineering time, Terraform plus Argo CD plus your own preview-environment tooling is the lowest cash cost. If you do not, an internal developer platform is usually cheaper once you count the engineering hours, because it gives you previews, RBAC, and auto-stop without a dedicated team.

Romaric Philogene
About the author
Romaric Philogene

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 AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.