Files
infrastructure/clusters/cl01tl/manifests/vault/ConfigMap-vault-backup-script.yaml

1453 lines
40 KiB
YAML

apiVersion: v1
kind: ConfigMap
metadata:
name: vault-backup-script
namespace: vault
labels:
app.kubernetes.io/name: vault-backup-script
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
data:
backup.sh: |
echo " ";
echo ">> Running S3 backup for Vault snapshot";
OUTPUT=$(s3cmd sync --no-check-certificate -v /opt/backup/* "${BUCKET}/cl01tl/cl01tl-vault-snapshots/" 2>&1)
STATUS=$?
if [ $STATUS -ne 0 ]; then
if echo "$OUTPUT" | grep -q "403 Forbidden"; then
MESSAGE="403 Authentication Error: Your keys are wrong or you don't have permission"
elif echo "$OUTPUT" | grep -q "404 Not Found"; then
MESSAGE="404 Error: The bucket or folder does not exist"
elif echo "$OUTPUT" | grep -q "Connection refused"; then
MESSAGE="Network Error: Cannot reach the S3 endpoint"
else
MESSAGE="Unknown Error"
echo " ";
echo ">> Unknown Error, output:"
echo " "
echo "$OUTPUT"
fi
MAX_RETRIES=5
SUCCESS=false
echo " "
echo ">> Sending message to ntfy using curl ..."
echo " "
echo ">> Verifying required commands ..."
for i in $(seq 1 "$MAX_RETRIES"); do
if apk update 2>&1 >/dev/null; then
echo ">> Attempt $i: Repositories are reachable";
SUCCESS=true;
break;
else
echo ">> Attempt $i: Connection failed, retrying in 5 seconds ...";
sleep 5;
fi;
done;
if [ "$SUCCESS" = false ]; then
echo ">> ERROR: Could not connect to apk repositories after $MAX_RETRIES attempts, exiting ...";
exit 1;
fi
if ! command -v curl 2>&1 >/dev/null; then
echo ">> Command curl could not be found, installing";
apk add --no-cache -q curl;
if [ $? -eq 0 ]; then
echo ">> Installation successful";
else
echo ">> Installation failed with exit code $?";
exit 1;
fi;
fi;
echo " "
echo ">> Sending to NTFY ..."
echo ">> Message: $MESSAGE"
HTTP_STATUS=$(curl \
--silent \
--write-out '%{http_code}' \
-H "Authorization: Bearer ${NTFY_TOKEN}" \
-H "X-Priority: 5" \
-H "X-Tags: warning" \
-H "X-Title: Vault Backup Failed for ${TARGET}" \
-d "$MESSAGE" \
${NTFY_ENDPOINT}/${NTFY_TOPIC}
)
echo ">> HTTP Status Code: $HTTP_STATUS"
else
echo " ";
echo ">> S3 Sync succeeded"
fi
---
apiVersion: v1
kind: ConfigMap
metadata:
name: vault-config
namespace: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
data:
extraconfig-from-values.hcl: |-
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
telemetry {
unauthenticated_metrics_access = "true"
}
}
storage "raft" {
path = "/vault/data"
retry_join {
leader_api_addr = "http://vault-0.vault-internal:8200"
}
retry_join {
leader_api_addr = "http://vault-1.vault-internal:8200"
}
retry_join {
leader_api_addr = "http://vault-2.vault-internal:8200"
}
}
service_registration "kubernetes" {}
telemetry {
prometheus_retention_time = "30s"
disable_hostname = true
}
disable_mlock = true
---
apiVersion: v1
kind: ConfigMap
metadata:
name: vault-snapshot-script
namespace: vault
labels:
app.kubernetes.io/name: vault-snapshot-script
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
data:
snapshot.sh: |
DATE=$(date +"%Y%m%d-%H-%M")
MAX_RETRIES=5
SUCCESS=false
echo " "
echo ">> Running Vault Snapshot Script ..."
echo " "
echo ">> Verifying required commands ..."
echo " "
for i in $(seq 1 "$MAX_RETRIES"); do
if apk update 2>&1 >/dev/null; then
echo ">> Attempt $i: Repositories are reachable";
SUCCESS=true;
break;
else
echo ">> Attempt $i: Connection failed, retrying in 5 seconds ...";
sleep 5;
fi;
done;
if [ "$SUCCESS" = false ]; then
echo ">> ERROR: Could not connect to apk repositories after $MAX_RETRIES attempts, exiting ...";
exit 1;
fi
echo " "
if ! command -v jq 2>&1 >/dev/null; then
echo ">> Command jq could not be found, installing";
apk add --no-cache -q jq;
if [ $? -eq 0 ]; then
echo ">> Installation successful";
else
echo ">> Installation failed with exit code $?";
exit 1;
fi;
fi;
echo " ";
echo ">> Fetching Vault token ...";
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);
echo " ";
echo ">> Taking Vault snapsot ...";
vault operator raft snapshot save /opt/backup/vault-snapshot-$DATE.snap
echo " ";
echo ">> Setting ownership of Vault snapsot ...";
chown 100:1000 /opt/backup/vault-snapshot-$DATE.snap
echo " ";
echo ">> Completed Vault snapshot";
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: vault-snapshot
labels:
app.kubernetes.io/controller: snapshot
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: vault
helm.sh/chart: snapshot-4.6.2
namespace: vault
spec:
suspend: false
concurrencyPolicy: Forbid
startingDeadlineSeconds: 90
timeZone: US/Central
schedule: "0 4 * * *"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 3
jobTemplate:
spec:
parallelism: 1
backoffLimit: 3
template:
metadata:
labels:
app.kubernetes.io/controller: snapshot
app.kubernetes.io/instance: vault
app.kubernetes.io/name: vault
spec:
enableServiceLinks: false
serviceAccountName: default
automountServiceAccountToken: true
hostIPC: false
hostNetwork: false
hostPID: false
dnsPolicy: ClusterFirst
restartPolicy: Never
initContainers:
- args:
- -ec
- /scripts/snapshot.sh
command:
- /bin/ash
env:
- name: VAULT_ADDR
value: http://vault-active.vault.svc.cluster.local:8200
envFrom:
- secretRef:
name: vault-snapshot-agent-token
image: hashicorp/vault:1.21.4
imagePullPolicy: IfNotPresent
name: snapshot
volumeMounts:
- mountPath: /opt/backup
name: backup
- mountPath: /scripts/snapshot.sh
name: snapshot-script
subPath: snapshot.sh
containers:
- args:
- -ec
- /scripts/backup.sh
command:
- /bin/sh
env:
- name: BUCKET
valueFrom:
secretKeyRef:
key: BUCKET
name: vault-s3cmd-external-config
- name: TARGET
value: External
envFrom:
- secretRef:
name: vault-backup-ntfy-secret
image: d3fk/s3cmd:latest@sha256:a41234c2b43d6cfa0d51c9523a2d7925f7f21297a41d69932946c3e364d32b5e
imagePullPolicy: IfNotPresent
name: s3-backup-external
volumeMounts:
- mountPath: /opt/backup
name: backup
- mountPath: /scripts/backup.sh
name: backup-script
subPath: backup.sh
- mountPath: /root/.s3cfg
mountPropagation: None
name: s3cmd-external-config
readOnly: true
subPath: .s3cfg
- args:
- -ec
- /scripts/backup.sh
command:
- /bin/sh
env:
- name: BUCKET
valueFrom:
secretKeyRef:
key: BUCKET
name: vault-s3cmd-local-config
- name: TARGET
value: Local
envFrom:
- secretRef:
name: vault-backup-ntfy-secret
image: d3fk/s3cmd:latest@sha256:a41234c2b43d6cfa0d51c9523a2d7925f7f21297a41d69932946c3e364d32b5e
imagePullPolicy: IfNotPresent
name: s3-backup-local
volumeMounts:
- mountPath: /opt/backup
name: backup
- mountPath: /scripts/backup.sh
name: backup-script
subPath: backup.sh
- mountPath: /root/.s3cfg
mountPropagation: None
name: s3cmd-local-config
readOnly: true
subPath: .s3cfg
- args:
- -ec
- /scripts/backup.sh
command:
- /bin/sh
env:
- name: BUCKET
valueFrom:
secretKeyRef:
key: BUCKET
name: vault-s3cmd-remote-config
- name: TARGET
value: Remote
envFrom:
- secretRef:
name: vault-backup-ntfy-secret
image: d3fk/s3cmd:latest@sha256:a41234c2b43d6cfa0d51c9523a2d7925f7f21297a41d69932946c3e364d32b5e
imagePullPolicy: IfNotPresent
name: s3-backup-remote
volumeMounts:
- mountPath: /opt/backup
name: backup
- mountPath: /scripts/backup.sh
name: backup-script
subPath: backup.sh
- mountPath: /root/.s3cfg
mountPropagation: None
name: s3cmd-remote-config
readOnly: true
subPath: .s3cfg
volumes:
- name: backup
persistentVolumeClaim:
claimName: vault-storage-backup
- configMap:
defaultMode: 493
name: vault-backup-script
name: backup-script
- name: s3cmd-external-config
secret:
secretName: vault-s3cmd-external-config
- name: s3cmd-local-config
secret:
secretName: vault-s3cmd-local-config
- name: s3cmd-remote-config
secret:
secretName: vault-s3cmd-remote-config
- configMap:
defaultMode: 493
name: vault-snapshot-script
name: snapshot-script
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vault-unseal-unseal-1
labels:
app.kubernetes.io/controller: unseal-1
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: vault
helm.sh/chart: unseal-4.6.2
namespace: vault
spec:
revisionHistoryLimit: 3
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/controller: unseal-1
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
template:
metadata:
labels:
app.kubernetes.io/controller: unseal-1
app.kubernetes.io/instance: vault
app.kubernetes.io/name: vault
spec:
enableServiceLinks: false
serviceAccountName: default
automountServiceAccountToken: true
hostIPC: false
hostNetwork: false
hostPID: false
dnsPolicy: ClusterFirst
containers:
- envFrom:
- secretRef:
name: vault-unseal-config-1
image: ghcr.io/lrstanley/vault-unseal:0.7.2
imagePullPolicy: IfNotPresent
name: main
resources:
requests:
cpu: 10m
memory: 24Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vault-unseal-unseal-2
labels:
app.kubernetes.io/controller: unseal-2
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: vault
helm.sh/chart: unseal-4.6.2
namespace: vault
spec:
revisionHistoryLimit: 3
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/controller: unseal-2
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
template:
metadata:
labels:
app.kubernetes.io/controller: unseal-2
app.kubernetes.io/instance: vault
app.kubernetes.io/name: vault
spec:
enableServiceLinks: false
serviceAccountName: default
automountServiceAccountToken: true
hostIPC: false
hostNetwork: false
hostPID: false
dnsPolicy: ClusterFirst
containers:
- envFrom:
- secretRef:
name: vault-unseal-config-2
image: ghcr.io/lrstanley/vault-unseal:0.7.2
imagePullPolicy: IfNotPresent
name: main
resources:
requests:
cpu: 10m
memory: 24Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vault-unseal-unseal-3
labels:
app.kubernetes.io/controller: unseal-3
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: vault
helm.sh/chart: unseal-4.6.2
namespace: vault
spec:
revisionHistoryLimit: 3
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/controller: unseal-3
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
template:
metadata:
labels:
app.kubernetes.io/controller: unseal-3
app.kubernetes.io/instance: vault
app.kubernetes.io/name: vault
spec:
enableServiceLinks: false
serviceAccountName: default
automountServiceAccountToken: true
hostIPC: false
hostNetwork: false
hostPID: false
dnsPolicy: ClusterFirst
containers:
- envFrom:
- secretRef:
name: vault-unseal-config-3
image: ghcr.io/lrstanley/vault-unseal:0.7.2
imagePullPolicy: IfNotPresent
name: main
resources:
requests:
cpu: 10m
memory: 24Mi
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-backup-ntfy-secret
namespace: vault
labels:
app.kubernetes.io/name: vault-backup-ntfy-secret
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: NTFY_TOKEN
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /ntfy/user/cl01tl
metadataPolicy: None
property: token
- secretKey: NTFY_ENDPOINT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /ntfy/user/cl01tl
metadataPolicy: None
property: endpoint
- secretKey: NTFY_TOPIC
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/snapshot
metadataPolicy: None
property: NTFY_TOPIC
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-s3cmd-external-config
namespace: vault
labels:
app.kubernetes.io/name: vault-s3cmd-external-config
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: .s3cfg
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/vault-backup
metadataPolicy: None
property: s3cfg
- secretKey: BUCKET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /digital-ocean/home-infra/vault-backup
metadataPolicy: None
property: BUCKET
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-s3cmd-local-config
namespace: vault
labels:
app.kubernetes.io/name: vault-s3cmd-local-config
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: .s3cfg
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/vault-backups
metadataPolicy: None
property: s3cfg-local
- secretKey: BUCKET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/vault-backups
metadataPolicy: None
property: BUCKET
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-s3cmd-remote-config
namespace: vault
labels:
app.kubernetes.io/name: vault-s3cmd-remote-config
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: .s3cfg
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/vault-backups
metadataPolicy: None
property: s3cfg-remote
- secretKey: BUCKET
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /garage/home-infra/vault-backups
metadataPolicy: None
property: BUCKET
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-snapshot-agent-token
namespace: vault
labels:
app.kubernetes.io/name: vault-snapshot-agent-token
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: VAULT_APPROLE_ROLE_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/snapshot
metadataPolicy: None
property: VAULT_APPROLE_ROLE_ID
- secretKey: VAULT_APPROLE_SECRET_ID
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/snapshot
metadataPolicy: None
property: VAULT_APPROLE_SECRET_ID
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-token
namespace: vault
labels:
app.kubernetes.io/name: vault-token
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
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
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-unseal-config-1
namespace: vault
labels:
app.kubernetes.io/name: vault-unseal-config-1
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ENVIRONMENT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: ENVIRONMENT
- secretKey: CHECK_INTERVAL
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: CHECK_INTERVAL
- secretKey: MAX_CHECK_INTERVAL
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: MAX_CHECK_INTERVAL
- secretKey: NODES
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: NODES
- secretKey: TLS_SKIP_VERIFY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: TLS_SKIP_VERIFY
- secretKey: TOKENS
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: TOKENS
- secretKey: EMAIL_ENABLED
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: EMAIL_ENABLED
- secretKey: NOTIFY_MAX_ELAPSED
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: NOTIFY_MAX_ELAPSED
- secretKey: NOTIFY_QUEUE_DELAY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-1
metadataPolicy: None
property: NOTIFY_QUEUE_DELAY
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-unseal-config-2
namespace: vault
labels:
app.kubernetes.io/name: vault-unseal-config-2
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ENVIRONMENT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: ENVIRONMENT
- secretKey: CHECK_INTERVAL
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: CHECK_INTERVAL
- secretKey: MAX_CHECK_INTERVAL
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: MAX_CHECK_INTERVAL
- secretKey: NODES
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: NODES
- secretKey: TLS_SKIP_VERIFY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: TLS_SKIP_VERIFY
- secretKey: TOKENS
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: TOKENS
- secretKey: EMAIL_ENABLED
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: EMAIL_ENABLED
- secretKey: NOTIFY_MAX_ELAPSED
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: NOTIFY_MAX_ELAPSED
- secretKey: NOTIFY_QUEUE_DELAY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-2
metadataPolicy: None
property: NOTIFY_QUEUE_DELAY
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vault-unseal-config-3
namespace: vault
labels:
app.kubernetes.io/name: vault-unseal-config-3
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
secretStoreRef:
kind: ClusterSecretStore
name: vault
data:
- secretKey: ENVIRONMENT
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: ENVIRONMENT
- secretKey: CHECK_INTERVAL
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: CHECK_INTERVAL
- secretKey: MAX_CHECK_INTERVAL
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: MAX_CHECK_INTERVAL
- secretKey: NODES
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: NODES
- secretKey: TLS_SKIP_VERIFY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: TLS_SKIP_VERIFY
- secretKey: TOKENS
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: TOKENS
- secretKey: EMAIL_ENABLED
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: EMAIL_ENABLED
- secretKey: NOTIFY_MAX_ELAPSED
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: NOTIFY_MAX_ELAPSED
- secretKey: NOTIFY_QUEUE_DELAY
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /cl01tl/vault/unseal/config-3
metadataPolicy: None
property: NOTIFY_QUEUE_DELAY
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vault
namespace: vault
labels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: traefik-gateway
namespace: traefik
hostnames:
- vault.alexlebens.net
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ''
kind: Service
name: vault-active
port: 8200
weight: 100
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vault-tailscale
namespace: vault
labels:
app.kubernetes.io/name: vault-tailscale
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
tailscale.com/proxy-class: no-metrics
annotations:
tailscale.com/experimental-forward-cluster-traffic-via-ingress: "true"
spec:
ingressClassName: tailscale
tls:
- hosts:
- vault-cl01tl
secretName: vault-cl01tl
rules:
- host: vault-cl01tl
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vault-active
port:
number: 8200
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vault-storage-backup
namespace: vault
labels:
app.kubernetes.io/name: vault-storage-backup
app.kubernetes.io/instance: vault
app.kubernetes.io/part-of: vault
spec:
volumeMode: Filesystem
storageClassName: ceph-filesystem
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: vault-server-test
namespace: vault
annotations:
"helm.sh/hook": test
spec:
containers:
- name: vault-server-test
image: hashicorp/vault:1.21.4
imagePullPolicy: IfNotPresent
env:
- name: VAULT_ADDR
value: http://vault.vault.svc:8200
command:
- /bin/sh
- -c
- |
echo "Checking for sealed info in 'vault status' output"
ATTEMPTS=10
n=0
until [ "$n" -ge $ATTEMPTS ]
do
echo "Attempt" $n...
vault status -format yaml | grep -E '^sealed: (true|false)' && break
n=$((n+1))
sleep 5
done
if [ $n -ge $ATTEMPTS ]; then
echo "timed out looking for sealed info in 'vault status' output"
exit 1
fi
exit 0
volumeMounts:
- mountPath: /opt/backups/
name: vault-storage-backup
readOnly: false
volumes:
- name: vault-storage-backup
persistentVolumeClaim:
claimName: vault-storage-backup
restartPolicy: Never
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: vault
namespace: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
spec:
maxUnavailable: 1
selector:
matchLabels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
component: server
---
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
release: prometheus
spec:
groups:
- name: vault
rules:
- alert: vault-HighResponseTime
annotations:
message: The response time of Vault is over 500ms on average over the last 5 minutes.
expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 500
for: 5m
labels:
severity: warning
- alert: vault-HighResponseTime
annotations:
message: The response time of Vault is over 1s on average over the last 5 minutes.
expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 1000
for: 5m
labels:
severity: critical
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: vault
name: vault-discovery-role
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: vault-discovery-rolebinding
namespace: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: vault-discovery-role
subjects:
- kind: ServiceAccount
name: vault
namespace: vault
---
apiVersion: v1
kind: Service
metadata:
name: vault-active
namespace: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
vault-active: "true"
annotations:
spec:
type: ClusterIP
publishNotReadyAddresses: true
ports:
- name: http
port: 8200
targetPort: 8200
- name: https-internal
port: 8201
targetPort: 8201
selector:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
component: server
vault-active: "true"
---
apiVersion: v1
kind: Service
metadata:
name: vault-internal
namespace: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
vault-internal: "true"
annotations:
spec:
clusterIP: None
publishNotReadyAddresses: true
ports:
- name: "http"
port: 8200
targetPort: 8200
- name: https-internal
port: 8201
targetPort: 8201
selector:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
component: server
---
apiVersion: v1
kind: Service
metadata:
name: vault-ui
namespace: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault-ui
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
spec:
selector:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
component: server
publishNotReadyAddresses: true
ports:
- name: http
port: 8200
targetPort: 8200
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: vault
namespace: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
annotations:
spec:
type: ClusterIP
publishNotReadyAddresses: true
ports:
- name: http
port: 8200
targetPort: 8200
- name: https-internal
port: 8201
targetPort: 8201
selector:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
component: server
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault
namespace: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: vault
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
release: prometheus
spec:
selector:
matchLabels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
vault-active: "true"
endpoints:
- port: http
interval: 30s
scrapeTimeout: 10s
scheme: http
path: /v1/sys/metrics
params:
format:
- prometheus
tlsConfig:
insecureSkipVerify: true
namespaceSelector:
matchNames:
- vault
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: vault
namespace: vault
labels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
app.kubernetes.io/managed-by: Helm
spec:
serviceName: vault-internal
podManagementPolicy: Parallel
replicas: 3
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
component: server
template:
metadata:
labels:
helm.sh/chart: vault-0.32.0
app.kubernetes.io/name: vault
app.kubernetes.io/instance: vault
component: server
annotations:
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app.kubernetes.io/name: vault
app.kubernetes.io/instance: "vault"
component: server
topologyKey: kubernetes.io/hostname
terminationGracePeriodSeconds: 10
serviceAccountName: vault
securityContext:
runAsNonRoot: true
runAsGroup: 1000
runAsUser: 100
fsGroup: 1000
hostNetwork: false
volumes:
- name: config
configMap:
name: vault-config
- name: vault-storage-backup
persistentVolumeClaim:
claimName: vault-storage-backup
- name: home
emptyDir: {}
containers:
- name: vault
resources:
requests:
cpu: 50m
memory: 512Mi
image: hashicorp/vault:1.21.4
imagePullPolicy: IfNotPresent
command:
- "/bin/sh"
- "-ec"
args:
- "cp /vault/config/extraconfig-from-values.hcl /tmp/storageconfig.hcl;\n[ -n \"${HOST_IP}\" ] && sed -Ei \"s|HOST_IP|${HOST_IP?}|g\" /tmp/storageconfig.hcl;\n[ -n \"${POD_IP}\" ] && sed -Ei \"s|POD_IP|${POD_IP?}|g\" /tmp/storageconfig.hcl;\n[ -n \"${HOSTNAME}\" ] && sed -Ei \"s|HOSTNAME|${HOSTNAME?}|g\" /tmp/storageconfig.hcl;\n[ -n \"${API_ADDR}\" ] && sed -Ei \"s|API_ADDR|${API_ADDR?}|g\" /tmp/storageconfig.hcl;\n[ -n \"${TRANSIT_ADDR}\" ] && sed -Ei \"s|TRANSIT_ADDR|${TRANSIT_ADDR?}|g\" /tmp/storageconfig.hcl;\n[ -n \"${RAFT_ADDR}\" ] && sed -Ei \"s|RAFT_ADDR|${RAFT_ADDR?}|g\" /tmp/storageconfig.hcl;\n/usr/local/bin/docker-entrypoint.sh vault server -config=/tmp/storageconfig.hcl \n"
securityContext:
allowPrivilegeEscalation: false
env:
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: VAULT_K8S_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: VAULT_K8S_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: VAULT_ADDR
value: "http://127.0.0.1:8200"
- name: VAULT_API_ADDR
value: "http://$(POD_IP):8200"
- name: SKIP_CHOWN
value: "true"
- name: SKIP_SETCAP
value: "true"
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: VAULT_CLUSTER_ADDR
value: "https://$(HOSTNAME).vault-internal:8201"
- name: HOME
value: "/home/vault"
- name: VAULT_LOG_LEVEL
value: "debug"
- name: VAULT_LOG_FORMAT
value: "standard"
volumeMounts:
- name: data
mountPath: /vault/data
- name: config
mountPath: /vault/config
- mountPath: /opt/backups/
name: vault-storage-backup
readOnly: false
- name: home
mountPath: /home/vault
ports:
- containerPort: 8200
name: http
- containerPort: 8201
name: https-internal
- containerPort: 8202
name: http-rep
readinessProbe:
exec:
command: ["/bin/sh", "-ec", "vault status -tls-skip-verify"]
failureThreshold: 2
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 3
lifecycle:
preStop:
exec:
command:
- "/bin/sh"
- "-c"
- "sleep 5 && kill -SIGTERM $(pidof vault)"
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi