Import Existing k8s Resources in Helm 3
When managing a production cluster, you might need to import existing k8s cluster resources to a Helm deployment from time to time. It could be because you try to migrate existing cluster app that is not deployed by Helm or manually fix some errors during the migration/upgrade. Being able to import existing resources means you don’t have to delete all resources (which is usually not an acceptable option for production) and redeploy the whole application, which is crucial for managing production deployment.
Since Helm 3.2, it’s possible to import/adopt existing resources into the helm release¹. To achieve that, you simply need to add the following annotation & label to the resource:
annotations:
meta.helm.sh/release-name: app-release-name
meta.helm.sh/release-namespace: app-deploy-namespace-name
labels:
app.kubernetes.io/managed-by: Helm
Here, app-release-name
is the release name you used to deploy your helm chart and app-deploy-namespace-name
is the deployment namespace.
Use kubectl
You can use the following commands to add the annotation & label using kubectl
command-line tool:
KIND=deployment
NAME=my-app-staging
RELEASE_NAME=staging
NAMESPACE=defaultkubectl annotate $KIND $NAME meta.helm.sh/release-name=$RELEASE_NAMEkubectl annotate $KIND $NAME meta.helm.sh/release-namespace=$NAMESPACEkubectl label $KIND $NAME app.kubernetes.io/managed-by=Helm
The command above will set proper annotation & label for a deployment
object with name my-app-staging
in namespace default
and make it be adopted by a Helm deployment with name staging
. You can set environment variables (e.g.$KIND
etc.) above to different values to import a different resource.
Import Resource in Batch
The command above might still be too troublesome if you want to migrate an existing application that is not deployed previously to Helm. To import all existing resources of a kind in batch, you can use the following command instead:
NAMESPACE=default
RELEASE_NAME=stagingkubectl get -n $NAMESPACE deploy,configMap -o name | xargs -I % kubectl label -n $NAMESPACE % app.kubernetes.io/managed-by=Helmkubectl get -n $NAMESPACE deploy,configMap -o name | xargs -I % kubectl annotate -n $NAMESPACE % meta.helm.sh/release-name=$RELEASE_NAMEkubectl get -n $NAMESPACE deploy,configMap -o name | xargs -I % kubectl annotate -n $NAMESPACE % meta.helm.sh/release-namespace=$NAMESPACE
The command above will import all existing deployment & configMap type/kind of resources to Helm release staging
.