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-1Slug :
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
- Cluster Kubernetes 1.31+ avec
kubectladmin (kind, minikube, kubeadm ou EKS lab) - Secrets Kubernetes : Opaque, TLS et limites : comprendre why Secrets ≠ chiffrement
- Helm 3 installé ; AWS CLI v2 + profil
lab - Compte AWS de lab — Démarrer avec AWS
- Notions IAM utiles (rôle / politique minimale)
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 où 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 :
- Jamais de vrais secrets dans Git, captures ou tickets Slack
- IAM least privilege + resource ARN préfixés
deh/lab/* - RBAC : qui peut lire le Secret matérialisé ≠ qui gère ExternalSecret
- Préférez IRSA/Pod Identity sur EKS plutôt que Access Keys longues
deletionPolicyconscient :DeletevsRetainselon incident response- 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
- SOPS + age : secrets dans Git (WOW 12)
- HashiCorp Vault pour secrets DevOps (WOW 11)
- cert-manager + Let’s Encrypt (WOW 14)
- Secrets Kubernetes
- EKS Pod Identity
- Argo CD GitOps
- Policy-as-Code OPA
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)
Pour aller plus loin — hubs live
Retour parcours Catalogue Tutoriels — hub de la série et leçons sœurs.