How I Migrated an AKS Cluster Across Regions Using Velero

DevOps & Cloud Engineer — building scalable, automated, and intelligent systems. Developer of sorts | Automator | Innovator
Search for a command to run...

DevOps & Cloud Engineer — building scalable, automated, and intelligent systems. Developer of sorts | Automator | Innovator
Artificial Intelligence has become one of the biggest talking points in software engineering. Every week, a new tool promises to automate deployments, fix production incidents, or replace developers a

You spin up a Kubernetes workload. You connect to PostgreSQL. You add sslmode=require because security matters. And then PostgreSQL replies with: server does not support SSL, but SSL was required Wai

When you first approach Tencent Cloud, it feels familiar if you come from AWS or Azure. There are VPCs, Kubernetes clusters, load balancers, object storage, IAM, everything you would expect. But once

When I first automated Docker builds and deployments, I thought the hard part would be writing the YAML. It was not. The real challenges were versioning, preventing accidental rollbacks, handling envi

For a long time, Docker Compose felt like the perfect solution. Simple YAML, fast local setup, predictable behavior. For a single service or even a small stack, it works beautifully. But at some point, reality catches up. As the application grew, tra...

CodeOps Studies
40 posts
Simple write-ups on day to day code or devops experiments, tests etc.
Migrating an entire Kubernetes cluster is one of those tasks that sounds straightforward until you actually begin. When I recently needed to migrate an Azure Kubernetes Service (AKS) cluster from the Central India region to the East US region, the process involved more considerations than simply exporting YAML files and applying them elsewhere.
The requirement was clear. Migrate every workload, every Persistent Volume Claim, every Secret, every ConfigMap, every Custom Resource Definition, and all namespace-level objects. Everything had to move with accuracy.
After evaluating different approaches, Velero turned out to be the most reliable and practical tool for a complete AKS region migration. Velero supports backup and restoration of cluster state as well as persistent storage, and its Azure plugin works smoothly with both Azure Blob Storage and Azure Disk snapshots.
This guide describes the exact steps I followed, the challenges I encountered, and the final workflow that resulted in a successful migration.
Velero has several advantages for full-cluster migration:
This includes Deployments, StatefulSets, Services, Secrets, ConfigMaps, RBAC objects, and Custom Resources.
This is essential when migrating workloads that depend on Persistent Volume Claims.
Velero supports most Kubernetes API versions used in AKS.
This is useful when the source and destination are in different regions.
Velero requires an Azure Blob Storage account and a resource group for snapshot management.
Choose a region for the storage account. You can use either the source or destination region because Velero backups are region independent.
az storage account create \
--name veleroaccount123 \
--resource-group velero-rg \
--location eastus \
--sku Standard_GRS
az storage container create \
--name velero-backups \
--account-name veleroaccount123
In my case, I used a managed identity created for Velero with the required permissions:
Contributor role on the Resource Group
Storage Blob Data Contributor on the Storage Account
This avoids the need for storing client secrets.
Once the storage and identity were ready, I installed Velero on the source cluster.
brew install velero
(Or download from the official GitHub releases page if not using macOS.)
velero install \
--provider azure \
--plugins velero/velero-plugin-for-microsoft-azure:v1.10.0 \
--bucket velero-backups \
--secret-file ./credentials-velero \
--backup-location-config resourceGroup=velero-rg,storageAccount=veleroaccount123 \
--use-volume-snapshots=true \
--snapshot-location-config resourceGroup=velero-rg
Now Velero runs inside the cluster with all necessary permissions.

I wanted a complete backup of every namespace, every CRD, and all persistent volumes.
velero version
kubectl get pods -n velero

velero backup create aks-full-backup \
--include-namespaces '*' \
--wait
The backup took several minutes because the cluster had StatefulSets and large PVCs.
velero backup describe aks-full-backup
velero backup logs aks-full-backup
At this stage I had a complete backup stored in Azure Blob Storage and snapshots created for all PVCs.
I created a new cluster in East US with the same Kubernetes version as the source cluster. Matching the Kubernetes version is important because restoring cluster-level objects may otherwise cause compatibility issues.
az aks create \
--resource-group uspreprod-rg \
--name uspreprod-aks \
--location eastus \
--node-count 3 \
--kubernetes-version 1.29
After the cluster was ready, I connected to it:
az aks get-credentials \
--resource-group uspreprod-rg \
--name uspreprod-aks \
--overwrite-existing
The installation process is similar to the source cluster:
velero install \
--provider azure \
--plugins velero/velero-plugin-for-microsoft-azure:v1.10.0 \
--bucket velero-backups \
--secret-file ./credentials-velero \
--backup-location-config resourceGroup=velero-rg,storageAccount=veleroaccount123 \
--use-volume-snapshots=true \
--snapshot-location-config resourceGroup=velero-rg
Velero now has access to the same storage account and snapshots that were created from the source cluster.
velero restore create aks-full-restore \
--from-backup aks-full-backup \
--wait
Velero recreated:
Namespaces
Deployments
StatefulSets
Services
Ingress objects
Secrets and ConfigMaps
CRDs and CRs
Everything linked to snapshots
velero restore describe aks-full-restore
velero restore logs aks-full-restore
I validated that workloads came up correctly:
kubectl get pods --all-namespaces
kubectl get pvc --all-namespaces
kubectl get ingress --all-namespaces
Any workload that depended on Persistent Volumes was able to recover because the Azure snapshots were restored successfully.
Some CRDs must exist before restoring their corresponding objects.
Solution: Install CRDs manually or let Velero restore cluster-level CRDs first.
Azure snapshots sometimes take time to rehydrate into new disks.
Solution: Wait a few minutes and reapply StatefulSets if needed.
The managed identity must have Contributor access on both resource groups.
Without this, PVC restore will fail.
The new cluster may create a different external IP for the ingress controller.
Update DNS records accordingly.
Migrating an AKS cluster across regions can feel overwhelming due to the number of moving parts involved. Velero simplifies the process significantly by offering a predictable and reliable way to back up and restore clusters at scale.
In my case, Velero successfully migrated every namespace, every workload, and every Persistent Volume from the Central India AKS cluster to a completely new cluster in East US. The process was clean, repeatable, and did not require manual recreation of YAML files.
If you are planning a similar migration, I strongly recommend preparing the destination cluster with the same Kubernetes version, ensuring proper identity permissions, and validating your snapshot restores.
Velero is a powerful tool, and with the right configuration, it can handle migrations across regions with very little manual effort.