{{- /* Copyright VMware, Inc. SPDX-License-Identifier: APACHE-2.0 */}} {{- if and .Values.web.enabled (include "concourse.host" .) }} apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} kind: Deployment metadata: name: {{ template "concourse.web.fullname" . }} namespace: {{ .Release.Namespace | quote }} labels: {{- include "common.labels.standard" . | nindent 4 }} app.kubernetes.io/component: web {{- if .Values.commonLabels }} {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} {{- end }} {{- if .Values.commonAnnotations }} annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} {{- end }} spec: replicas: {{ .Values.web.replicaCount }} {{- if .Values.web.updateStrategy }} strategy: {{- toYaml .Values.web.updateStrategy | nindent 4 }} {{- end }} selector: matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} app.kubernetes.io/component: web template: metadata: {{- if .Values.web.podAnnotations }} annotations: {{- include "common.tplvalues.render" (dict "value" .Values.web.podAnnotations "context" $) | nindent 8 }} {{- end }} labels: {{- include "common.labels.standard" . | nindent 8 }} app.kubernetes.io/component: web {{- if .Values.web.podLabels }} {{- include "common.tplvalues.render" (dict "value" .Values.web.podLabels "context" $) | nindent 8 }} {{- end }} spec: {{- include "concourse.imagePullSecrets" . | nindent 6 }} {{- if .Values.web.hostAliases }} hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.web.hostAliases "context" $) | nindent 8 }} {{- end }} {{- if .Values.web.affinity }} affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.web.affinity "context" $) | nindent 8 }} {{- else }} affinity: podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.web.podAffinityPreset "component" "web" "context" $) | nindent 10 }} podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.web.podAntiAffinityPreset "component" "web" "context" $) | nindent 10 }} nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.web.nodeAffinityPreset.type "key" .Values.web.nodeAffinityPreset.key "values" .Values.web.nodeAffinityPreset.values) | nindent 10 }} {{- end }} {{- if .Values.web.nodeSelector }} nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.web.nodeSelector "context" $) | nindent 8 }} {{- end }} {{- if .Values.web.tolerations }} tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.web.tolerations "context" $) | nindent 8 }} {{- end }} {{- if .Values.web.topologySpreadConstraints }} topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.web.topologySpreadConstraints "context" .) | nindent 8 }} {{- end }} {{- if .Values.web.priorityClassName }} priorityClassName: {{ .Values.web.priorityClassName }} {{- end }} {{- if .Values.web.schedulerName }} schedulerName: {{ .Values.web.schedulerName | quote }} {{- end }} {{- if .Values.web.terminationGracePeriodSeconds }} terminationGracePeriodSeconds: {{ .Values.web.terminationGracePeriodSeconds }} {{- end }} {{- if .Values.web.podSecurityContext.enabled }} securityContext: {{- omit .Values.web.podSecurityContext "enabled" | toYaml | nindent 8 }} {{- end }} serviceAccountName: {{ template "concourse.web.serviceAccountName" . }} initContainers: {{- if .Values.postgresql.enabled }} # NOTE: The value postgresql.image is not available unless postgresql.enabled is not set. We could change this to use os-shell if # it had the binary wait-for-port. # This init container is for avoiding CrashLoopback errors in the Hub container because the PostgreSQL container is not ready - name: wait-for-db image: {{ include "common.images.image" (dict "imageRoot" .Values.postgresql.image "global" .Values.global) }} imagePullPolicy: {{ .Values.postgresql.image.pullPolicy }} command: - /bin/bash args: - -ec - | #!/bin/bash set -o errexit set -o nounset set -o pipefail . /opt/bitnami/scripts/libos.sh . /opt/bitnami/scripts/liblog.sh . /opt/bitnami/scripts/libpostgresql.sh check_postgresql_connection() { echo "SELECT 1" | postgresql_remote_execute "$POSTGRESQL_CLIENT_DATABASE_HOST" "$POSTGRESQL_CLIENT_DATABASE_PORT_NUMBER" "$POSTGRESQL_CLIENT_DATABASE_NAME" "$POSTGRESQL_CLIENT_POSTGRES_USER" "$POSTGRESQL_CLIENT_CREATE_DATABASE_PASSWORD" } info "Connecting to the PostgreSQL instance $POSTGRESQL_CLIENT_DATABASE_HOST:$POSTGRESQL_CLIENT_DATABASE_PORT_NUMBER" if ! retry_while "check_postgresql_connection"; then error "Could not connect to the database server" return 1 else info "Connected to the PostgreSQL instance" fi {{- if .Values.web.containerSecurityContext.enabled }} securityContext: {{- omit .Values.web.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} env: - name: POSTGRESQL_CLIENT_DATABASE_HOST value: {{ include "concourse.database.host" . }} - name: POSTGRESQL_CLIENT_DATABASE_NAME value: {{ include "concourse.database.name" . }} - name: POSTGRESQL_CLIENT_DATABASE_PORT_NUMBER value: {{ include "concourse.database.port" . }} - name: POSTGRESQL_CLIENT_CREATE_DATABASE_PASSWORD valueFrom: secretKeyRef: name: {{ include "concourse.postgresql.secretName" . }} key: {{ include "concourse.database.existingsecret.key" . }} - name: POSTGRESQL_CLIENT_POSTGRES_USER value: {{ include "concourse.database.user" . }} {{- end }} - name: db-migrate image: {{ template "concourse.image" . }} imagePullPolicy: {{ .Values.image.pullPolicy }} command: - /opt/bitnami/concourse/bin/concourse args: - migrate - --migrate-to-latest-version env: - name: CONCOURSE_POSTGRES_PASSWORD valueFrom: secretKeyRef: name: {{ include "concourse.postgresql.secretName" . }} key: {{ include "concourse.database.existingsecret.key" . }} - name: CONCOURSE_POSTGRES_DATABASE value: {{ include "concourse.database.name" . }} - name: CONCOURSE_POSTGRES_HOST value: {{ include "concourse.database.host" . }} - name: CONCOURSE_POSTGRES_PORT value: {{ include "concourse.database.port" . }} - name: CONCOURSE_POSTGRES_USER value: {{ include "concourse.database.user" . }} {{- if .Values.web.initContainers }} {{- include "common.tplvalues.render" (dict "value" .Values.web.initContainers "context" $) | nindent 8 }} {{- end }} containers: - name: concourse image: {{ template "concourse.image" . }} imagePullPolicy: {{ .Values.image.pullPolicy }} {{- if .Values.web.lifecycleHooks }} lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.web.lifecycleHooks "context" $) | nindent 12 }} {{- end }} {{- if .Values.web.containerSecurityContext.enabled }} securityContext: {{- omit .Values.web.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} {{- if .Values.diagnosticMode.enabled }} command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} {{- else if .Values.web.command }} command: {{- include "common.tplvalues.render" (dict "value" .Values.web.command "context" $) | nindent 12 }} {{- else }} command: - /opt/bitnami/concourse/bin/concourse {{- end }} {{- if .Values.diagnosticMode.enabled }} args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} {{- else if .Values.web.args }} args: {{- include "common.tplvalues.render" (dict "value" .Values.web.args "context" $) | nindent 12 }} {{- else }} args: - web {{- end }} env: {{- if .Values.web.tsa.logLevel }} - name: CONCOURSE_TSA_LOG_LEVEL value: {{ .Values.web.tsa.logLevel | quote }} {{- end }} {{- if .Values.web.bindIp }} - name: CONCOURSE_BIND_IP value: {{ .Values.web.bindIp | quote }} {{- end }} {{- if .Values.web.tsa.bindIp }} - name: CONCOURSE_TSA_BIND_IP value: {{ .Values.web.tsa.bindIp | quote }} {{- end }} - name: CONCOURSE_TSA_BIND_PORT value: {{ .Values.web.containerPorts.tsa | quote }} {{- if .Values.web.tsa.debugBindIp }} - name: CONCOURSE_TSA_DEBUG_BIND_IP value: {{ .Values.web.tsa.debugBindIp | quote }} {{- end }} {{- if .Values.web.containerPorts.pprof }} - name: CONCOURSE_TSA_DEBUG_BIND_PORT value: {{ .Values.web.containerPorts.pprof | quote }} {{- end }} - name: CONCOURSE_BIND_PORT value: {{ .Values.web.containerPorts.http | quote }} - name: CONCOURSE_TSA_HOST_KEY value: "/bitnami/concourse/concourse-keys/host_key" - name: CONCOURSE_TSA_AUTHORIZED_KEYS value: "/bitnami/concourse/concourse-keys/worker_key.pub" - name: CONCOURSE_SESSION_SIGNING_KEY value: "/bitnami/concourse/concourse-keys/session_signing_key" {{- if .Values.web.logLevel }} - name: CONCOURSE_LOG_LEVEL value: {{ .Values.web.logLevel | quote }} {{- end }} {{- if .Values.web.tsa.heartbeatInterval }} - name: CONCOURSE_TSA_HEARTBEAT_INTERVAL value: {{ .Values.web.tsa.heartbeatInterval | quote }} {{- end }} - name: CONCOURSE_EXTERNAL_URL value: {{ include "concourse.host" . | quote }} - name: CONCOURSE_BIND_PORT value: {{ .Values.web.containerPorts.http | quote }} {{- if .Values.web.peerAddress }} - name: CONCOURSE_PEER_ADDRESS value: {{ .Values.web.peerAddress | quote }} {{- else }} - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: CONCOURSE_PEER_ADDRESS value: "$(POD_IP)" {{- end }} {{- if .Values.web.auth.mainTeam.localUser }} - name: CONCOURSE_MAIN_TEAM_LOCAL_USER value: {{ .Values.web.auth.mainTeam.localUser | quote }} {{- end }} {{- if .Values.web.auth.mainTeam.config }} - name: CONCOURSE_MAIN_TEAM_CONFIG value: /bitnami/concourse/conf/main-team.yml {{- end }} {{- if .Values.web.configRBAC }} - name: CONCOURSE_CONFIG_RBAC value: /bitnami/concourse/conf/config-rbac.yml {{- end }} {{- if .Values.web.baseResourceTypeDefaults }} - name: CONCOURSE_BASE_RESOURCE_TYPE_DEFAULTS value: /bitnami/concourse/conf/brt-defaults.yml {{- end }} {{- if .Values.secrets.localAuth.enabled }} - name: CONCOURSE_ADD_LOCAL_USER valueFrom: secretKeyRef: name: {{ template "concourse.web.fullname" . }} key: local_users {{- end }} {{- if .Values.web.clusterName }} - name: CONCOURSE_CLUSTER_NAME value: {{ .Values.web.clusterName | quote }} {{- end }} {{- if .Values.web.extraEnvVars }} {{- include "common.tplvalues.render" (dict "value" .Values.web.extraEnvVars "context" $) | nindent 12 }} {{- end }} {{- if .Values.web.enablePipelineInstances }} - name: CONCOURSE_ENABLE_PIPELINE_INSTANCES value: {{ .Values.web.enablePipelineInstances | quote }} {{- end }} {{- if .Values.web.enableAcrossStep }} - name: CONCOURSE_ENABLE_ACROSS_STEP value: {{ .Values.web.enableAcrossStep | quote }} {{- end }} {{- if .Values.web.auth.cookieSecure }} - name: CONCOURSE_COOKIE_SECURE value: {{ .Values.web.auth.cookieSecure | quote }} {{- end }} {{- if .Values.web.auth.duration }} - name: CONCOURSE_AUTH_DURATION value: {{ .Values.web.auth.duration | quote }} {{- end }} {{- if .Values.web.auth.passwordConnector }} - name: CONCOURSE_PASSWORD_CONNECTOR value: {{ .Values.web.auth.passwordConnector | quote }} {{- end }} {{- if .Values.web.enableCacheStreamedVolumes }} - name: CONCOURSE_ENABLE_CACHE_STREAMED_VOLUMES value: {{ .Values.web.enableCacheStreamedVolumes | quote }} {{- end }} {{- if .Values.web.tsa.gardenRequestTimeout }} - name: CONCOURSE_TSA_GARDEN_REQUEST_TIMEOUT value: {{ .Values.web.tsa.gardenRequestTimeout | quote }} {{- end }} - name: CONCOURSE_POSTGRES_PASSWORD valueFrom: secretKeyRef: name: {{ include "concourse.postgresql.secretName" . }} key: {{ include "concourse.database.existingsecret.key" . }} - name: CONCOURSE_POSTGRES_DATABASE value: {{ include "concourse.database.name" . }} - name: CONCOURSE_POSTGRES_HOST value: {{ include "concourse.database.host" . }} - name: CONCOURSE_POSTGRES_PORT value: {{ include "concourse.database.port" . }} - name: CONCOURSE_POSTGRES_USER value: {{ include "concourse.database.user" . }} {{- if .Values.web.conjur.enabled }} - name: CONCOURSE_CONJUR_APPLIANCE_URL value: {{ .Values.web.conjur.applianceUrl | quote }} - name: CONCOURSE_CONJUR_ACCOUNT valueFrom: secretKeyRef: name: {{ template "concourse.web.fullname" . }} key: conjur_account {{- if .Values.secrets.conjurCACert }} - name: CONCOURSE_CONJUR_CERT_FILE value: "/bitnami/concourse/conjur-keys/ca.cert" {{- end }} - name: CONCOURSE_CONJUR_AUTHN_LOGIN valueFrom: secretKeyRef: name: {{ template "concourse.web.fullname" . }} key: conjur_authn_login - name: CONCOURSE_CONJUR_AUTHN_API_KEY valueFrom: secretKeyRef: name: {{ template "concourse.web.fullname" . }} key: conjur_authn_api_key {{- if (empty .Values.secrets.conjurAuthnApiKey) }} - name: CONCOURSE_CONJUR_AUTHN_TOKEN_FILE valueFrom: secretKeyRef: name: {{ template "concourse.web.fullname" . }} key: conjur_authn_token_file {{- end }} - name: CONCOURSE_CONJUR_PIPELINE_SECRET_TEMPLATE value: {{ .Values.web.conjur.pipelineSecretTemplate | quote }} - name: CONCOURSE_CONJUR_TEAM_SECRET_TEMPLATE value: {{ .Values.web.conjur.teamSecretTemplate | quote }} - name: CONCOURSE_CONJUR_SECRET_TEMPLATE value: {{ .Values.web.conjur.secretTemplate | quote }} {{- end }} envFrom: {{- if .Values.web.extraEnvVarsCM }} - configMapRef: name: {{ include "common.tplvalues.render" (dict "value" .Values.web.extraEnvVarsCM "context" $) }} {{- end }} {{- if .Values.web.extraEnvVarsSecret }} - secretRef: name: {{ include "common.tplvalues.render" (dict "value" .Values.web.extraEnvVarsSecret "context" $) }} {{- end }} ports: - name: http containerPort: {{ .Values.web.containerPorts.http }} - name: tsa containerPort: {{ .Values.web.containerPorts.tsa }} {{- if .Values.web.tls.enabled }} - name: https containerPort: {{ .Values.web.containerPorts.https }} {{- end }} {{- if .Values.web.containerPorts.tsa }} - name: http-debug containerPort: {{ .Values.web.containerPorts.tsa }} {{- end }} {{- if .Values.web.resources }} resources: {{- toYaml .Values.web.resources | nindent 12 }} {{- end }} {{- if not .Values.diagnosticMode.enabled }} {{- if .Values.web.customStartupProbe }} startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.web.customStartupProbe "context" $) | nindent 12 }} {{- else if .Values.web.startupProbe.enabled }} startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.web.startupProbe "enabled") "context" $) | nindent 12 }} tcpSocket: port: http {{- end }} {{- if .Values.web.customLivenessProbe }} livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.web.customLivenessProbe "context" $) | nindent 12 }} {{- else if .Values.web.livenessProbe.enabled }} livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.web.livenessProbe "enabled") "context" $) | nindent 12 }} httpGet: path: {{ .Values.web.baseUrl | trimSuffix "/" }}/api/v1/info port: http {{- end }} {{- if .Values.web.customReadinessProbe }} readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.web.customReadinessProbe "context" $) | nindent 12 }} {{- else if .Values.web.readinessProbe.enabled }} readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.web.readinessProbe "enabled") "context" $) | nindent 12 }} httpGet: path: {{ .Values.web.baseUrl | trimSuffix "/" }}/api/v1/info port: http {{- end }} {{- end }} volumeMounts: - name: concourse-keys mountPath: /bitnami/concourse/concourse-keys readOnly: true {{- if .Values.secrets.teamAuthorizedKeys }} - name: team-authorized-keys mountPath: /bitnami/concourse/team-authorized-keys readOnly: true {{- end }} {{- if .Values.web.conjur.enabled }} - name: conjur-keys mountPath: /bitnami/concourse/conjur-keys readOnly: true {{- end }} {{- if .Values.web.extraVolumeMounts }} {{- include "common.tplvalues.render" (dict "value" .Values.web.extraVolumeMounts "context" $) | nindent 12 }} {{- end }} {{- if .Values.web.sidecars }} {{- include "common.tplvalues.render" ( dict "value" .Values.web.sidecars "context" $) | nindent 8 }} {{- end }} volumes: - name: concourse-configuration configMap: name: {{ include "concourse.web.configmapName" . }} - name: concourse-keys secret: secretName: {{ include "concourse.web.secretName" . }} defaultMode: 0400 items: - key: host_key path: host_key - key: session_signing_key path: session_signing_key - key: worker_key.pub path: worker_key.pub {{- if .Values.secrets.teamAuthorizedKeys }} - name: team-authorized-keys secret: secretName: {{ include "concourse.web.secretName" }} defaultMode: 0400 {{- end }} {{- if .Values.web.extraVolumes }} {{- include "common.tplvalues.render" (dict "value" .Values.web.extraVolumes "context" $) | nindent 8 }} {{- end }} {{- if .Values.web.conjur.enabled }} - name: conjur-keys secret: secretName: {{ template "concourse.web.fullname" . }} defaultMode: 0400 items: - key: conjur_account path: conjur_account - key: conjur_authn_api_key path: conjur_authn_api_key - key: conjur_authn_login path: conjur_authn_login - key: conjur_authn_token_file path: conjur_authn_token_file {{- if .Values.secrets.conjurCACert }} - key: conjur_ca_cert path: ca.cert {{- end }} {{- end }} {{- end }}