NG: secret manager and VW
Update Kubernetes Services Wiki / Generate and Update K8s Wiki (push) Failing after 14m33s
Update Kubernetes Services Wiki / Generate and Update K8s Wiki (push) Failing after 14m33s
This commit is contained in:
1 parent
862a7619e2
commit
cf88753ff5
15 files changed
+533
No files matched your search
@@ -0,0 +1,26 @@
|
||||
FROM debian:sid
|
||||
|
||||
ENV BW_CLI_VERSION=2025.12.1
|
||||
|
||||
RUN apt update && \
|
||||
apt install -y wget unzip && \
|
||||
wget https://github.com/bitwarden/clients/releases/download/cli-v${BW_CLI_VERSION}/bw-linux-${BW_CLI_VERSION}.zip && \
|
||||
unzip bw-linux-${BW_CLI_VERSION}.zip && \
|
||||
chmod +x bw && \
|
||||
mv bw /usr/local/bin/bw && \
|
||||
rm -rfv *.zip && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Build entrypoint script
|
||||
RUN echo '#!/bin/sh\n\
|
||||
set -e\n\
|
||||
bw config server ${BW_HOST}\n\
|
||||
export BW_SESSION=$(bw login ${BW_USER} --passwordenv BW_PASSWORD --raw)\n\
|
||||
bw unlock --check\n\
|
||||
echo "Running \`bw server\` on port 8087"\n\
|
||||
bw serve --hostname 0.0.0.0\n' > /entrypoint.sh && \
|
||||
chmod +x /entrypoint.sh
|
||||
|
||||
CMD ["/entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: external-secrets
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: core
|
||||
destination:
|
||||
namespace: external-secrets
|
||||
server: https://kubernetes.default.svc
|
||||
source:
|
||||
repoURL: https://gt.hexor.cy/ab/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s-ng/external-secrets
|
||||
syncPolicy:
|
||||
automated:
|
||||
selfHeal: true
|
||||
prune: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
@@ -0,0 +1,153 @@
|
||||
# ---
|
||||
# apiVersion: v1
|
||||
# kind: Secret
|
||||
# metadata:
|
||||
# name: bitwarden-cli
|
||||
# namespace: external-secrets
|
||||
# data:
|
||||
# BW_HOST: base64(url)
|
||||
# BW_USERNAME: base64(name)
|
||||
# BW_PASSWORD: base64(pass)
|
||||
# Vaultwarden bot - 81212111-6350-4069-8bcf-19a67d3964a5
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bitwarden-cli
|
||||
labels:
|
||||
reloader.stakater.com/auto: "true"
|
||||
app.kubernetes.io/instance: bitwarden-cli
|
||||
app.kubernetes.io/name: bitwarden-cli
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: bitwarden-cli
|
||||
app.kubernetes.io/instance: bitwarden-cli
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: bitwarden-cli
|
||||
app.kubernetes.io/instance: bitwarden-cli
|
||||
spec:
|
||||
nodeSelector:
|
||||
kubernetes.io/arch: amd64
|
||||
containers:
|
||||
- name: bitwarden-cli
|
||||
image: ultradesu/bitwarden-client:2025.12.1
|
||||
imagePullPolicy: Always
|
||||
resources:
|
||||
requests:
|
||||
memory: "128Mi"
|
||||
cpu: "300m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "1000m"
|
||||
env:
|
||||
- name: BW_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: bitwarden-cli
|
||||
key: BW_HOST
|
||||
- name: BW_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: bitwarden-cli
|
||||
key: BW_USERNAME
|
||||
- name: BW_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: bitwarden-cli
|
||||
key: BW_PASSWORD
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8087
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- wget
|
||||
- -q
|
||||
- http://127.0.0.1:8087/sync
|
||||
- --post-data=''
|
||||
initialDelaySeconds: 20
|
||||
failureThreshold: 3
|
||||
timeoutSeconds: 1
|
||||
periodSeconds: 120
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: 8087
|
||||
initialDelaySeconds: 20
|
||||
failureThreshold: 3
|
||||
timeoutSeconds: 1
|
||||
periodSeconds: 10
|
||||
startupProbe:
|
||||
tcpSocket:
|
||||
port: 8087
|
||||
initialDelaySeconds: 10
|
||||
failureThreshold: 30
|
||||
timeoutSeconds: 1
|
||||
periodSeconds: 5
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: bitwarden-cli
|
||||
labels:
|
||||
app.kubernetes.io/instance: bitwarden-cli
|
||||
app.kubernetes.io/name: bitwarden-cli
|
||||
annotations:
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 8087
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app.kubernetes.io/name: bitwarden-cli
|
||||
app.kubernetes.io/instance: bitwarden-cli
|
||||
---
|
||||
kind: NetworkPolicy
|
||||
apiVersion: networking.k8s.io/v1
|
||||
metadata:
|
||||
name: external-secret-2-bw-cli
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: bitwarden-cli
|
||||
app.kubernetes.io/name: bitwarden-cli
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: external-secrets
|
||||
app.kubernetes.io/name: external-secrets
|
||||
|
||||
---
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: vaultwarden-login
|
||||
spec:
|
||||
provider:
|
||||
webhook:
|
||||
url: "http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}"
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
result:
|
||||
jsonPath: "$.data.{{ .remoteRef.property }}"
|
||||
---
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: vaultwarden-fields
|
||||
spec:
|
||||
provider:
|
||||
webhook:
|
||||
url: "http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}"
|
||||
result:
|
||||
jsonPath: "$.data.fields[?@.name==\"{{ .remoteRef.property }}\"].value"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- app.yaml
|
||||
# Enable after the Vaultwarden bot account exists and the bitwarden-cli
|
||||
# secret is created (see the header of bitwarden-store.yaml):
|
||||
# - bitwarden-store.yaml
|
||||
|
||||
helmCharts:
|
||||
- name: external-secrets
|
||||
repo: https://charts.external-secrets.io
|
||||
version: 2.11.0
|
||||
releaseName: external-secrets
|
||||
namespace: external-secrets
|
||||
valuesFile: values.yaml
|
||||
includeCRDs: true
|
||||
@@ -0,0 +1 @@
|
||||
installCRDs: true
|
||||
@@ -0,0 +1,81 @@
|
||||
# Database "vaultwarden": password, role, database and read access for the app.
|
||||
# To add another database copy this file and replace the name.
|
||||
|
||||
# Generated once; the role and the application both read this Secret.
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: vaultwarden-db
|
||||
namespace: psql
|
||||
spec:
|
||||
refreshPolicy: CreatedOnce
|
||||
target:
|
||||
name: vaultwarden-db
|
||||
template:
|
||||
type: kubernetes.io/basic-auth
|
||||
metadata:
|
||||
labels:
|
||||
cnpg.io/reload: "true"
|
||||
data:
|
||||
username: vaultwarden
|
||||
password: "{{ .password }}"
|
||||
dataFrom:
|
||||
- sourceRef:
|
||||
generatorRef:
|
||||
apiVersion: generators.external-secrets.io/v1alpha1
|
||||
kind: Password
|
||||
name: db-password
|
||||
---
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: DatabaseRole
|
||||
metadata:
|
||||
name: main-vaultwarden
|
||||
namespace: psql
|
||||
spec:
|
||||
cluster:
|
||||
name: main
|
||||
name: vaultwarden
|
||||
login: true
|
||||
passwordSecret:
|
||||
name: vaultwarden-db
|
||||
---
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Database
|
||||
metadata:
|
||||
name: main-vaultwarden
|
||||
namespace: psql
|
||||
spec:
|
||||
cluster:
|
||||
name: main
|
||||
name: vaultwarden
|
||||
owner: vaultwarden
|
||||
databaseReclaimPolicy: retain
|
||||
---
|
||||
# Lets the vaultwarden namespace read only its own credentials Secret.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: vaultwarden-db-reader
|
||||
namespace: psql
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: [secrets]
|
||||
resourceNames: [vaultwarden-db]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups: [authorization.k8s.io]
|
||||
resources: [selfsubjectrulesreviews]
|
||||
verbs: [create]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: vaultwarden-db-reader
|
||||
namespace: psql
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: vaultwarden-db-reader
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: db-credentials-reader
|
||||
namespace: vaultwarden
|
||||
@@ -4,3 +4,5 @@ kind: Kustomization
|
||||
resources:
|
||||
- app.yaml
|
||||
- cluster.yaml
|
||||
- password-generator.yaml
|
||||
- databases/vaultwarden.yaml
|
||||
@@ -0,0 +1,12 @@
|
||||
# Random passwords for database roles. Referenced by the ExternalSecrets in databases/.
|
||||
apiVersion: generators.external-secrets.io/v1alpha1
|
||||
kind: Password
|
||||
metadata:
|
||||
name: db-password
|
||||
namespace: psql
|
||||
spec:
|
||||
length: 40
|
||||
digits: 10
|
||||
symbols: 0 # the password ends up inside a connection URL
|
||||
noUpper: false
|
||||
allowRepeat: true
|
||||
@@ -0,0 +1,22 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: vaultwarden
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: apps
|
||||
destination:
|
||||
namespace: vaultwarden
|
||||
server: https://kubernetes.default.svc
|
||||
source:
|
||||
repoURL: https://gt.hexor.cy/ab/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s-ng/vaultwarden
|
||||
syncPolicy:
|
||||
automated:
|
||||
selfHeal: true
|
||||
prune: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
- SkipDryRunOnMissingResource=true # the external-secrets Application installs the CRDs
|
||||
@@ -0,0 +1,64 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: vaultwarden
|
||||
labels:
|
||||
app: vaultwarden
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate # the RWO local volume cannot be mounted by two pods
|
||||
selector:
|
||||
matchLabels:
|
||||
app: vaultwarden
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: vaultwarden
|
||||
spec:
|
||||
containers:
|
||||
- name: vaultwarden
|
||||
image: vaultwarden/server:1.37.3
|
||||
resources:
|
||||
requests:
|
||||
memory: 128Mi
|
||||
cpu: 100m
|
||||
limits:
|
||||
memory: 512Mi
|
||||
env:
|
||||
- name: DOMAIN
|
||||
value: https://vw.hexor.cy
|
||||
- name: ORG_GROUPS_ENABLED
|
||||
value: "true"
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: vaultwarden-db-url
|
||||
key: DATABASE_URL
|
||||
- name: ADMIN_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: admin-token
|
||||
key: ADMIN_TOKEN
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /alive
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /alive
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: vaultwarden-data
|
||||
@@ -0,0 +1,23 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: vaultwarden
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
spec:
|
||||
rules:
|
||||
- host: vw.hexor.cy
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: vaultwarden
|
||||
port:
|
||||
number: 80
|
||||
tls:
|
||||
- secretName: vaultwarden-tls
|
||||
hosts:
|
||||
- vw.hexor.cy
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- app.yaml
|
||||
- secrets.yaml
|
||||
- pvc.yaml
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
- ingress.yaml
|
||||
@@ -0,0 +1,12 @@
|
||||
# Attachments, sends, icon cache and RSA keys live here; the database is in PostgreSQL.
|
||||
# A local-path volume is bound to one node: the pod stays on the node it first ran on.
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: vaultwarden-data
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: local-path
|
||||
resources:
|
||||
requests:
|
||||
storage: 2Gi
|
||||
@@ -0,0 +1,78 @@
|
||||
# Read-only access to the vaultwarden-db Secret in the psql namespace
|
||||
# (see postgresql/databases/vaultwarden.yaml for the other half).
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: db-credentials-reader
|
||||
---
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: psql-credentials
|
||||
spec:
|
||||
provider:
|
||||
kubernetes:
|
||||
remoteNamespace: psql
|
||||
server:
|
||||
caProvider:
|
||||
type: ConfigMap
|
||||
name: kube-root-ca.crt
|
||||
key: ca.crt
|
||||
auth:
|
||||
serviceAccount:
|
||||
name: db-credentials-reader
|
||||
---
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: vaultwarden-db-url
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
kind: SecretStore
|
||||
name: psql-credentials
|
||||
target:
|
||||
name: vaultwarden-db-url
|
||||
template:
|
||||
data:
|
||||
DATABASE_URL: "postgresql://{{ .username }}:{{ .password }}@main-rw.psql.svc:5432/vaultwarden"
|
||||
data:
|
||||
- secretKey: username
|
||||
remoteRef:
|
||||
key: vaultwarden-db
|
||||
property: username
|
||||
- secretKey: password
|
||||
remoteRef:
|
||||
key: vaultwarden-db
|
||||
property: password
|
||||
---
|
||||
# Admin panel token (/admin). Generated once; read it with:
|
||||
# kubectl -n vaultwarden get secret admin-token -o jsonpath='{.data.ADMIN_TOKEN}' | base64 -d
|
||||
apiVersion: generators.external-secrets.io/v1alpha1
|
||||
kind: Password
|
||||
metadata:
|
||||
name: admin-token
|
||||
spec:
|
||||
length: 48
|
||||
digits: 10
|
||||
symbols: 0
|
||||
noUpper: false
|
||||
allowRepeat: true
|
||||
---
|
||||
apiVersion: external-secrets.io/v1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: admin-token
|
||||
spec:
|
||||
refreshPolicy: CreatedOnce
|
||||
target:
|
||||
name: admin-token
|
||||
template:
|
||||
data:
|
||||
ADMIN_TOKEN: "{{ .password }}"
|
||||
dataFrom:
|
||||
- sourceRef:
|
||||
generatorRef:
|
||||
apiVersion: generators.external-secrets.io/v1alpha1
|
||||
kind: Password
|
||||
name: admin-token
|
||||
@@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: vaultwarden
|
||||
spec:
|
||||
selector:
|
||||
app: vaultwarden
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: http
|
||||
Reference in new issue
Block a user