diff --git a/argocd/manifests/argocd/external-secret-repo-forge.yaml b/argocd/manifests/argocd/external-secret-repo-forge.yaml new file mode 100644 index 0000000..61fe3d6 --- /dev/null +++ b/argocd/manifests/argocd/external-secret-repo-forge.yaml @@ -0,0 +1,36 @@ +# ExternalSecret for ArgoCD Forge SSH credentials +# +# Replaces the manual op inject workflow from repo-forge-secret.yaml.tpl +# +# 1Password item: "argocd forge key" in blumeops vault +# Field: "private key" +# +# This is a repo-creds (credential template) that matches ALL repos under eblume/ +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: repo-creds-forge + namespace: argocd +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: repo-creds-forge + creationPolicy: Merge + template: + metadata: + labels: + argocd.argoproj.io/secret-type: repo-creds + data: + type: git + url: "ssh://forgejo@forge.ops.eblu.me:2222/eblume/" + insecure: "true" + sshPrivateKey: "{{ .privateKey }}" + data: + - secretKey: privateKey + remoteRef: + key: argocd forge key + property: private key diff --git a/argocd/manifests/argocd/kustomization.yaml b/argocd/manifests/argocd/kustomization.yaml index 6662c4b..31b9cd6 100644 --- a/argocd/manifests/argocd/kustomization.yaml +++ b/argocd/manifests/argocd/kustomization.yaml @@ -7,6 +7,7 @@ resources: # Pin to specific version for intentional upgrades - https://raw.githubusercontent.com/argoproj/argo-cd/v3.2.6/manifests/install.yaml - service-tailscale.yaml + - external-secret-repo-forge.yaml patches: - path: argocd-cmd-params-cm.yaml diff --git a/argocd/manifests/databases/external-secret-borgmatic.yaml b/argocd/manifests/databases/external-secret-borgmatic.yaml new file mode 100644 index 0000000..0af8cf6 --- /dev/null +++ b/argocd/manifests/databases/external-secret-borgmatic.yaml @@ -0,0 +1,30 @@ +# ExternalSecret for borgmatic backup user password +# +# Replaces the manual op inject workflow from secret-borgmatic.yaml.tpl +# +# 1Password item: "borgmatic" in blumeops vault +# Field: "db-password" +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: blumeops-pg-borgmatic + namespace: databases +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: blumeops-pg-borgmatic + creationPolicy: Merge + template: + type: kubernetes.io/basic-auth + data: + username: borgmatic + password: "{{ .password }}" + data: + - secretKey: password + remoteRef: + key: borgmatic + property: db-password diff --git a/argocd/manifests/databases/external-secret-eblume.yaml b/argocd/manifests/databases/external-secret-eblume.yaml new file mode 100644 index 0000000..532a1ed --- /dev/null +++ b/argocd/manifests/databases/external-secret-eblume.yaml @@ -0,0 +1,30 @@ +# ExternalSecret for eblume superuser password +# +# Replaces the manual op inject workflow from secret-eblume.yaml.tpl +# +# 1Password item: "postgres" in blumeops vault +# Field: "password" +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: blumeops-pg-eblume + namespace: databases +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: blumeops-pg-eblume + creationPolicy: Merge + template: + type: kubernetes.io/basic-auth + data: + username: eblume + password: "{{ .password }}" + data: + - secretKey: password + remoteRef: + key: postgres + property: password diff --git a/argocd/manifests/databases/external-secret-teslamate.yaml b/argocd/manifests/databases/external-secret-teslamate.yaml new file mode 100644 index 0000000..346a4bb --- /dev/null +++ b/argocd/manifests/databases/external-secret-teslamate.yaml @@ -0,0 +1,30 @@ +# ExternalSecret for TeslaMate database user password +# +# Replaces the manual op inject workflow from secret-teslamate.yaml.tpl +# +# 1Password item: "TeslaMate" in blumeops vault +# Field: "db_password" +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: blumeops-pg-teslamate + namespace: databases +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: blumeops-pg-teslamate + creationPolicy: Merge + template: + type: kubernetes.io/basic-auth + data: + username: teslamate + password: "{{ .password }}" + data: + - secretKey: password + remoteRef: + key: TeslaMate + property: db_password diff --git a/argocd/manifests/databases/kustomization.yaml b/argocd/manifests/databases/kustomization.yaml index e2eaa0c..4e33a7c 100644 --- a/argocd/manifests/databases/kustomization.yaml +++ b/argocd/manifests/databases/kustomization.yaml @@ -8,3 +8,6 @@ resources: - immich-pg.yaml - service-tailscale.yaml - service-metrics-tailscale.yaml + - external-secret-eblume.yaml + - external-secret-borgmatic.yaml + - external-secret-teslamate.yaml diff --git a/argocd/manifests/forgejo-runner/external-secret.yaml b/argocd/manifests/forgejo-runner/external-secret.yaml new file mode 100644 index 0000000..ec1f5c6 --- /dev/null +++ b/argocd/manifests/forgejo-runner/external-secret.yaml @@ -0,0 +1,34 @@ +# ExternalSecret for Forgejo Runner environment +# +# Replaces the manual op inject workflow from secret.yaml.tpl +# +# 1Password item: "Forgejo Secrets" in blumeops vault +# Field: "runner_reg" +# +# Note: Static values (FORGEJO_URL, RUNNER_NAME, RUNNER_LABELS) are included +# via template since they don't need to be in 1Password. +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: forgejo-runner-env + namespace: forgejo-runner +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: forgejo-runner-env + creationPolicy: Merge + template: + data: + FORGEJO_URL: "https://forge.ops.eblu.me" + RUNNER_NAME: "k8s-runner" + RUNNER_LABELS: "k8s:docker://registry.ops.eblu.me/blumeops/forgejo-runner:v2.1.7" + RUNNER_TOKEN: "{{ .runner_token }}" + data: + - secretKey: runner_token + remoteRef: + key: Forgejo Secrets + property: runner_reg diff --git a/argocd/manifests/grafana-config/external-secret-admin.yaml b/argocd/manifests/grafana-config/external-secret-admin.yaml new file mode 100644 index 0000000..547676b --- /dev/null +++ b/argocd/manifests/grafana-config/external-secret-admin.yaml @@ -0,0 +1,29 @@ +# ExternalSecret for Grafana admin password +# +# Replaces the manual op inject workflow from secret-admin.yaml.tpl +# +# 1Password item: "Grafana (blumeops)" in blumeops vault +# Field: "password" +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: grafana-admin + namespace: monitoring +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: grafana-admin + creationPolicy: Merge + template: + data: + admin-user: admin + admin-password: "{{ .password }}" + data: + - secretKey: password + remoteRef: + key: Grafana (blumeops) + property: password diff --git a/argocd/manifests/grafana-config/external-secret-teslamate-datasource.yaml b/argocd/manifests/grafana-config/external-secret-teslamate-datasource.yaml new file mode 100644 index 0000000..4533c2f --- /dev/null +++ b/argocd/manifests/grafana-config/external-secret-teslamate-datasource.yaml @@ -0,0 +1,31 @@ +# ExternalSecret for TeslaMate PostgreSQL datasource password +# +# Replaces the manual op inject workflow from secret-teslamate-datasource.yaml.tpl +# +# 1Password item: "TeslaMate" in blumeops vault +# Field: "db_password" +# +# This secret is mounted as environment variables in Grafana. +# The password is referenced in values.yaml datasource config as $TESLAMATE_DB_PASSWORD +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: grafana-teslamate-datasource + namespace: monitoring +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: grafana-teslamate-datasource + creationPolicy: Merge + template: + data: + TESLAMATE_DB_PASSWORD: "{{ .password }}" + data: + - secretKey: password + remoteRef: + key: TeslaMate + property: db_password diff --git a/argocd/manifests/grafana-config/kustomization.yaml b/argocd/manifests/grafana-config/kustomization.yaml index 2611b0a..6a14e45 100644 --- a/argocd/manifests/grafana-config/kustomization.yaml +++ b/argocd/manifests/grafana-config/kustomization.yaml @@ -5,6 +5,8 @@ namespace: monitoring resources: - ingress-tailscale.yaml + - external-secret-admin.yaml + - external-secret-teslamate-datasource.yaml # Dashboard ConfigMaps - discovered by Grafana sidecar via label grafana_dashboard=1 - dashboards/configmap-borgmatic.yaml - dashboards/configmap-devpi.yaml diff --git a/argocd/manifests/tailscale-operator/external-secret.yaml b/argocd/manifests/tailscale-operator/external-secret.yaml new file mode 100644 index 0000000..b8658cc --- /dev/null +++ b/argocd/manifests/tailscale-operator/external-secret.yaml @@ -0,0 +1,29 @@ +# ExternalSecret for Tailscale Operator OAuth credentials +# +# Replaces the manual op inject workflow from secret.yaml.tpl +# +# 1Password item: "Tailscale K8s Operator OAuth" in blumeops vault +# Fields: "client-id", "client-secret" +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: operator-oauth + namespace: tailscale +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: operator-oauth + creationPolicy: Merge + data: + - secretKey: client_id + remoteRef: + key: Tailscale K8s Operator OAuth + property: client-id + - secretKey: client_secret + remoteRef: + key: Tailscale K8s Operator OAuth + property: client-secret diff --git a/argocd/manifests/tailscale-operator/kustomization.yaml b/argocd/manifests/tailscale-operator/kustomization.yaml index f0517ad..65f3786 100644 --- a/argocd/manifests/tailscale-operator/kustomization.yaml +++ b/argocd/manifests/tailscale-operator/kustomization.yaml @@ -8,6 +8,4 @@ resources: - proxyclass.yaml - dnsconfig.yaml - egress-forge.yaml - -# Note: OAuth secret (operator-oauth) is NOT included here. -# It must be manually applied before deploying - see README.md + - external-secret.yaml diff --git a/argocd/manifests/teslamate/external-secret-db.yaml b/argocd/manifests/teslamate/external-secret-db.yaml new file mode 100644 index 0000000..38d1925 --- /dev/null +++ b/argocd/manifests/teslamate/external-secret-db.yaml @@ -0,0 +1,25 @@ +# ExternalSecret for TeslaMate database password +# +# Replaces the manual op inject workflow from secret-db.yaml.tpl +# +# 1Password item: "TeslaMate" in blumeops vault +# Field: "db_password" +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: teslamate-db + namespace: teslamate +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: teslamate-db + creationPolicy: Merge + data: + - secretKey: password + remoteRef: + key: TeslaMate + property: db_password diff --git a/argocd/manifests/teslamate/external-secret-encryption-key.yaml b/argocd/manifests/teslamate/external-secret-encryption-key.yaml new file mode 100644 index 0000000..92e1f50 --- /dev/null +++ b/argocd/manifests/teslamate/external-secret-encryption-key.yaml @@ -0,0 +1,27 @@ +# ExternalSecret for TeslaMate encryption key +# +# Replaces the manual op inject workflow from secret-encryption-key.yaml.tpl +# +# 1Password item: "TeslaMate" in blumeops vault +# Field: "api_enc_key" +# +# This key encrypts Tesla API tokens at rest in the database. +# +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: teslamate-encryption + namespace: teslamate +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-blumeops + target: + name: teslamate-encryption + creationPolicy: Merge + data: + - secretKey: key + remoteRef: + key: TeslaMate + property: api_enc_key diff --git a/argocd/manifests/teslamate/kustomization.yaml b/argocd/manifests/teslamate/kustomization.yaml index 5ae053f..3be2de4 100644 --- a/argocd/manifests/teslamate/kustomization.yaml +++ b/argocd/manifests/teslamate/kustomization.yaml @@ -7,3 +7,5 @@ resources: - deployment.yaml - service.yaml - ingress-tailscale.yaml + - external-secret-db.yaml + - external-secret-encryption-key.yaml