Deploy Sealed Secrets with Argo CD

This commit is contained in:
2026-10-18 13:37:03 +02:00
parent 517e0ee5b0
commit 832d53739d
5 changed files with 105 additions and 1 deletions
+29 -1
View File
@@ -6,7 +6,8 @@ container images and then commits the selected image tag here; it never receives
## Repository layout
- `apps/immich-sync/` is the desired Kubernetes state for Immich Share Sync.
- `bootstrap/` contains the Argo CD project and Application that point back to this repository.
- `bootstrap/` contains Argo CD projects and Applications, including the
upstream Sealed Secrets controller.
- `scripts/update-immich-sync-image.sh` is the single image-promotion interface used by CI.
The only canonical Immich Share Sync image version is `images[0].newTag` in
@@ -88,3 +89,30 @@ radius.
Argo CD is the normal deployment mechanism. If it is unavailable, `apps/immich-sync/install.sh` renders, performs a
server-side dry-run, applies the same Kustomize source, and waits for the Deployment rollout. A later Argo CD refresh
will see the same desired resources.
## Sealed Secrets
Argo CD installs the official Sealed Secrets chart pinned in
`bootstrap/sealed-secrets.yaml`. Public Git stores only `SealedSecret`
ciphertext. The controller decrypts that ciphertext into namespace-scoped
Kubernetes Secrets; the private sealing key never belongs in this repository.
Install the matching `kubeseal` client, then seal a Secret for its final name
and namespace. The default strict scope prevents ciphertext from being moved to
another name or namespace:
```sh
kubectl --namespace default create secret generic example \
--from-literal=token='replace-me' \
--dry-run=client --output=yaml \
| kubeseal \
--controller-name sealed-secrets-controller \
--controller-namespace sealed-secrets \
--format yaml > example-sealed-secret.yaml
```
The controller's generated private key is the disaster-recovery key for every
sealed value. Back up the Secrets labelled
`sealedsecrets.bitnami.com/sealed-secrets-key=active` from namespace
`sealed-secrets` to an encrypted offline store. Do not commit that backup. A
cluster rebuilt without one of those keys cannot decrypt existing ciphertext.
+6
View File
@@ -17,3 +17,9 @@ kubectl --namespace argocd wait application/immich-sync \
kubectl --namespace argocd wait application/immich-sync \
--for=jsonpath='{.status.health.status}'=Healthy \
--timeout=5m
kubectl --namespace argocd wait application/sealed-secrets \
--for=jsonpath='{.status.sync.status}'=Synced \
--timeout=5m
kubectl --namespace argocd wait application/sealed-secrets \
--for=jsonpath='{.status.health.status}'=Healthy \
--timeout=5m
+2
View File
@@ -2,4 +2,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- project.yaml
- platform-project.yaml
- sealed-secrets.yaml
- immich-sync.yaml
+32
View File
@@ -0,0 +1,32 @@
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: platform
namespace: argocd
spec:
description: Cluster services installed from maintained upstream charts
sourceRepos:
- https://bitnami.github.io/sealed-secrets
destinations:
- namespace: sealed-secrets
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: apiextensions.k8s.io
kind: CustomResourceDefinition
- group: rbac.authorization.k8s.io
kind: ClusterRole
- group: rbac.authorization.k8s.io
kind: ClusterRoleBinding
namespaceResourceWhitelist:
- group: ""
kind: Service
- group: ""
kind: ServiceAccount
- group: apps
kind: Deployment
- group: monitoring.coreos.com
kind: ServiceMonitor
- group: rbac.authorization.k8s.io
kind: Role
- group: rbac.authorization.k8s.io
kind: RoleBinding
+36
View File
@@ -0,0 +1,36 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: sealed-secrets
namespace: argocd
spec:
project: platform
source:
chart: sealed-secrets
repoURL: https://bitnami.github.io/sealed-secrets
targetRevision: 2.20.0
helm:
releaseName: sealed-secrets
valuesObject:
fullnameOverride: sealed-secrets-controller
metrics:
serviceMonitor:
enabled: true
labels:
release: prometheus
resources:
limits:
memory: 128Mi
requests:
cpu: 10m
memory: 32Mi
destination:
server: https://kubernetes.default.svc
namespace: sealed-secrets
syncPolicy:
automated:
enabled: true
prune: false
selfHeal: true
syncOptions:
- CreateNamespace=true