Belajar GitOps - FluxCD - External Secrets Operator
Episode 21 of 36

Belajar GitOps - FluxCD - External Secrets Operator

Mengelola secret dari sistem eksternal dengan External Secrets Operator: arsitektur SecretStore dan ExternalSecret, integrasi AWS Secrets Manager, Vault, hingga 1Password, sinkronisasi lewat FluxCD, dan praktik terbaik rotasi serta audit secret.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Pendahuluan

Di episode 20 kalian sudah mengenkripsi secret dengan SOPS sehingga bisa di-commit ke Git. Namun ada keterbatasan: kunci privat tetap harus ada di setiap cluster, dan rotasi otomatis tidak built-in — kalau secret berubah di sistem sumber, SOPS tidak tahu. Di sinilah pendekatan yang berbeda: simpan secret di sistem terkelola eksternal, dan biarkan operator menariknya ke cluster.

Episode ini membahas External Secrets Operator (ESO): arsitektur dan CRD-nya, integrasi dengan backend populer seperti AWS Secrets Manager dan HashiCorp Vault, cara mengintegrasikannya dengan Flux, serta praktik terbaik untuk siklus hidup secret.

Arsitektur External Secrets Operator

ESO adalah sebuah controller di dalam cluster yang bekerja berdasarkan keinginan (desired state) yang dideklarasikan lewat CRD. Alurnya:

  1. ExternalSecret mendeklarasikan secret apa yang ingin dibuat di cluster dan dari mana.
  2. SecretStore / ClusterSecretStore mendefinisikan koneksi ke sistem eksternal dan kredensialnya.
  3. Controller mengambil nilai dari backend, lalu membuat dan memperbarui Kubernetes Secret native.

Yang menarik untuk GitOps: manifest yang masuk Git hanya berisi referensi dan konfigurasi, bukan nilai rahasia. Nilai sebenarnya hidup di backend eksternal dan tidak pernah ada di repo.

CRDScopeFungsi
SecretStoreNamespaceKoneksi ke backend, hanya berlaku dalam satu namespace
ClusterSecretStoreClusterKoneksi ke backend, bisa dipakai semua namespace
ExternalSecretNamespaceMenarik nilai dari store dan membentuk Secret

Integrasi Backend

ESO mendukung banyak backend. Pemilihan biasanya mengikuti tempat organisasi sudah menyimpan rahasianya.

BackendCocok untukCatatan
AWS Secrets ManagerTim AWSRotasi terkelola, harga per secret
AWS Parameter StoreTim AWSMurah, bagus untuk konfigurasi non-rahasia
GCP Secret ManagerTim GCPWorkload Identity
Azure Key VaultTim AzureManaged identity
HashiCorp VaultMulti-cloudKunci, dynamic secrets, audit lengkap
1PasswordTim kecilSimpel, akun tim

Contoh ClusterSecretStore ke AWS Secrets Manager dengan kredensial dari Secret:

clusters/prod/eso/clustersecretstore.yaml
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: aws-secrets-manager
spec:
  provider:
    aws:
      service: SecretsManager
      region: ap-southeast-1
      auth:
        secretRef:
          accessKeyIDSecretRef:
            name: aws-eso-creds
            key: access-key
          secretAccessKeySecretRef:
            name: aws-eso-creds
            key: secret-access-key

Tip

Di AWS gunakan IAM Roles for Service Accounts alih-alih access key: controller cukup diberi peran IAM dengan izin secretsmanager:GetSecretValue, sehingga tidak ada kredensial statis yang disimpan di cluster.

Membuat Secret dengan ExternalSecret

Setelah store tersedia, deklarasikan secret yang ingin dibentuk. Nilai diambil dari backend per key dan dipetakan ke data Secret:

clusters/prod/apps/api-db-externalsecret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: api-db
  namespace: apps
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: api-db
    creationPolicy: Owner
  data:
    - secretKey: DB_PASSWORD
      remoteRef:
        key: prod/api/db
        property: password
    - secretKey: DB_USER
      remoteRef:
        key: prod/api/db
        property: username

refreshInterval: 1h membuat controller menarik nilai terbaru dari backend secara berkala — rotasi di backend akan tersinkron ke cluster tanpa intervensi. Periksa statusnya dengan kubectl get externalsecrets -n apps dan lihat kolom SYNCED.

Integrasi ESO dengan Flux

Tidak ada yang istimewa secara teknis — justru itulah keuntungannya. ESO sendiri diinstal lewat HelmRelease, dan semua CRD-nya (ClusterSecretStore, ExternalSecret, termasuk Secret kredensial yang bisa dienkripsi SOPS) dideklarasikan di Git dan disinkronkan Flux:

  • ESO sebagai HelmRelease: chart external-secrets dideklarasikan di Git bersama HelmRepository-nya.
  • SecretStore di Git: manifest store ditaruh di folder repo; Flux menerapkannya sebelum aplikasi yang memakai secret.
  • Dependency management: urutkan dengan dependsOn di Kustomization — pastikan CRD ESO dan store sudah siap sebelum aplikasi. Gunakan initContainer atau readiness probe bila aplikasi gagal karena secret belum ada.
  • Satu source of truth: secret eksternal tetap di backend, konfigurasi ada di Git, dan Kubernetes Secret dibuat otomatis. Tidak ada duplikasi manual.

Best Practices

  • Siklus hidup secret: gunakan creationPolicy: Owner agar Secret ikut terhapus saat ExternalSecret dihapus, dan deletionPolicy yang sesuai untuk menghindari secret yatim.
  • Access control: beri izin minimal pada kredensial store. Untuk tenant berbeda, pakai SecretStore per namespace alih-alih satu ClusterSecretStore global.
  • Audit logging: aktifkan audit di backend (CloudTrail, Vault audit log) dan review pola akses secara berkala.
  • Rotasi otomatis: andalkan refreshInterval atau event backend; perbarui secret tanpa memodifikasi Git.
  • Hindari nilai dalam kode: aplikasi membaca secret dari Kubernetes Secret biasa, bukan dari environment variable yang hardcoded.

Penutup

Episode ini memperkenalkan pendekatan kedua dalam manajemen secret: daripada menyimpan ciphertext di Git seperti SOPS, ESO menyimpan secret di sistem eksternal dan membuat Kubernetes Secret secara otomatis. Flux mengelola konfigurasinya, ESO mengelola nilainya, dan tidak ada rahasia yang menetap di repo.

Inti yang harus dibawa pulang:

  • Referensi di Git, nilai di eksternal: manifest hanya berisi konfigurasi, bukan rahasia.
  • Tiga CRD inti: SecretStore dan ClusterSecretStore untuk koneksi, ExternalSecret untuk definisi secret.
  • Rotasi jadi otomatis: refreshInterval menyinkronkan perubahan backend ke cluster.
  • Terintegrasi mulus dengan Flux: ESO, store, dan CRD dideklarasikan dan diterapkan lewat Git.
  • Least privilege dan audit: kredensial store dibatasi, akses dipantau.

ESO ideal bila secret sudah ada di sistem terkelola. Tapi tidak semua tim punya Vault atau AWS. Di episode 22 selanjutnya kita belajar Sealed Secrets — alternatif ringan yang tetap memakai Git sebagai tempat penyimpanan secret, dengan enkripsi berbasis kunci publik-privat Bitnami. Sampai jumpa di episode 22!