{{- if .Values.copilot.enabled }} {{- include "sim.copilot.validate" . }} apiVersion: v1 kind: Service metadata: name: {{ include "sim.fullname" . }}-copilot namespace: {{ .Release.Namespace }} labels: {{- include "sim.copilot.labels" . | nindent 4 }} spec: type: {{ .Values.copilot.server.service.type }} ports: - port: {{ .Values.copilot.server.service.port }} targetPort: {{ .Values.copilot.server.service.targetPort }} protocol: TCP name: http selector: {{- include "sim.copilot.selectorLabels" . | nindent 4 }} --- apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "sim.fullname" . }}-copilot namespace: {{ .Release.Namespace }} labels: {{- include "sim.copilot.labels" . | nindent 4 }} spec: replicas: {{ .Values.copilot.server.replicaCount }} selector: matchLabels: {{- include "sim.copilot.selectorLabels" . | nindent 6 }} template: metadata: annotations: {{- /* Hash both the inline Secret and the ExternalSecret template — whichever mode is active, only one renders non-empty content, but concatenating both means a mode switch or a remoteRefs.copilot mapping change still changes the checksum and forces a rollout. This can't see the live value ESO syncs from the external store (Helm only has the ExternalSecret manifest at render time, not the store's payload) — that's an inherent ESO limitation, not something a Helm checksum can close; ESO's own reconciliation handles picking up rotated values. */}} checksum/secret: {{ printf "%s%s" (include (print $.Template.BasePath "/secrets-copilot.yaml") .) (include (print $.Template.BasePath "/external-secret-copilot.yaml") .) | sha256sum }} {{- with .Values.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "sim.copilot.selectorLabels" . | nindent 8 }} {{- with .Values.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} spec: {{- with .Values.global.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "sim.serviceAccountName" . }} automountServiceAccountToken: false {{- include "sim.podSecurityContext" .Values.copilot.server | nindent 6 }} {{- with .Values.copilot.server.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} {{- end }} containers: - name: copilot image: {{ include "sim.image" (dict "imageRoot" .Values.copilot.server.image "global" .Values.global "chartAppVersion" .Chart.AppVersion) }} imagePullPolicy: {{ .Values.copilot.server.image.pullPolicy }} ports: - name: http containerPort: {{ .Values.copilot.server.service.targetPort }} protocol: TCP envFrom: - secretRef: name: {{ include "sim.copilot.envSecretName" . }} - secretRef: name: {{ include "sim.copilot.databaseSecretName" . }} {{- with .Values.copilot.server.extraEnvFrom }} {{- toYaml . | nindent 12 }} {{- end }} {{- /* copilot.server.env flows through envFrom (the Secret/ExternalSecret) above. copilot.server.envDefaults are inlined here so they don't leak into the chart-managed Secret and don't need to be mapped when externalSecrets.enabled=true — same rationale as app.envDefaults. Skipped entirely in existingSecret mode: the pre-created Secret is the source of truth, and inlining defaults would silently shadow keys (PORT, LOG_LEVEL, etc.) the user stored there via envFrom, since explicit env wins over envFrom. Keyed purely on copilot.server.secret.create, NOT the global externalSecrets.enabled flag — envFrom always points at the user-provided Secret name whenever secret.create=false, regardless of whether ESO is used for other components, so the global flag is irrelevant here. */}} {{- $useExistingSecret := not .Values.copilot.server.secret.create }} {{- if or (not $useExistingSecret) .Values.copilot.server.extraEnv }} env: {{- $copilotEnv := .Values.copilot.server.env | default dict }} {{- if not $useExistingSecret }} {{- range $key, $value := .Values.copilot.server.envDefaults | default dict }} {{- $override := index $copilotEnv $key }} {{- if and (ne (toString $value) "") (ne (toString $value) "") (or (not $override) (eq (toString $override) "") (eq (toString $override) "")) }} - name: {{ $key }} value: {{ $value | quote }} {{- end }} {{- end }} {{- end }} {{- with .Values.copilot.server.extraEnv }} {{- toYaml . | nindent 12 }} {{- end }} {{- end }} {{- if .Values.copilot.server.startupProbe }} startupProbe: {{- toYaml .Values.copilot.server.startupProbe | nindent 12 }} {{- end }} {{- if .Values.copilot.server.livenessProbe }} livenessProbe: {{- toYaml .Values.copilot.server.livenessProbe | nindent 12 }} {{- end }} {{- if .Values.copilot.server.readinessProbe }} readinessProbe: {{- toYaml .Values.copilot.server.readinessProbe | nindent 12 }} {{- end }} {{- with .Values.copilot.server.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} {{- include "sim.containerSecurityContext" .Values.copilot.server | nindent 10 }} {{- if or .Values.extraVolumeMounts .Values.copilot.server.extraVolumeMounts }} volumeMounts: {{- with .Values.extraVolumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} {{- with .Values.copilot.server.extraVolumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} {{- end }} {{- if or .Values.extraVolumes .Values.copilot.server.extraVolumes }} volumes: {{- with .Values.extraVolumes }} {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.copilot.server.extraVolumes }} {{- toYaml . | nindent 8 }} {{- end }} {{- end }} {{- end }}