[Sebuah Cerita Tentang Implementasi GitOps] - Management Secret Dengan Vault dan ArgoCD

February 02, 2023

[Sebuah Cerita Tentang Implementasi GitOps] - Management Secret Dengan Vault dan ArgoCD

Ketika menggunakan repository sebagai media penyimpanan deployment files, maka tantangan yang dihadapi adalah management sensitif data pada deployment tersebut


Latar belakang

Ketika akan melakukan implementasi GitOps di kubernetes (Menggunakan Git sebagai tempat penyimpanan Manifest dari resources Kubernetes) maka melakukan management sensitif data perlu dilakukan dengan rapihh~~~, menuliskan sensitif data secara telanjang pada Git Repo yang digunakan sebagai pusat operation kita adalah sesuatu yang kurang etis.

Masalah

Untuk dapat melakukan management resource Kind=Secret pada kubernetes bisa dihandle dengan sangat cantik oleh CustomResoureDefintion dari External Secrets Operator, namun terkadang konfidensial data perlu juga diletakkan pada resources lain selain seperti ConfigMaps atau resources lainnya, sayangnya hal tersebut tidak disupport oleh external-secrets operator.

ESO Desing

  • Contoh keperluan confidential data di resources selain secret.

initsql dari resources

External Secret Operator

Pros Cons
There's some schedule RefreshInterval by design Only support Kind=Secret resources
More mature project also more wide comunity
Multiple namespace management secret by design

ArgoCD Vault Plugin

Pros Cons
Handle all resources k8s Required hard refresh the application, if we want to pull new values from vault
ArgoCD Ecosystem Required third party tools like relector or create multi application in all wanted namespace where resources going to deploy

Pilih Solusi Sesuai Kebutuhan

Apabila tidak ada keperluan konfidensial data di luar Kind=Secret maka Externalsecret.io operator adalah piliahan paling cantik.

External Secret Operator

Penggunaan External Secret secara sederhana seperti menifest dibawah. Secret tersebut akan terbuat di namespace yang memiliki label eso=test External Secret Cluster

ArgoCD Vault Plugin

Untuk argocd-vault-plugin, tools tersebut akan dipasang sebagai plugin dari argocd. Setiap saat sebuah manifests akan di-render maka command tersebut bisa dijalankan.

Lakukan penyesuaian pada Deployment argocd-repo-server kita pada beberapa bagian.

  • Menambahkan initContainer.
  • Menambahkan sidecar container.
  • Melakukan Mounting ServiceAccountToken.
  • Menambah clusterrolebinding di untuk SA argocd-repo-server.

1. Create backend configruation

Di sini backend saya menggunakan Vault dari Hascicorp dan menggunakan metode autentifikasi github token.

apiVersion: v1
stringData:
  VAULT_ADDR: http://vault.myvaultserver.com
  AVP_AUTH_TYPE: github
  AVP_GITHUB_TOKEN: t0ke3nsecret
  AVP_TYPE: vault
kind: Secret
metadata:
  name: argocd-vault-plugin-credentials
  namespace: argocd
type: Opaque

2. InitContainer - Download binary argocd-vault-plugin

# Download tools
initContainers:
- name: download-tools
image: registry.access.redhat.com/ubi8
env:
  - name: AVP_VERSION
    value: 1.11.0
command: [sh, -c]
args:
  - >-
    curl -L https://github.com/argoproj-labs/argocd-vault-plugin/releases/download/v$(AVP_VERSION)/argocd-vault-plugin_$(AVP_VERSION)_linux_amd64 -o argocd-vault-plugin &&
    chmod +x argocd-vault-plugin &&
    mv argocd-vault-plugin /custom-tools/
volumeMounts:
  - mountPath: /custom-tools
    name: custom-tools
volumes:
- configMap:
    name: cmp-plugin
  name: cmp-plugin
- name: custom-tools
  emptyDir: {}

3. Configure argocd-repo-server Container

Add backend Secret to Environment Variables in argocd-repo-server container, and mount argocd-vault-plugin.

containers:
- name: argocd-repo-server
volumeMounts:
- name: custom-tools
  mountPath: /usr/local/bin/argocd-vault-plugin
  subPath: argocd-vault-plugin        
envFrom:
  - secretRef:
      name: argocd-vault-plugin-credentials

4. Add ClusterRoleBinding

Untuk dapat membaca konfigurasi backend vault yang sudah kita masukkan ke secret argocd-vault-plugin-credentials maka token dari service account argocd-repo-server perlu mendapatkan akses read ke secrets.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: argocd-vault
rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Secret
  # objects is "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
  name: read-secrets-argocd-repo-server
subjects:
- kind: ServiceAccount
  name: argocd-repo-server
  namespace: argocd
roleRef:
  kind: ClusterRole
  name: argocd-vault
  apiGroup: rbac.authorization.k8s.io

5. Mounting ServiceAccountToken

apiVersion: apps/v1
kind: Deployment
metadata:
  name: argocd-repo-server
spec:
  template:
    spec:
      serviceAccount: argocd-repo-server
      serviceAccountName: argocd-repo-server
      automountServiceAccountToken: true

6. Buat konfigurasi plugin argo-cd

YAML berikut bukanlah resources dari kubernetes, namun syntax dari Plugin argo-cd yang mengikuti rules dari Kubernetes YAML.

Plugin ini hanya akan berjalan apabila terdapat file ./kustomization.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: cmp-plugin
data:
  avp-kustomize.yaml: |
    ---
    apiVersion: argoproj.io/v1alpha1
    kind: ConfigManagementPlugin
    metadata:
      name: argocd-vault-plugin-kustomize
    spec:
      allowConcurrency: true

      # Note: this command is run _before_ anything is done, therefore the logic is to check
      # if this looks like a Kustomize bundle
      discover:
        fileName: "./kustomization.yaml"
      generate:
        command:
          - sh
          - "-c"
          - "kustomize build . |  argocd-vault-plugin generate --secret-name argocd:argocd-vault-plugin-credentials -"
      lockRepo: false
---

7. Tambahkan sidecar container.

Sidecar container ini ditambahkan pada deployment argocd-repo-server.

# argocd-vault-plugin with Kustomize
- name: avp-kustomize
command: [/var/run/argocd/argocd-cmp-server]
image: quay.io/argoproj/argocd:v2.4.0
securityContext:
  runAsNonRoot: true
  runAsUser: 999
volumeMounts:
  - mountPath: /var/run/argocd
    name: var-files
  - mountPath: /home/argocd/cmp-server/plugins
    name: plugins
  - mountPath: /tmp
    name: tmp
  # Register plugins into sidecar
  - mountPath: /home/argocd/cmp-server/config/plugin.yaml
    subPath: avp-kustomize.yaml
    name: cmp-plugin
  # Important: Mount tools into $PATH
  - name: custom-tools
    subPath: argocd-vault-plugin
    mountPath: /usr/local/bin/argocd-vault-plugin

Contoh Penggunaan

  1. Buat Secret baru di hasci vault

Create new secret in Vault

  1. Buat resources secret, dengan annotation avp.kubernets.io/path: "secret/data/test-secret", annotation tersebut menunjukan alamat dari path secret yang akan diambil. Lalu <supper-secret> pada isi stringData secret tersebut menunjukan property key yang harus diambil dari path yang di-define pada annotation.

How to Save the Secret in Repo

  1. Deploy dengan Argocd

Deploy with Argocd

  1. Lihat final Secret

Final Secret

Kekurangan Saat ini

Jika kita menggunakan ArgoCD Plugin dan juga argocd-image-updater maka ada sedikit penyesuaian yang perlu dilakukan pada setiap YAML application, ya itu penambahan annotation writeback target

annotation:
  argocd-image-updater.argoproj.io/write-back-target: kustomization

My Talk at Kubernetes Meetup X BukaMeetup

Referensi


Profile picture

Written by Nicolas Julian Seseorang yang mencoba berkarya. Chit Chat with me in Twitter