diff --git a/clusters/cl01tl/platform/vault/Chart.yaml b/clusters/cl01tl/platform/vault/Chart.yaml index e86fe9a08..ca9b02f02 100644 --- a/clusters/cl01tl/platform/vault/Chart.yaml +++ b/clusters/cl01tl/platform/vault/Chart.yaml @@ -16,5 +16,13 @@ dependencies: - name: vault version: 0.28.0 repository: https://helm.releases.hashicorp.com + - name: app-template + alias: snapshot + repository: https://bjw-s.github.io/helm-charts/ + version: 3.2.1 + - name: app-template + alias: vault-unseal + repository: https://bjw-s.github.io/helm-charts/ + version: 3.2.1 icon: https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/vault.png appVersion: 1.17.0 diff --git a/clusters/cl01tl/platform/vault/templates/cron-job.yaml b/clusters/cl01tl/platform/vault/templates/cron-job.yaml deleted file mode 100644 index 04a89e7f6..000000000 --- a/clusters/cl01tl/platform/vault/templates/cron-job.yaml +++ /dev/null @@ -1,64 +0,0 @@ -apiVersion: batch/v1 -kind: CronJob -metadata: - name: vault-snapshot-cronjob - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: vault-snapshot-cronjob - app.kubernetes.io/instance: {{ .Release.Name }} - app.kubernetes.io/version: {{ .Chart.AppVersion }} - app.kubernetes.io/component: storage - app.kubernetes.io/part-of: {{ .Release.Name }} -spec: - schedule: "@every 24h" - successfulJobsHistoryLimit: 3 - failedJobsHistoryLimit: 3 - jobTemplate: - spec: - template: - spec: - restartPolicy: OnFailure - containers: - - name: snapshot - image: hashicorp/vault:1.16.2 - imagePullPolicy: IfNotPresent - command: - - /bin/ash - args: - - -ec - - | - apk add --no-cache jq; - export VAULT_TOKEN=$(vault write auth/approle/login role_id=$VAULT_APPROLE_ROLE_ID secret_id=$VAULT_APPROLE_SECRET_ID -format=json | jq -r .auth.client_token); - vault operator raft snapshot save /opt/backup/vault-snapshot-latest.snap; - cp /opt/backup/vault-snapshot-latest.snap /opt/backup/vault-snapshot-$(date +"%Y%m%d-%H-%M").snap; - cp /opt/backup/vault-snapshot-latest.snap /opt/backup/vault-snapshot-s3.snap; - envFrom: - - secretRef: - name: vault-snapshot-agent-token - env: - - name: VAULT_ADDR - value: http://vault-active.vault.svc.cluster.local:8200 - volumeMounts: - - mountPath: /opt/backup - name: backup - - name: upload - image: amazon/aws-cli:2.15.42 - imagePullPolicy: IfNotPresent - command: - - /bin/sh - args: - - -ec - - | - until [ -f /opt/backup/vault-snapshot-s3.snap ]; do sleep 5; done; - aws s3 cp /opt/backup/vault-snapshot-s3.snap s3://cl01tl-vault-snapshots/vault-snapshot-$(date +"%Y%m%d-%H-%M").snap; - rm /opt/backup/vault-snapshot-s3.snap; - envFrom: - - secretRef: - name: vault-snapshot-s3 - volumeMounts: - - mountPath: /opt/backup - name: backup - volumes: - - name: backup - persistentVolumeClaim: - claimName: vault-nfs-storage-backup diff --git a/clusters/cl01tl/platform/vault/templates/external-secret.yaml b/clusters/cl01tl/platform/vault/templates/external-secret.yaml new file mode 100644 index 000000000..09dc2c517 --- /dev/null +++ b/clusters/cl01tl/platform/vault/templates/external-secret.yaml @@ -0,0 +1,243 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vault-snapshot-agent-token + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-snapshot-agent-token + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: snapshot + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: VAULT_APPROLE_ROLE_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/snapshot/approle + metadataPolicy: None + property: role-id + - secretKey: VAULT_APPROLE_SECRET_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/snapshot/approle + metadataPolicy: None + property: secret-id + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vault-snapshot-s3 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-snapshot-s3 + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: snapshot + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: AWS_ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/approle/job + metadataPolicy: None + property: AWS_ACCESS_KEY_ID + - secretKey: AWS_DEFAULT_REGION + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/approle/job + metadataPolicy: None + property: AWS_DEFAULT_REGION + - secretKey: AWS_ENDPOINT_URL + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/approle/job + metadataPolicy: None + property: AWS_ENDPOINT_URL + - secretKey: AWS_SECRET_ACCESS_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/approle/job + metadataPolicy: None + property: AWS_SECRET_ACCESS_KEY + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vault-unseal-agent-token + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-unseal-agent-token + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: unseal + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: VAULT_APPROLE_ROLE_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/unseal/approle + metadataPolicy: None + property: role-id + - secretKey: VAULT_APPROLE_SECRET_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/unseal/approle + metadataPolicy: None + property: secret-id + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vault-unseal-config-1 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-unseal-key-1 + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: unseal + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: vault-unseal.yaml + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/unseal/config + metadataPolicy: None + property: vault-unseal.yaml-1 + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vault-unseal-config-2 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-unseal-key-2 + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: unseal + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: vault-unseal.yaml + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/unseal/config + metadataPolicy: None + property: vault-unseal.yaml-2 + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vault-unseal-config-3 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-unseal-config-3 + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: unseal + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: vault-unseal.yaml + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/unseal/config + metadataPolicy: None + property: vault-unseal.yaml-3 + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: vault-token + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: vault-token + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: token + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: token + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/token + metadataPolicy: None + property: token + - secretKey: unseal_key_1 + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/token + metadataPolicy: None + property: unseal_key_1 + - secretKey: unseal_key_2 + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/token + metadataPolicy: None + property: unseal_key_2 + - secretKey: unseal_key_3 + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/token + metadataPolicy: None + property: unseal_key_3 + - secretKey: unseal_key_4 + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/token + metadataPolicy: None + property: unseal_key_4 + - secretKey: unseal_key_5 + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/vault/token + metadataPolicy: None + property: unseal_key_5 diff --git a/clusters/cl01tl/platform/vault/values.yaml b/clusters/cl01tl/platform/vault/values.yaml index 557a0b3da..2c8885fe6 100644 --- a/clusters/cl01tl/platform/vault/values.yaml +++ b/clusters/cl01tl/platform/vault/values.yaml @@ -18,7 +18,7 @@ vault: logFormat: standard resources: requests: - cpu: 100m + cpu: 100m memory: 256Mi ingress: enabled: true @@ -165,3 +165,154 @@ vault: for: 5m labels: severity: critical +snapshot: + controllers: + main: + type: cronjob + cronjob: + suspend: false + concurrencyPolicy: Forbid + timeZone: US/Central + schedule: "@every 24h" + startingDeadlineSeconds: 90 + successfulJobsHistory: 3 + failedJobsHistory: 3 + backoffLimit: 3 + parallelism: 1 + containers: + snapshot: + image: + repository: hashicorp/vault + tag: 1.16.2 + pullPolicy: IfNotPresent + command: + - /bin/ash + args: + - -ec + - | + apk add --no-cache jq; + export VAULT_TOKEN=$(vault write auth/approle/login role_id=$VAULT_APPROLE_ROLE_ID secret_id=$VAULT_APPROLE_SECRET_ID -format=json | jq -r .auth.client_token); + vault operator raft snapshot save /opt/backup/vault-snapshot-latest.snap; + cp /opt/backup/vault-snapshot-latest.snap /opt/backup/vault-snapshot-$(date +"%Y%m%d-%H-%M").snap; + cp /opt/backup/vault-snapshot-latest.snap /opt/backup/vault-snapshot-s3.snap; + envFrom: + - secretRef: + name: vault-snapshot-agent-token + env: + - name: VAULT_ADDR + value: http://vault-active.vault.svc.cluster.local:8200 + resources: + requests: + cpu: 100m + memory: 128Mi + backup: + image: + repository: amazon/aws-cli + tag: 2.15.42 + pullPolicy: IfNotPresent + command: + - /bin/sh + args: + - -ec + - | + until [ -f /opt/backup/vault-snapshot-s3.snap ]; do sleep 5; done; + aws s3 cp /opt/backup/vault-snapshot-s3.snap s3://cl01tl-vault-snapshots/vault-snapshot-$(date +"%Y%m%d-%H-%M").snap; + rm /opt/backup/vault-snapshot-s3.snap; + envFrom: + - secretRef: + name: vault-snapshot-s3 + resources: + requests: + cpu: 100m + memory: 128Mi + serviceAccount: + create: true + persistence: + config: + existingClaim: vault-nfs-storage-backup + advancedMounts: + main: + snapshot: + - path: /opt/backup + readOnly: false + backup: + - path: /opt/backup + readOnly: false +vault-unseal: + controllers: + main: + type: cronjob + cronjob: + suspend: false + concurrencyPolicy: Allow + timeZone: US/Central + schedule: "0 * * * *" + startingDeadlineSeconds: 90 + successfulJobsHistory: 3 + failedJobsHistory: 3 + backoffLimit: 3 + parallelism: 3 + containers: + unseal-1: + image: + repository: ghcr.io/lrstanley/vault-unseal + tag: 0.5.1 + pullPolicy: IfNotPresent + resources: + requests: + cpu: 100m + memory: 128Mi + unseal-2: + image: + repository: ghcr.io/lrstanley/vault-unseal + tag: 0.5.1 + pullPolicy: IfNotPresent + resources: + requests: + cpu: 100m + memory: 128Mi + unseal-3: + image: + repository: ghcr.io/lrstanley/vault-unseal + tag: 0.5.1 + pullPolicy: IfNotPresent + resources: + requests: + cpu: 100m + memory: 128Mi + serviceAccount: + create: true + persistence: + config-1: + enabled: true + type: configMap + name: vault-unseal-config-1 + advancedMounts: + main: + unseal-1: + - path: /etc/vault-unseal.yaml + readOnly: true + mountPropagation: None + subPath: vault-unseal.yaml + config-2: + enabled: true + type: configMap + name: vault-unseal-config-2 + advancedMounts: + main: + unseal-2: + - path: /etc/vault-unseal.yaml + readOnly: true + mountPropagation: None + subPath: vault-unseal.yaml + config-3: + enabled: true + type: configMap + name: vault-unseal-config-3 + advancedMounts: + main: + unseal-3: + - path: /etc/vault-unseal.yaml + readOnly: true + mountPropagation: None + subPath: vault-unseal.yaml