feat(iam): own the ZITADEL core objects in GitOps
The chart declares its ServiceAccount, ConfigMap, Role and RoleBinding as pre-install/pre-upgrade Helm hooks with hook-delete-policy before-hook-creation. ArgoCD maps those to PreSync and prunes them when a sync ends, so every sync deleted the ServiceAccount and ConfigMap the ZITADEL Deployment mounts. New pods failed with `serviceaccount "zitadel" not found`, leaving the IdP one restart from an outage. Add a zatadel-core Application owning hook-free copies, keeping them as ordinary desired state that survives every sync. Prune is off for this path: deleting a ServiceAccount here would recreate the outage. The ConfigMap also carries the notification settings, pointing DefaultInstance.SMTPConfiguration at the smtp-gotify relay, with SMTPSenderAddressMatchesInstanceDomain false because the sender [email protected] differs from the instance domain zatadel.riotpiao.com. Drop the envVarsSecret approach: ZITADEL created no SMTP provider from those env vars (no instance.smtp.config.added event).
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- zitadel-core.yaml
|
||||
@@ -0,0 +1,133 @@
|
||||
# ZITADEL core objects, owned by this repository instead of the Helm chart.
|
||||
#
|
||||
# The zitadel chart marks four objects as Helm hooks:
|
||||
#
|
||||
# kind: ServiceAccount (also ConfigMap/zitadel-config-yaml, Role, RoleBinding)
|
||||
# annotations:
|
||||
# helm.sh/hook: pre-install,pre-upgrade
|
||||
# helm.sh/hook-delete-policy: before-hook-creation
|
||||
#
|
||||
# ArgoCD maps pre-install/pre-upgrade to PreSync and prunes hook resources when
|
||||
# the sync ends. Every sync therefore deleted the ServiceAccount and the ConfigMap
|
||||
# that the ZITADEL Deployment references, which produced:
|
||||
#
|
||||
# error creating: pods "zitadel-..." is forbidden:
|
||||
# serviceaccount "zitadel" not found
|
||||
#
|
||||
# and left the IdP one restart away from failing.
|
||||
#
|
||||
# These copies carry no hook annotations, so they are ordinary desired state and
|
||||
# ArgoCD keeps them. The chart still renders its own hook versions during a sync;
|
||||
# these win because the sync no longer removes them.
|
||||
#
|
||||
# ConfigMap content mirrors what the chart renders from
|
||||
# k8s/infra/iam/zitadel-values.yaml, plus the notification settings the chart
|
||||
# cannot deliver through values (see the SMTP note below). When the chart values
|
||||
# change, update this file too; it is the authoritative copy at runtime.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: zitadel
|
||||
namespace: iam
|
||||
labels:
|
||||
app.kubernetes.io/name: zitadel
|
||||
app.kubernetes.io/instance: zitadel
|
||||
app.kubernetes.io/managed-by: gitops
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: zitadel
|
||||
namespace: iam
|
||||
labels:
|
||||
app.kubernetes.io/name: zitadel
|
||||
app.kubernetes.io/instance: zitadel
|
||||
app.kubernetes.io/managed-by: gitops
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "create", "patch", "list", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: zitadel
|
||||
namespace: iam
|
||||
labels:
|
||||
app.kubernetes.io/name: zitadel
|
||||
app.kubernetes.io/instance: zitadel
|
||||
app.kubernetes.io/managed-by: gitops
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: zitadel
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: zitadel
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: zitadel-config-yaml
|
||||
namespace: iam
|
||||
labels:
|
||||
app.kubernetes.io/name: zitadel
|
||||
app.kubernetes.io/instance: zitadel
|
||||
app.kubernetes.io/managed-by: gitops
|
||||
data:
|
||||
zitadel-config-yaml: |
|
||||
ExternalDomain: zitadel.riotpiao.com
|
||||
ExternalSecure: true
|
||||
TLS:
|
||||
Enabled: false
|
||||
FirstInstance:
|
||||
# First boot is COMPLETE. Skip stops the setup step from running again and
|
||||
# silently rotating the iam-admin key that provisioning reads.
|
||||
Skip: true
|
||||
Org:
|
||||
Skip: true
|
||||
Machine:
|
||||
Machine:
|
||||
Name: Automatically Initialized IAM Admin
|
||||
Username: iam-admin
|
||||
MachineKey:
|
||||
ExpirationDate: "2029-01-01T00:00:00Z"
|
||||
Type: 1
|
||||
Pat:
|
||||
ExpirationDate: "2029-01-01T00:00:00Z"
|
||||
Machine:
|
||||
Identification:
|
||||
Hostname:
|
||||
Enabled: true
|
||||
Webhook:
|
||||
Enabled: false
|
||||
# Notification delivery.
|
||||
#
|
||||
# ZITADEL sends verification codes and password resets by SMTP only. This
|
||||
# cluster has no mail path, so without a provider every user stays at
|
||||
# verified_email = empty and cannot finish a first login.
|
||||
#
|
||||
# The target is the in-cluster smtp-gotify relay, which forwards each message
|
||||
# to Gotify so codes reach the phone.
|
||||
#
|
||||
# Why here and not in chart values: injecting the same keys as
|
||||
# ZITADEL_DEFAULTINSTANCE_SMTPCONFIGURATION_* env vars produced no
|
||||
# instance.smtp.config.added event, so ZITADEL never created the provider.
|
||||
# Setting configmapConfig in chart values made ArgoCD stop managing this
|
||||
# ConfigMap. Owning the file here avoids both problems.
|
||||
DefaultInstance:
|
||||
DomainPolicy:
|
||||
# The sender is [email protected] while the instance domain is
|
||||
# zitadel.riotpiao.com. Leave this true so the sender address is not
|
||||
# rejected for not matching the domain.
|
||||
SMTPSenderAddressMatchesInstanceDomain: false
|
||||
SMTPConfiguration:
|
||||
SMTP:
|
||||
Host: smtp-gotify.iam.svc.cluster.local:2525
|
||||
TLS: false
|
||||
From: [email protected]
|
||||
FromName: ZITADEL
|
||||
Reference in New Issue
Block a user