# Migrating an ArgoCD-based Linkerd install to BEL's lifecycle automation

In this guide we'll walk you through how to migrate from an ArgoCD deployment of
the Linkerd control plane to one that is managed with BEL's
[lifecycle automation](/buoyant-enterprise-linkerd/latest/features/operator/).

## Why do we need to do anything?

BEL's lifecycle operator relies on a Helm deployment of the
`linkerd-control-plane` and `linkerd-crds` charts. ArgoCD deploys a templated
version of those charts instead of the actual charts themselves. Before the
operator can take over a Linkerd deployment we'll first need to tell Helm to
"adopt" the existing Linkerd install.

## What do we need to do?

Follow along with the steps in this document to "adopt" an existing Linkerd
install. In our example we're going to show you how to spin up a k3d cluster but
you can perform the migration steps on any cluster.

## Required tools

To complete this migration, you will need:

- A functioning Kubernetes cluster with Linkerd install via ArgoCD
- Helm installed on your local machine
- The `BUOYANT_LICENSE` environment variable set
- The `base64` BEL CLI, for decoding TLS certificates in Step 1

## Step 1: Migrating an ArgoCD install to Helm

You'll need to move your ArgoCD install to a Helm install of the latest BEL
version before managing it with the lifecycle automation operator.

The Helm charts used in this step are hosted in the `linkerd-buoyant` Helm repo,
which can be added/updated as followed:

```bash
helm repo add linkerd-buoyant https://helm.buoyant.cloud
helm repo update linkerd-buoyant
```

Start by adding the required labels and annotations to Linkerd's CRDs:

```bash
kubectl label crds -l linkerd.io/control-plane-ns=linkerd app.kubernetes.io/managed-by=Helm
kubectl annotate crds -l linkerd.io/control-plane-ns=linkerd \
  meta.helm.sh/release-name=linkerd-crds meta.helm.sh/release-namespace=linkerd
```

Then use the `helm` command to move these resources to be managed by BEL's
`linkerd-enterprise-crds` chart:

```bash
helm install linkerd-crds -n linkerd linkerd-buoyant/linkerd-enterprise-crds
```

Next add the required labels and annotations to all control plane resources:

```bash
kubectl label clusterrole,clusterrolebinding,configmap,cronjob,deployment,mutatingwebhookconfiguration,namespace,role,rolebinding,secret,service,serviceaccount,validatingwebhookconfiguration \
  -A -l linkerd.io/control-plane-ns=linkerd \
  app.kubernetes.io/managed-by=Helm
kubectl annotate clusterrole,clusterrolebinding,configmap,cronjob,deployment,mutatingwebhookconfiguration,namespace,role,rolebinding,secret,service,serviceaccount,validatingwebhookconfiguration \
  -A -l linkerd.io/control-plane-ns=linkerd \
  meta.helm.sh/release-name=linkerd-control-plane meta.helm.sh/release-namespace=linkerd
kubectl -n linkerd label role/ext-namespace-metadata-linkerd-config \
  app.kubernetes.io/managed-by=Helm
kubectl -n linkerd annotate role/ext-namespace-metadata-linkerd-config \
  linkerd.io/control-plane-ns=linkerd meta.helm.sh/release-name=linkerd-control-plane meta.helm.sh/release-namespace=linkerd
```

If you have enabled Pod Disruption Budgets policies, then you will also need to
label and annotate these resources:

```bash
kubectl annotate pdb -l linkerd.io/control-plane-ns=linkerd \
  meta.helm.sh/release-name=linkerd-control-plane meta.helm.sh/release-namespace=linkerd
kubectl label pdb -l linkerd.io/control-plane-ns=linkerd \
  app.kubernetes.io/managed-by=Helm
```

Then use the `helm` command to move these resources to be managed by BEL's
`linkerd-enterprise-crds` chart.

To complete this step, you will need the CA certificate that you used to install
your control plane. Assuming you followed [Linkerd's GitOps guide to
ArgoCD](https://linkerd.io/2.20/tasks/gitops/), you'll
already be using [cert-manager](https://cert-manager.io/) to furnish your issuer
certificates. Get the CA certificate with:

```bash
kubectl -n linkerd get cm/linkerd-identity-trust-roots -ojsonpath='{.data.ca-bundle\.crt}' > ca.crt
```

Then run the Helm install:

```bash
helm install linkerd-control-plane \
  -n linkerd \
  --set license=$BUOYANT_LICENSE \
  --set-file identityTrustAnchorsPEM=ca.crt \
  --set identity.issuer.scheme=kubernetes.io/tls \
  linkerd-buoyant/linkerd-enterprise-control-plane
```

Your Linkerd installation on this cluster is now managed via Helm, which you can
verify by running:

```bash
helm list -n linkerd
```

Which should output something like:

```bash
NAME                 	NAMESPACE	REVISION	...	APP VERSION
linkerd-control-plane	linkerd  	1       	...	enterprise-2.20.6
linkerd-crds         	linkerd  	1       	...	enterprise-2.20.6
```

## Step 2: Migrating to BEL's lifecycle automation

With Step 1 completed, the ArgoCD deployment of the Linkerd control plane has
been migrated to Helm.

You can now use BEL's lifecycle operator to takeover this Helm install using the
[BEL lifecycle automation guide](/buoyant-enterprise-linkerd/latest/guides/migrating-to-bel-lifecycle-automation/#step-2-install-lifecycle-automation-components),
starting with Step 2.
