External Secrets Operator sur Kubernetes

À la fin de ce tutoriel, vous saurez installer External Secrets Operator (ESO), connecter un SecretStore à AWS Secrets Manager (et SSM Parameter Store) en région ca-central-1, déclarer un ExternalSecret qui matérialise un Secret Kubernetes, et appliquer les réflexes day-2 (rotation, RBAC, cleanup) sans committer de credentials dans Git.

Niveau : Intermédiaire · Temps estimé : 55–75 min · Versions cibles : External Secrets Operator stable (Helm) · Kubernetes 1.31+ · AWS CLI v2 · Helm 3 · Dernière vérification : 2026-09-11 · Region : ca-central-1

Slug : wow-external-secrets-operator · Série : WOW (13/50) · Mot-clé SEO : external secrets operator · Publish : HOLD

← Précédent : SOPS + age : secrets dans Git · → Suivant : cert-manager + Let’s Encrypt · Aussi : Secrets Kubernetes · Vault

Prérequis

Coût estimé : 0–1 € si vous créez un secret Secrets Manager court, restez en Free Tier et supprimez tout en fin de lab. Pas d’EKS « pour tester ESO » si un kind local suffit pour le contrôleur ; AWS ne sert qu’au backend secrets.

export AWS_PROFILE=lab
export AWS_DEFAULT_REGION=ca-central-1
aws sts get-caller-identity
kubectl version --short 2>/dev/null || kubectl version
helm version --short

Ce que nous allons construire

Lab External Secrets Operator (WOW 13/50) — ca-central-1
  ├── Pourquoi ESO (vs Secrets nus / SOPS / Vault)
  ├── Install Helm : namespace external-secrets
  ├── Secret AWS Secrets Manager (placeholder lab)
  ├── IAM minimal + SecretStore (aws)
  ├── ExternalSecret → Secret K8s Opaque
  ├── Consommation Pod (envFrom) + refresh
  ├── Variante SSM Parameter Store
  └── Cleanup + quiz + FAQ + maillage WOW

(Schéma — alt : « External Secrets Operator synchronise AWS Secrets Manager ca-central-1 vers un Secret Kubernetes ».)

Étape 1 — Pourquoi External Secrets Operator ?

Un Secret Kubernetes stocke des données en base64 dans etcd. Ce n’est pas un coffre-fort : qui a accès à l’API ou à etcd peut lire. Committer des Secrets YAML dans Git = fuite garantie.

Trois patterns DevOps courants :

Approche Idée Quand
SOPS + age Chiffrer des fichiers dans Git GitOps pur, petits clusters
Vault Coffre central + agents Multi-équipes, policies riches
ESO Sync depuis un backend cloud (ASM, SSM, Vault, Azure KV…) vers des Secrets K8s AWS/GCP/Azure natif, GitOps sans secret en clair

External Secrets Operator est un contrôleur Kubernetes : vous déclarez lire (provider + clé) et comment projeter (template Secret). Le Secret live est créé/mis à jour dans le cluster ; le source of truth reste AWS (ou Vault). Idéal avec Argo CD : manifests ESO dans Git, valeurs hors Git.

En 2026, ESO est le pont standard « cloud secret store → Kubernetes » pour beaucoup d’équipes plateforme — complémentaire de Vault et SOPS, pas un remplacement dogmatique.

Étape 2 — Installer External Secrets Operator (Helm)

kubectl create namespace external-secrets --dry-run=client -o yaml | kubectl apply -f -

helm repo add external-secrets https://charts.external-secrets.io
helm repo update

helm upgrade --install external-secrets external-secrets/external-secrets 
  -n external-secrets 
  --set installCRDs=true 
  --wait --timeout 5m

kubectl -n external-secrets get pods
kubectl get crd | grep external-secrets

Attendu : Pods controller / webhook / cert-controller Ready ; CRDs secretstores, clustersecretstores, externalsecrets, etc.

Vérifiez les versions API :

kubectl api-resources | grep -E 'externalsecret|secretstore'

Étape 3 — Créer le secret source dans AWS (ca-central-1)

Placeholders uniquement — jamais de vrais credentials de prod.

SECRET_NAME="deh/lab/eso-demo"
aws secretsmanager create-secret 
  --name "$SECRET_NAME" 
  --region ca-central-1 
  --secret-string '{"username":"demo-user","password":"CHANGE_ME_lab_only"}' 
  --tags Key=Project,Value=devops-elastic-hayway Key=Env,Value=lab

Si le secret existe déjà : put-secret-value avec la même chaîne JSON. Notez l’ARN :

aws secretsmanager describe-secret --secret-id "$SECRET_NAME" 
  --region ca-central-1 
  --query ARN --output text

Étape 4 — IAM minimal et SecretStore

Le contrôleur ESO doit lire Secrets Manager. En lab kind/kubeadm hors AWS, le pattern simple est un utilisateur/rôle IAM dont les clés vivent dans un Secret Kubernetes bootstrapping (jetable). En EKS, préférez IRSA ou Pod Identity — voir wow-eks-pod-identity.

Politique minimale (lab) :

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "secretsmanager:GetSecretValue",
      "secretsmanager:DescribeSecret"
    ],
    "Resource": "arn:aws:secretsmanager:ca-central-1:*:secret:deh/lab/*"
  }]
}

Créez le Secret d’accès AWS hors Git (placeholders) :

kubectl -n default create secret generic awssm-creds 
  --from-literal=access-key=AKIA_PLACEHOLDER_LAB 
  --from-literal=secret-access-key=PLACEHOLDER_SECRET_LAB

SecretStore (namespace-scoped) :

# secretstore-aws.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: aws-secretsmanager
  namespace: default
spec:
  provider:
    aws:
      service: SecretsManager
      region: ca-central-1
      auth:
        secretRef:
          accessKeyIDSecretRef:
            name: awssm-creds
            key: access-key
          secretAccessKeySecretRef:
            name: awssm-creds
            key: secret-access-key
kubectl apply -f secretstore-aws.yaml
kubectl describe secretstore aws-secretsmanager

Attendu : condition Ready=True. En EKS, remplacez auth.secretRef par jwt / IRSA selon la doc provider AWS ESO.

Étape 5 — ExternalSecret → Secret Opaque

# externalsecret-demo.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: app-db-credentials
  namespace: default
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secretsmanager
    kind: SecretStore
  target:
    name: app-db-credentials
    creationPolicy: Owner
    deletionPolicy: Retain
  data:
  - secretKey: username
    remoteRef:
      key: deh/lab/eso-demo
      property: username
  - secretKey: password
    remoteRef:
      key: deh/lab/eso-demo
      property: password
kubectl apply -f externalsecret-demo.yaml
kubectl get externalsecret app-db-credentials
kubectl get secret app-db-credentials -o yaml

Attendu : ExternalSecret SecretSynced ; Secret Opaque avec clés username / password (valeurs base64). Le YAML Git ne contient aucune valeur sensible — seulement des références.

Consommation Pod (lab) :

apiVersion: v1
kind: Pod
metadata:
  name: eso-consumer
spec:
  containers:
  - name: demo
    image: busybox:1.36
    command: ["sh","-c","env | grep -E 'username|password'; sleep 3600"]
    envFrom:
    - secretRef:
        name: app-db-credentials
  restartPolicy: Never
kubectl apply -f pod-eso-consumer.yaml
kubectl logs eso-consumer

Étape 6 — SSM Parameter Store (variante) et rotation

Pour un paramètre String/SecureString :

aws ssm put-parameter 
  --name /deh/lab/eso-api-token 
  --type SecureString 
  --value "PLACEHOLDER_TOKEN_LAB" 
  --region ca-central-1 
  --overwrite

SecretStore avec service: ParameterStore (même région ca-central-1). Dans l’ExternalSecret, remoteRef.key: /deh/lab/eso-api-token.

Rotation : changez la valeur côté AWS (put-secret-value / put-parameter). ESO rafraîchit selon refreshInterval (ex. 1h, ou 5m en lab). Pour forcer : annoter / recréer l’ExternalSecret, ou attendre le reconcile. En prod, alignez intervalle, alarmes CloudWatch et runbook incident.

ClusterSecretStore : même idée, scope cluster, pour partager un provider entre namespaces (RBAC strict recommandé).

Étape 7 — Sécurité, GitOps et cleanup

Règles DEH :

  1. Jamais de vrais secrets dans Git, captures ou tickets Slack
  2. IAM least privilege + resource ARN préfixés deh/lab/*
  3. RBAC : qui peut lire le Secret matérialisé ≠ qui gère ExternalSecret
  4. Préférez IRSA/Pod Identity sur EKS plutôt que Access Keys longues
  5. deletionPolicy conscient : Delete vs Retain selon incident response
  6. Observabilité : metrics controller + alertes sync failed

Cleanup lab :

kubectl delete pod eso-consumer --ignore-not-found
kubectl delete externalsecret app-db-credentials --ignore-not-found
kubectl delete secret app-db-credentials awssm-creds --ignore-not-found
kubectl delete secretstore aws-secretsmanager --ignore-not-found
# helm uninstall external-secrets -n external-secrets  # optionnel
aws secretsmanager delete-secret --secret-id deh/lab/eso-demo 
  --region ca-central-1 --force-delete-without-recovery
aws ssm delete-parameter --name /deh/lab/eso-api-token --region ca-central-1 || true

Erreurs fréquentes

Erreur Impact Correction
Region us-east-1 par défaut Secret introuvable Forcer ca-central-1 partout
Access Key dans le manifeste Git Fuite Secret bootstrapping hors Git / IRSA
property JSON incorrect Sync Failed Vérifier secret-string JSON + clés
RBAC trop large sur Secrets Lecture latérale Least privilege namespace
refreshInterval trop long Secrets périmés Ajuster + runbook rotation
Confondre SOPS et ESO Mauvais outil SOPS = fichiers Git ; ESO = sync runtime

Quiz (5 questions)

1. External Secrets Operator sert surtout à :
– A. Remplacer etcd
– B. Synchroniser un backend secrets vers des Secrets K8s
– C. Chiffrer les images Docker

2. Le source of truth recommandé avec ESO + AWS est :
– A. Un YAML Secret commité
– B. Secrets Manager / SSM (valeurs hors Git)
– C. Un ConfigMap

3. Region lab DEH :
– A. us-east-1
– B. ca-central-1
– C. eu-west-3

4. Sur EKS en prod, l’auth ESO préférée est :
– A. Access keys dans le Dockerfile
– B. IRSA ou Pod Identity
– C. User root AWS

5. refreshInterval: 1h signifie :
– A. Le Pod redémarre chaque heure
– B. ESO re-lit le backend au plus tôt toutes les heures
– C. AWS rotate automatiquement

Réponses : 1‑B · 2‑B · 3‑B · 4‑B · 5‑B

FAQ

ESO remplace-t-il Vault ?

Non. Vault reste un coffre riche (dynamic secrets, policies). ESO peut consommer Vault comme provider, ou synchroniser ASM/SSM. Choisissez selon maturité et multi-cloud.

ESO vs sealed-secrets / SOPS ?

Sealed-secrets et SOPS gardent des blobs chiffrés dans Git. ESO garde les références dans Git et les valeurs dans le cloud. Les trois coexistent souvent (SOPS pour bootstrap, ESO pour app secrets).

Faut-il ClusterSecretStore dès le jour 1 ?

Non. Commencez par un SecretStore namespacé. Passez cluster-scoped quand plusieurs équipes partagent le même provider avec RBAC clair.

Kind local + Secrets Manager : utile ?

Oui pour apprendre les CRDs. Le contrôleur tourne en local ; seuls les appels AWS sortent. Supprimez le secret lab ensuite.

Et Azure Key Vault / GCP Secret Manager ?

Même modèle : provider dans SecretStore, puis ExternalSecret. Les concepts DEH (region lab, least privilege, GitOps) restent valides.

Comment déboguer Sync Failed ?

kubectl describe externalsecret, events, logs du controller (external-secrets ns), droits IAM, nom de clé / property JSON, region.

Pour aller plus loin

Maillage série WOW

← Précédent SOPS + age
→ Suivant cert-manager + Let’s Encrypt
Aussi Vault · Secrets K8s · Argo CD · Trivy

Meta publication (SEO)

  • Title SEO : External Secrets Operator sur Kubernetes (guide FR 2026)
  • Meta description : External Secrets Operator : installer ESO, SecretStore AWS Secrets Manager / SSM en ca-central-1, ExternalSecret, rotation, FAQ et quiz DEH.
  • Focus keyword : external secrets operator
  • Secondary : AWS Secrets Manager Kubernetes, ExternalSecret, SecretStore, SSM Parameter Store
  • Image : assets/web/devopelastichayway/cover-wow-external-secrets-operator-1200x630.webp (à générer)
  • Catégorie : WOW / Kubernetes Security · Niveau : Intermédiaire
  • URL cible : https://devopelastichayway.com/tutoriels/wow-external-secrets-operator/
  • Post live : N/A (nouveau) · slug wow-external-secrets-operator · Publish : HOLD (draft only — feu vert Maître / auto-push WP-CLI)

← Catalogue Tutoriels

Pour aller plus loin — hubs live

Retour parcours Catalogue Tutoriels — hub de la série et leçons sœurs.