diff --git a/charts/templates/deployment.yaml b/charts/templates/deployment.yaml index fd1e55e..7a29c47 100644 --- a/charts/templates/deployment.yaml +++ b/charts/templates/deployment.yaml @@ -37,10 +37,20 @@ spec: - name: db-migrate image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} - command: ["/app/hyperfleet-api", "migrate"] + command: + - /app/hyperfleet-api + - migrate + {{- if and .Values.database.external.enabled .Values.database.external.usePodIdentity }} + - --db-host-file={{ .Values.database.external.secretMountPath }}/db.host + - --db-port-file={{ .Values.database.external.secretMountPath }}/db.port + - --db-name-file={{ .Values.database.external.secretMountPath }}/db.name + - --db-user-file={{ .Values.database.external.secretMountPath }}/db.user + - --db-password-file={{ .Values.database.external.secretMountPath }}/db.password + - --db-sslmode={{ .Values.database.external.sslMode | default "require" }} + {{- end }} volumeMounts: - name: secrets - mountPath: /build/secrets + mountPath: {{ if and .Values.database.external.enabled .Values.database.external.usePodIdentity }}{{ .Values.database.external.secretMountPath }}{{ else }}/build/secrets{{ end }} readOnly: true {{- end }} containers: @@ -55,6 +65,14 @@ spec: - --api-server-bindaddress={{ .Values.server.bindAddress | default ":8000" }} - --health-server-bindaddress={{ .Values.server.healthBindAddress | default ":8080" }} - --metrics-server-bindaddress={{ .Values.server.metricsBindAddress | default ":9090" }} + {{- if and .Values.database.external.enabled .Values.database.external.usePodIdentity }} + - --db-host-file={{ .Values.database.external.secretMountPath }}/db.host + - --db-port-file={{ .Values.database.external.secretMountPath }}/db.port + - --db-name-file={{ .Values.database.external.secretMountPath }}/db.name + - --db-user-file={{ .Values.database.external.secretMountPath }}/db.user + - --db-password-file={{ .Values.database.external.secretMountPath }}/db.password + - --db-sslmode={{ .Values.database.external.sslMode | default "require" }} + {{- end }} ports: - name: http containerPort: 8000 @@ -113,7 +131,7 @@ spec: mountPath: /tmp {{- if or .Values.database.external.enabled .Values.database.postgresql.enabled }} - name: secrets - mountPath: /build/secrets + mountPath: {{ if and .Values.database.external.enabled .Values.database.external.usePodIdentity }}{{ .Values.database.external.secretMountPath }}{{ else }}/build/secrets{{ end }} readOnly: true {{- end }} {{- if .Values.extraVolumeMounts }} @@ -124,6 +142,13 @@ spec: emptyDir: {} {{- if or .Values.database.external.enabled .Values.database.postgresql.enabled }} - name: secrets + {{- if and .Values.database.external.enabled .Values.database.external.usePodIdentity }} + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: {{ ternary (printf "%s-db-secrets" (include "hyperfleet-api.fullname" .)) .Values.database.external.secretProviderClass .Values.database.external.createSecretProviderClass | quote }} + {{- else }} secret: {{- if .Values.database.external.enabled }} secretName: {{ .Values.database.external.secretName }} @@ -131,6 +156,7 @@ spec: secretName: {{ include "hyperfleet-api.fullname" . }}-db-secrets {{- end }} {{- end }} + {{- end }} {{- if .Values.extraVolumes }} {{- toYaml .Values.extraVolumes | nindent 6 }} {{- end }} diff --git a/charts/templates/secretproviderclass.yaml b/charts/templates/secretproviderclass.yaml new file mode 100644 index 0000000..d66a0fb --- /dev/null +++ b/charts/templates/secretproviderclass.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.database.external.enabled .Values.database.external.usePodIdentity .Values.database.external.createSecretProviderClass }} +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: {{ include "hyperfleet-api.fullname" . }}-db-secrets + namespace: {{ .Release.Namespace }} + labels: + {{- include "hyperfleet-api.labels" . | nindent 4 }} +spec: + provider: aws + parameters: + usePodIdentity: "true" + region: {{ .Values.database.external.aws.region | quote }} + objects: | + - objectName: {{ .Values.database.external.aws.secretName | quote }} + objectType: "secretsmanager" + jmesPath: + - path: "username" + objectAlias: "db.user" + - path: "password" + objectAlias: "db.password" + - path: "host" + objectAlias: "db.host" + - path: "port" + objectAlias: "db.port" + - path: "database" + objectAlias: "db.name" +{{- end }} diff --git a/charts/values.yaml b/charts/values.yaml index 0b1717c..8b05c5c 100644 --- a/charts/values.yaml +++ b/charts/values.yaml @@ -93,6 +93,21 @@ database: enabled: false # Name of existing secret with db.host, db.port, db.name, db.user, db.password keys secretName: "" + # Use AWS Pod Identity / Secrets Store CSI driver for DB credentials (no Kubernetes Secret) + usePodIdentity: false + # Mount path for CSI secrets-store volume (when usePodIdentity is true) + secretMountPath: /mnt/secrets-store + # Name of SecretProviderClass for CSI secrets-store driver (required when usePodIdentity is true and createSecretProviderClass is false) + secretProviderClass: "" + # Create a SecretProviderClass from the chart (uses database.external.aws when true) + createSecretProviderClass: false + # AWS Secrets Manager config when createSecretProviderClass is true + aws: + region: "" + # Secrets Manager secret name or ARN (objectName in SecretProviderClass) + secretName: "hyperfleet/db-credentials" + # PostgreSQL SSL mode: disable | require | verify-ca | verify-full + sslMode: require # Built-in PostgreSQL for development/testing postgresql: @@ -126,15 +141,12 @@ auth: # Adapter configuration (REQUIRED) # Configure which adapters must be ready for resources to be marked as "Ready" -# Both cluster and nodepool adapters MUST be specified - the application will not start without them -# Empty arrays [] are valid if you want no adapters required for the Ready state +# Both cluster and nodepool MUST be specified (empty arrays [] are valid) adapters: - # Required adapters for cluster "Ready" state (REQUIRED) - # Example: ["validation", "dns", "pullsecret", "hypershift"] - # cluster: [] - # Required adapters for nodepool "Ready" state (REQUIRED) - # Example: ["validation", "hypershift"] - # nodepool: [] + # Required adapters for cluster "Ready" state. Example: ["validation", "dns", "pullsecret", "hypershift"] + cluster: [] + # Required adapters for nodepool "Ready" state. Example: ["validation", "hypershift"] + nodepool: [] # ServiceMonitor for Prometheus Operator # Enables automatic metrics discovery in clusters with Prometheus Operator @@ -155,8 +167,8 @@ serviceMonitor: # Additional environment variables # You can override adapters by setting HYPERFLEET_*_ADAPTERS here env: [] - # - name: GLOG_V - # value: "10" +# - name: GLOG_V +# value: "10" # Volume mounts for additional configs extraVolumeMounts: []