PJEM
PJEM

Reputation: 667

Install helm package with already installed components

I've deploed an app to k8s using kubectl apply ... few weeks ago, the application is running in prod. Now we switch to helm installation and build chart that we want to update the application with it. The problem is that there is already deployed artifacts like secret/config maps of the application which I cannot delete.

And while running helm upgrade --install app chart/myapp -n ns

I got error like

Error: rendered manifests contain a resource that already exists. Unable to continue with install: existing resource conflict: namespace: ns, name: bts, existing_kind: /v1, Kind=Secret, new_kind: /v1, Kind=Secret

Is there any trick which I can use to overcome this without deleting the secret/configmap ?

Upvotes: 2

Views: 1879

Answers (2)

user2039152
user2039152

Reputation: 146

You can have helm hooks which can help you to remove it.

annotations:
  "helm.sh/hook": pre-install, pre-upgrade

Above annotation would help fixing this. Similar annotations can be added to resources which are not deleted by default such as ClusterRoles and such.

More hooks can be found here which can be used as per the need.

Upvotes: 0

Mr.KoopaKiller
Mr.KoopaKiller

Reputation: 3962

After testing some options in my lab, I've realized that the way I told you in comments worked.

Helm uses information on metadata and labels are injected in the resources to know what are the resources managed by itself. The workaround below shows how you can import a previous created secret, not managed by Helm, using matadata information from a new secret deployed with Helm.

Let's suppose the my-secret is already deployed and you want to "import" that resource to helm, you need to get the metadata information of the new resource. Let's dig into it:

Scenario:

  1. A secret name my-secret deployed in default name space. (Not managed by Helm)
  2. A helm chart with a secret template named my-new-var with a different value.

Steps:

  1. Create a normal secret for testing purposes using this spec:
    apiVersion: v1
    kind: Secret
    metadata:
      name: my-secret
    type: Opaque
    data:
      secret: S29vcGFLaWxsZXIK
  1. Apply the Helm chart to create the my-new-secret. The real purpose of that is get the metadata and labels information.

After that you can see the secret file using the command:

kubectl get secrets my-secret -o yaml:

apiVersion: v1
data:
  secret: VXB2b3RlSXQ=
kind: Secret
metadata:
  annotations:
    meta.helm.sh/release-name: myapp-1599472603
    meta.helm.sh/release-namespace: default
  creationTimestamp: "2020-09-07T10:03:05Z"
  labels:
    app.kubernetes.io/managed-by: Helm
  name: my-secret
  namespace: default
  resourceVersion: "2064792"
  selfLink: /api/v1/namespaces/default/secrets/my-secret
  uid: 7cf66475-b26b-415b-8c11-8fb6974da495
type: Opaque

From this file we need to get the annotations and labels to apply in our old my-secret.

  1. Edit the secret file created on step 1 to add thoses information. It will result in a file like that:
apiVersion: v1
data:
  secret: S29vcGFLaWxsZXIK
kind: Secret
metadata:
  annotations:
    meta.helm.sh/release-name: myapp-1599472603
    meta.helm.sh/release-namespace: default
  name: my-secret
  labels:
    app.kubernetes.io/managed-by: Helm
  namespace: default
  1. Delete the my-new-secret create by Helm, since we not longer use it: kubectl delete secrets my-new-secret

  2. In the Helm chart, edit the secret name to match with the old secret, in our case change the name from my-new-secret to my-secret.

  3. Upgrade the Helm chart, in my case I have used a value from Values.yaml:

$ helm upgrade -f myapp/values.yaml myapp-1599472603 ./myapp/
Release "myapp-1599472603" has been upgraded. Happy Helming!
NAME: myapp-1599472603
LAST DEPLOYED: Mon Sep  7 10:28:38 2020
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None

Upvotes: 2

Related Questions