External Secrets Operator

Pulls secrets out of Vault and lays them down as native Kubernetes secrets

The External Secrets Operator reconciles ExternalSecret resources against Vault and materialises plain Kubernetes Secrets in the target namespaces. No sensitive value is ever committed to Git: manifests reference a Vault path, and ESO does the rest. ArgoCD itself reads its own configuration secrets through ESO, which is why ESO is one of the first things installed.

ArgoCD configuration

Excerpt from argocd-apps/values.yaml in the argocd-apps chart, with annotations added for this site:

external-secrets:
  # false: NOT a generated Application. Installed by external-helm-repos/external-secrets-operator.yaml
  application: false
  project: k3s-services
  # the source values.yaml says "external-hel-repos" (typo for external-helm-repos)
  info:
    "This service is installed with the external-secrets-operator.yaml file in
    the external-hel-repos folder"
  # false: ESO must exist before ArgoCD reads its own secrets via ESO
  autoSync: false

Manifests & templates

argocd-apps/templates/external-helm-repos/external-secrets-operator.yaml

Application manifest installing the upstream external-secrets chart from its public Helm repo. There is no local chart: upstream is pinned and the wrapper only sets the release metadata.

Show manifest
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: external-secrets-operator
  namespace: argocd
  annotations:
    meta.helm.sh/release-name: argocd-configuration
    meta.helm.sh/release-namespace: argocd
    argocd.argoproj.io/sync-wave: "-9"
  labels:
    app.kubernetes.io/managed-by: Helm
    meta.helm.sh/release-name: argocd-configuration
    meta.helm.sh/release-namespace: argocd
spec:
  destination:
    namespace: external-secrets-operator
    server: https://kubernetes.default.svc
  project: k3s-services
  source:
    chart: external-secrets
    helm:
      parameters:
        - name: serviceAccount.name
          value: external-secrets-service-account
    repoURL: https://charts.external-secrets.io
    targetRevision: 2.9.0
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
      - ApplyOutOfSyncOnly=true
      - PrunePropagationPolicy=foreground
  • Because ArgoCD depends on it, ESO is installed out-of-band before ArgoCD completes its bootstrap.

Trade-offs

Decision. ESO with Vault as the secret store

Alternative. Sealed Secrets or sops-encrypted values in Git

Why. Secrets stay central with a single rotation point in Vault, and there are no encrypted blobs to re-encrypt when a key rotates.

Decision. Install ESO from a dedicated manifest, not the generated Application

Alternative. A standard app-of-apps entry

Why. ESO must exist before most Applications reconcile, and its Helm repository registration is handled by the same dedicated manifest.

← Back to Platform & Infrastructure · All service groups