Add External Secrets Operator for GitOps secret management
Deploys ESO to sync secrets from 1Password to native K8s Secrets. Replaces manual `op inject` workflow with declarative ExternalSecrets. Includes: - ArgoCD Application for ESO operator (helm-chart-1.3.1) - Separate config app for ClusterSecretStore - ClusterSecretStore connecting to 1Password Connect - Helm values with resource limits for minikube Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
38179337e0
commit
eafcdb2f28
6 changed files with 199 additions and 0 deletions
26
argocd/apps/external-secrets-config.yaml
Normal file
26
argocd/apps/external-secrets-config.yaml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# External Secrets Configuration - ClusterSecretStore for 1Password
|
||||
#
|
||||
# Deploys the ClusterSecretStore that connects ESO to 1Password Connect.
|
||||
# Must be synced AFTER external-secrets operator is running.
|
||||
#
|
||||
# Prerequisites:
|
||||
# - 1password-connect is deployed and healthy
|
||||
# - external-secrets operator is deployed and CRDs are installed
|
||||
#
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: external-secrets-config
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: ssh://forgejo@forge.ops.eblu.me:2222/eblume/blumeops.git
|
||||
targetRevision: main
|
||||
path: argocd/manifests/external-secrets
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: external-secrets
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
33
argocd/apps/external-secrets.yaml
Normal file
33
argocd/apps/external-secrets.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# External Secrets Operator - Kubernetes secret sync from external providers
|
||||
# Syncs secrets from 1Password Connect to native Kubernetes Secrets
|
||||
#
|
||||
# Chart mirrored from https://github.com/external-secrets/external-secrets
|
||||
#
|
||||
# Prerequisites:
|
||||
# - 1password-connect must be deployed and healthy
|
||||
#
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: external-secrets
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
sources:
|
||||
- repoURL: ssh://forgejo@forge.ops.eblu.me:2222/eblume/external-secrets.git
|
||||
targetRevision: helm-chart-1.3.1
|
||||
path: deploy/charts/external-secrets
|
||||
helm:
|
||||
releaseName: external-secrets
|
||||
valueFiles:
|
||||
- $values/argocd/manifests/external-secrets/values.yaml
|
||||
- repoURL: ssh://forgejo@forge.ops.eblu.me:2222/eblume/blumeops.git
|
||||
targetRevision: main
|
||||
ref: values
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: external-secrets
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
83
argocd/manifests/external-secrets/README.md
Normal file
83
argocd/manifests/external-secrets/README.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# External Secrets Operator
|
||||
|
||||
External Secrets Operator (ESO) syncs secrets from 1Password Connect to native Kubernetes Secrets.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **ClusterSecretStore** (`onepassword-blumeops`): Cluster-wide access to 1Password via Connect
|
||||
- **ExternalSecret** (per-namespace): Defines which secrets to sync from 1Password
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1Password Connect must be deployed and healthy before syncing ESO.
|
||||
|
||||
## Deployment
|
||||
|
||||
```bash
|
||||
argocd app sync external-secrets
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
# Check operator pods
|
||||
kubectl --context=minikube-indri -n external-secrets get pods
|
||||
|
||||
# Check ClusterSecretStore status
|
||||
kubectl --context=minikube-indri get clustersecretstore onepassword-blumeops
|
||||
|
||||
# Check all ExternalSecrets across namespaces
|
||||
kubectl --context=minikube-indri get externalsecret -A
|
||||
```
|
||||
|
||||
## Creating ExternalSecrets
|
||||
|
||||
To sync a secret from 1Password, create an ExternalSecret in the target namespace:
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: my-secret
|
||||
namespace: my-namespace
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
kind: ClusterSecretStore
|
||||
name: onepassword-blumeops
|
||||
target:
|
||||
name: my-secret # Name of K8s Secret to create
|
||||
creationPolicy: Owner # ESO owns and manages the Secret
|
||||
data:
|
||||
- secretKey: password # Key in the K8s Secret
|
||||
remoteRef:
|
||||
key: My 1Password Item # Title of item in 1Password
|
||||
property: password # Field label in 1Password item
|
||||
```
|
||||
|
||||
### Finding 1Password Item Details
|
||||
|
||||
```bash
|
||||
# List items in blumeops vault
|
||||
op item list --vault blumeops
|
||||
|
||||
# Get field names for an item
|
||||
op item get <item-id> --vault blumeops --format json | jq -r '.fields[] | .label'
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### ClusterSecretStore not ready
|
||||
- Check 1Password Connect is running: `kubectl --context=minikube-indri -n 1password get pods`
|
||||
- Verify token secret exists: `kubectl --context=minikube-indri -n 1password get secret onepassword-token`
|
||||
|
||||
### ExternalSecret not syncing
|
||||
- Check the ExternalSecret status: `kubectl --context=minikube-indri describe externalsecret <name> -n <namespace>`
|
||||
- Verify the 1Password item title and field names match exactly
|
||||
- Check ESO controller logs: `kubectl --context=minikube-indri -n external-secrets logs -l app.kubernetes.io/name=external-secrets`
|
||||
|
||||
## Related
|
||||
|
||||
- [External Secrets Operator Docs](https://external-secrets.io/)
|
||||
- [1Password Provider](https://external-secrets.io/latest/provider/1password-automation/)
|
||||
- [1Password Connect](../1password-connect/README.md)
|
||||
21
argocd/manifests/external-secrets/cluster-secret-store.yaml
Normal file
21
argocd/manifests/external-secrets/cluster-secret-store.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# ClusterSecretStore for 1Password Connect
|
||||
#
|
||||
# Provides cluster-wide access to the blumeops vault via 1Password Connect.
|
||||
# ExternalSecret resources in any namespace can reference this store.
|
||||
#
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ClusterSecretStore
|
||||
metadata:
|
||||
name: onepassword-blumeops
|
||||
spec:
|
||||
provider:
|
||||
onepassword:
|
||||
connectHost: http://onepassword-connect.1password.svc.cluster.local:8080
|
||||
vaults:
|
||||
blumeops: 1
|
||||
auth:
|
||||
secretRef:
|
||||
connectTokenSecretRef:
|
||||
name: onepassword-token
|
||||
namespace: 1password
|
||||
key: token
|
||||
5
argocd/manifests/external-secrets/kustomization.yaml
Normal file
5
argocd/manifests/external-secrets/kustomization.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- cluster-secret-store.yaml
|
||||
31
argocd/manifests/external-secrets/values.yaml
Normal file
31
argocd/manifests/external-secrets/values.yaml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# External Secrets Operator Helm values for blumeops
|
||||
# Chart: https://github.com/external-secrets/external-secrets
|
||||
|
||||
installCRDs: true
|
||||
|
||||
# Resource limits for minikube
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "50m"
|
||||
limits:
|
||||
memory: "256Mi"
|
||||
cpu: "200m"
|
||||
|
||||
webhook:
|
||||
resources:
|
||||
requests:
|
||||
memory: "32Mi"
|
||||
cpu: "25m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
|
||||
certController:
|
||||
resources:
|
||||
requests:
|
||||
memory: "32Mi"
|
||||
cpu: "25m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "100m"
|
||||
Loading…
Add table
Add a link
Reference in a new issue