azure-aksargocdworkload-identity

How to use Workload Identity when configuring external clusters in Argo CD?


I think Workload Identity is supported for adding external (AKS) clusters in Argo CD but I can't find a detailed guide anywhere for how to do this.

The official docs contain some info about how to configure kubelogin to achieve what I want, but this isn't a complete guide. Any ideas?


Solution

  • You need to create a secret in the argocd namespace. If you want to use the cluster managed identity, use:

    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: argocd-cluster-mycluster
      labels:
        argocd.argoproj.io/secret-type: cluster
      namespace: argocd
    type: Opaque
    stringData:
      name: mycluster-cluster
      server: https://mycluster-h78yh3n4.privatelink.northeurope.azmk8s.io:443
      config: |
        {
          "execProviderConfig": {
            "command": "argocd-k8s-auth",
            "env": {
              "AAD_ENVIRONMENT_NAME": "AzurePublicCloud",
              "AZURE_TENANT_ID": "f819aa9e-a2bf-4407-886f-4b68f2ce1d87",
              "AAD_SERVICE_PRINCIPAL_CLIENT_ID": "acb689c3-412a-4358-ab19-c48f39c6768b",
              "AAD_LOGIN_METHOD": "msi"
            },
            "args": ["azure"],
            "apiVersion": "client.authentication.k8s.io/v1beta1"
          },
          "tlsClientConfig": {
            "insecure": false,
            "caData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FU..."
          }
        }
    

    For Workload Identity use:

    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: argocd-cluster-mycluster
      labels:
        argocd.argoproj.io/secret-type: cluster
      namespace: argocd
    type: Opaque
    stringData:
      name: mycluster-cluster
      server: https://mycluster-h78yh3n4.privatelink.northeurope.azmk8s.io:443
      config: |
        {
          "execProviderConfig": {
            "command": "argocd-k8s-auth",
            "env": {
              "AAD_ENVIRONMENT_NAME": "AzurePublicCloud",
              "AAD_LOGIN_METHOD": "workloadidentity"
            },
            "args": ["azure"],
            "apiVersion": "client.authentication.k8s.io/v1beta1"
          },
          "tlsClientConfig": {
            "insecure": false,
            "caData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FU..."
          }
        }
    

    The only tricky part is to understand the tlsClientConfig. You need to go to your cluster and run

    kubectl get cm -n kube-system kube-root-ca.crt -o jsonpath="{['data']['ca\.crt']}" | tr -d '\n' | base64
    

    Notice that you are retrieving a ConfigMap and the content of the caData is not sensitive.

    In order to setup Workload Identity in ArgoCD, I use a kustomization.yaml with the following patches:

    patches:
      - target:
          kind: ServiceAccount
          name: argocd-application-controller
        patch: &managedidentity |-
          - op: add
            path: /metadata/annotations/azure.workload.identity~1client-id
            value: 6f602cae-9e6b-4f59-b3e1-f3cd071b106d
      - target:
          kind: ServiceAccount
          name: argocd-applicationset-controller
        patch: *managedidentity
      - target:
          kind: ServiceAccount
          name: argocd-server
        patch: *managedidentity
      - target:
          kind: StatefulSet
          name: argocd-application-controller
        patch: |-
          - op: add
            path: /spec/template/metadata/labels/azure.workload.identity~1use
            value: "true"
      - target:
          kind: Deployment
          name: argocd-applicationset-controller
        patch: |-
          - op: add
            path: /spec/template/metadata/labels/azure.workload.identity~1use
            value: "true"
      - target:
          kind: Deployment
          name: argocd-server
        patch: |-
          - op: add
            path: /spec/template/metadata/labels/azure.workload.identity~1use
            value: "true"