{{- $configSum := (include (print $.Template.BasePath "/configmap.yaml") . | sha256sum) }} {{- $configSum2 := (include (print $.Template.BasePath "/secret.yaml") . | sha256sum) }} {{- $configSum3 := (include (print $.Template.BasePath "/controller-manager-configmap.yaml") . | sha256sum) }} {{- $configSumTornjak := (include (print $.Template.BasePath "/tornjak-config.yaml") . | sha256sum) }} {{- $fullname := include "spire-server.fullname" . }} {{- if not (has .Values.persistence.type (list "pvc" "hostPath" "emptyDir")) }} {{- fail "persistence.type must be one of [\"pvc\", \"hostPath\", \"emptyDir\"]" }} {{- end }} apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ include "spire-server.fullname" . }} namespace: {{ include "spire-server.namespace" . }} labels: {{- include "spire-server.labels" . | nindent 4 }} app.kubernetes.io/component: server spec: {{- if not .Values.autoscaling.enabled }} {{- if and (eq .Values.dataStore.sql.databaseType "sqlite3") (gt (int .Values.replicaCount) 1) }} {{- fail "When running with sqlite3 database, you can't scale up to more then one instance. 'replicaCount' MUST be 1" }} {{- end }} replicas: {{ .Values.replicaCount }} {{- end }} serviceName: {{ include "spire-server.fullname" . }} selector: matchLabels: {{- include "spire-server.selectorLabels" . | nindent 6 }} app.kubernetes.io/component: server template: metadata: annotations: kubectl.kubernetes.io/default-container: spire-server checksum/config: {{ $configSum }} checksum/config2: {{ $configSum2 }} checksum/config3: {{ $configSum3 }} checksum/configTornjak: {{ $configSumTornjak }} {{- with .Values.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "spire-server.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: server component: server release: {{ .Release.Name }} release-namespace: {{ .Release.Namespace }} {{- with .Values.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "spire-server.serviceAccountName" . }} shareProcessNamespace: true securityContext: {{- include "spire-lib.podsecuritycontext" . | nindent 8 }} {{- include "spire-lib.default_cluster_priority_class_name" . | nindent 6 }} {{- if or (gt (len .Values.initContainers) 0) (and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.ca.create) .Values.nodeAttestor.tpmDirect.enabled }} initContainers: {{- if .Values.nodeAttestor.tpmDirect.enabled }} - name: init-tpm-direct securityContext: {{- include "spire-lib.securitycontext" . | nindent 12 }} image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.nodeAttestor.tpmDirect.image "global" .Values.global) }} command: - sh - -ec - | # SPIRE must be able to fork the plugin directly within its container. Copy the plugin into a volume that can be mounted where SPIRE can execute it. cp -a {{ .Values.nodeAttestor.tpmDirect.pluginPath }} /tpm/tpm_attestor_server mkdir -p /run/spire/data/tpm-direct/certs mkdir -p /run/spire/data/tpm-direct/hashes volumeMounts: - name: tpm-direct mountPath: /tpm - name: spire-data mountPath: /run/spire/data imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.image.pullPolicy }} {{- end }} {{- if and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.ca.create }} - name: wait securityContext: {{- include "spire-lib.securitycontext" . | nindent 12 }} image: {{ template "spire-lib.kubectl-image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.kubectl.image "global" .Values.global "KubeVersion" .Capabilities.KubeVersion.Version) }} args: - wait - --namespace - {{ .Release.Namespace }} - --timeout=3m - --for=condition=ready - issuer - {{ include "spire-server.fullname" $ }}-ca imagePullPolicy: {{ .Values.tools.kubectl.image.pullPolicy }} {{- end }} {{- if gt (len .Values.initContainers) 0 }} {{- toYaml .Values.initContainers | nindent 8 }} {{- end }} {{- end }} containers: - name: {{ .Chart.Name }} securityContext: {{- include "spire-lib.securitycontext" . | nindent 12 }} image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.image "global" .Values.global) }} imagePullPolicy: {{ .Values.image.pullPolicy }} args: - -expandEnv - -config - /run/spire/config/server.conf env: - name: PATH value: "/opt/spire/bin:/bin" {{- with .Values.extraEnv }} {{- . | toYaml | nindent 10 }} {{- end }} {{- if ne .Values.dataStore.sql.databaseType "sqlite3" }} {{- if .Values.dataStore.sql.externalSecret.enabled }} - name: DBPW valueFrom: secretKeyRef: name: {{ .Values.dataStore.sql.externalSecret.name }} key: {{ .Values.dataStore.sql.externalSecret.key }} {{- else }} - name: DBPW valueFrom: secretKeyRef: name: {{ $fullname }}-dbpw key: DBPW {{- end }} {{- end }} {{- if ne .Values.keyManager.awsKMS.accessKeyID "" }} - name: AWS_KMS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: {{ $fullname }}-aws-kms key: AWS_KMS_ACCESS_KEY_ID {{- end }} {{- if ne .Values.keyManager.awsKMS.secretAccessKey "" }} - name: AWS_KMS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: {{ $fullname }}-aws-kms key: AWS_KMS_SECRET_ACCESS_KEY {{- end }} ports: - name: grpc containerPort: 8081 protocol: TCP - containerPort: 8080 name: healthz {{- with .Values.federation }} {{- if eq (.enabled | toString) "true" }} - name: federation containerPort: {{ .bundleEndpoint.port }} protocol: TCP {{- end }} {{- end }} {{- if or (dig "telemetry" "prometheus" "enabled" .Values.telemetry.prometheus.enabled .Values.global) (and (dig "spire" "recommendations" "enabled" false .Values.global) (dig "spire" "recommendations" "prometheus" true .Values.global)) }} - containerPort: 9988 name: prom {{- end }} livenessProbe: httpGet: path: /live port: healthz {{- toYaml .Values.livenessProbe | nindent 12 }} readinessProbe: httpGet: path: /ready port: healthz {{- toYaml .Values.readinessProbe | nindent 12 }} resources: {{- toYaml .Values.resources | nindent 12 }} volumeMounts: - name: spire-server-socket mountPath: /tmp/spire-server/private readOnly: false - name: spire-config mountPath: /run/spire/config readOnly: true - name: spire-data mountPath: /run/spire/data readOnly: false {{- if .Values.nodeAttestor.tpmDirect.enabled }} - name: tpm-direct mountPath: /tpm readOnly: true {{- if ne (len .Values.nodeAttestor.tpmDirect.cas) 0 }} - name: tpm-direct-cas mountPath: /tpm-direct-cas {{- end }} {{- if ne (len .Values.nodeAttestor.tpmDirect.hashes) 0 }} - name: tpm-direct-hashes mountPath: /tmp-direct-hashes {{- end }} {{- end }} {{- if eq (.Values.upstreamAuthority.disk.enabled | toString) "true" }} - name: upstream-ca mountPath: /run/spire/upstream_ca readOnly: false {{ end }} {{- if gt (len .Values.upstreamAuthority.spire.upstreamDriver) 0 }} - name: upstream-agent mountPath: /run/spire/upstream_agent readOnly: true {{ end }} {{- with .Values.keyManager.awsKMS }} {{- if and (eq (.enabled | toString) "true") (or (ne .keyPolicy.policy "") (ne .keyPolicy.existingConfigMap "")) }} - name: aws-kms-key-policy mountPath: /run/spire/data/aws-kms-key-policy.json subPath: policy.json readOnly: true {{ end }} {{- end }} {{- with .Values.upstreamAuthority.vault }} {{- if eq (.enabled | toString) "true" }} {{- if eq (.k8sAuth.enabled | toString) "true" }} - name: spire-psat mountPath: /var/run/secrets/tokens {{- end }} {{- if ne (.insecureSkipVerify | toString) "true" }} - name: vault-ca mountPath: /run/spire/vault-upstream {{- end }} {{- end }} {{- end }} {{- if gt (len .Values.extraVolumeMounts) 0 }} {{- toYaml .Values.extraVolumeMounts | nindent 12 }} {{- end }} - name: server-tmp mountPath: /tmp readOnly: false {{- if eq (.Values.controllerManager.enabled | toString) "true" }} - name: spire-controller-manager securityContext: {{- include "spire-lib.securitycontext-extended" (dict "root" . "securityContext" .Values.controllerManager.securityContext) | nindent 12 }} image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.controllerManager.image "global" .Values.global) }} imagePullPolicy: {{ .Values.controllerManager.image.pullPolicy }} args: - --config=controller-manager-config.yaml {{- if .Values.controllerManager.expandEnv }} - --expand-env {{- end }} env: - name: ENABLE_WEBHOOKS value: {{ .Values.controllerManager.validatingWebhookConfiguration.enabled | toString | quote }} {{- if gt (len .Values.controllerManager.extraEnv) 0 }} {{- .Values.controllerManager.extraEnv | toYaml | nindent 12 }} {{- end }} ports: - name: https containerPort: 9443 protocol: TCP - containerPort: 8083 name: healthz {{- if or (dig "telemetry" "prometheus" "enabled" .Values.telemetry.prometheus.enabled .Values.global) (and (dig "spire" "recommendations" "enabled" false .Values.global) (dig "spire" "recommendations" "prometheus" true .Values.global)) }} - containerPort: 8082 name: prom2 {{- end }} livenessProbe: httpGet: path: /healthz port: healthz readinessProbe: httpGet: path: /readyz port: healthz resources: {{- toYaml .Values.controllerManager.resources | nindent 12 }} volumeMounts: - name: spire-server-socket mountPath: /tmp/spire-server/private readOnly: true - name: controller-manager-config mountPath: /controller-manager-config.yaml subPath: controller-manager-config.yaml readOnly: true - name: spire-controller-manager-tmp mountPath: /tmp readOnly: false {{- if gt (len .Values.extraVolumeMounts) 0 }} {{- toYaml .Values.extraVolumeMounts | nindent 12 }} {{- end }} {{- end }} {{- if eq (.Values.tornjak.enabled | toString) "true" }} - name: tornjak securityContext: {{- include "spire-lib.securitycontext-extended" (dict "root" . "securityContext" .Values.tornjak.securityContext) | nindent 12 }} image: {{ template "spire-lib.image" (dict "appVersion" .Values.tornjak.image.defaultTag "image" .Values.tornjak.image "global" .Values.global "ubi" true) }} imagePullPolicy: {{ .Values.tornjak.image.pullPolicy }} {{- if eq (include "spire-tornjak.connectionType" .) "http" }} startupProbe: httpGet: scheme: HTTP path: /api/tornjak/serverinfo port: 10000 {{- toYaml .Values.tornjak.startupProbe | nindent 12 }} {{- end }} args: - --spire-config - /run/spire/config/server.conf - --tornjak-config - /run/spire/tornjak-config/server.conf ports: - name: tornjak-http containerPort: 10000 protocol: TCP - name: tornjak-https containerPort: 10443 protocol: TCP resources: {{- toYaml .Values.tornjak.resources | nindent 12 }} volumeMounts: - name: {{ include "spire-tornjak.config" . }} mountPath: /run/spire/tornjak-config - name: spire-server-socket mountPath: /tmp/spire-server/private readOnly: true - name: spire-config mountPath: /run/spire/config readOnly: true - name: spire-data mountPath: /run/spire/data readOnly: false {{- if or (eq (include "spire-tornjak.connectionType" .) "tls") (eq (include "spire-tornjak.connectionType" .) "mtls") }} - name: server-cert mountPath: /opt/spire/server {{- end }} {{- if eq (include "spire-tornjak.connectionType" .) "mtls" }} - name: user-cert mountPath: /opt/spire/user {{- end }} {{- end }} {{- if gt (len .Values.extraContainers) 0 }} {{- toYaml .Values.extraContainers | nindent 8 }} {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.topologySpreadConstraints }} topologySpreadConstraints: {{- toYaml . | nindent 8 }} {{- end }} volumes: - name: server-tmp emptyDir: {} - name: spire-config configMap: name: {{ include "spire-server.fullname" . }} - name: spire-server-socket emptyDir: {} - name: spire-controller-manager-tmp emptyDir: {} {{- if .Values.nodeAttestor.tpmDirect.enabled }} - name: tpm-direct emptyDir: {} {{- if ne (len .Values.nodeAttestor.tpmDirect.cas) 0 }} - name: tpm-direct-cas configMap: name: {{ include "spire-server.fullname" . }}-tpm-direct-ca {{- end }} {{- if ne (len .Values.nodeAttestor.tpmDirect.hashes) 0 }} - name: tpm-direct-hashes configMap: name: {{ include "spire-server.fullname" . }}-tpm-direct-hash {{- end }} {{- end }} {{- if or (eq (include "spire-tornjak.connectionType" .) "tls") (eq (include "spire-tornjak.connectionType" .) "mtls") }} - name: server-cert secret: defaultMode: 256 secretName: {{ .Values.tornjak.config.tlsSecret }} {{- end }} {{- if eq (include "spire-tornjak.connectionType" .) "mtls" }} {{- if eq .Values.tornjak.config.clientCA.type "Secret" }} - name: user-cert secret: defaultMode: 256 secretName: {{ .Values.tornjak.config.clientCA.name }} {{- else if eq .Values.tornjak.config.clientCA.type "ConfigMap" }} - name: user-cert configMap: name: {{ .Values.tornjak.config.clientCA.name }} {{- end }} {{- end }} {{- if eq (.Values.upstreamAuthority.disk.enabled | toString) "true" }} - name: upstream-ca secret: secretName: {{ include "spire-server.upstream-ca-secret" . }} {{- end }} {{- if gt (len .Values.upstreamAuthority.spire.upstreamDriver) 0 }} - name: upstream-agent csi: driver: {{ .Values.upstreamAuthority.spire.upstreamDriver }} readOnly: true {{- end }} {{- with .Values.keyManager.awsKMS }} {{- if and (eq (.enabled | toString) "true") (or (ne .keyPolicy.policy "") (ne .keyPolicy.existingConfigMap "")) }} - name: aws-kms-key-policy configMap: {{- if ne .keyPolicy.policy "" }} name: {{ $fullname }}-aws-kms {{- else if ne .keyPolicy.existingConfigMap "" }} name: {{ .keyPolicy.existingConfigMap }} {{- end }} {{- end }} {{- end }} {{- if eq (.Values.controllerManager.enabled | toString) "true" }} - name: controller-manager-config configMap: name: {{ include "spire-controller-manager.fullname" . }} {{- end }} {{- if eq (.Values.tornjak.enabled | toString) "true" }} {{- if .Values.tornjak.config }} - name: {{ include "spire-tornjak.config" . }} configMap: defaultMode: 420 name: {{ include "spire-tornjak.config" . }} {{- end }} {{- end }} {{- if gt (len .Values.extraVolumes) 0 }} {{- toYaml .Values.extraVolumes | nindent 8 }} {{- end }} {{- if eq .Values.persistence.type "emptyDir" }} - name: spire-data emptyDir: {} {{- else if eq .Values.persistence.type "hostPath" }} - name: spire-data hostPath: path: {{ .Values.persistence.hostPath }} type: Directory {{- end }} {{- with .Values.upstreamAuthority.vault }} {{- if eq (.enabled | toString) "true" }} {{- if ne (.insecureSkipVerify | toString) "true" }} {{- if eq (.caCert.type | lower) "configmap" }} - name: vault-ca configMap: name: {{ .caCert.name }} {{- else if eq (.caCert.type | lower) "secret" }} - name: vault-ca secret: secretName: {{ .caCert.name }} optional: false {{- end }} {{- end -}} {{- if eq (.k8sAuth.enabled | toString) "true" }} - name: spire-psat projected: sources: - serviceAccountToken: path: spire-server expirationSeconds: {{ .k8sAuth.token.expiry }} {{- if ne .k8sAuth.token.audience "" }} audience: {{ .k8sAuth.token.audience }} {{- end }} {{- end }} {{- end -}} {{- end -}} {{- if eq .Values.persistence.type "pvc" }} volumeClaimTemplates: - metadata: name: spire-data spec: accessModes: - {{ .Values.persistence.accessMode | default "ReadWriteOnce" }} resources: requests: storage: {{ .Values.persistence.size }} {{- if .Values.persistence.storageClass }} storageClassName: {{ .Values.persistence.storageClass }} {{- end }} {{- end }}