From f858177780316e82b27a2e8c5db5435c2e21a94e Mon Sep 17 00:00:00 2001 From: Martina Iglesias Fernandez Date: Mon, 5 Oct 2020 17:29:25 +0200 Subject: [PATCH] feat: add basic Helm charts for deploying backstage --- contrib/chart/backstage/Chart.lock | 6 + contrib/chart/backstage/Chart.yaml | 30 ++ contrib/chart/backstage/README.md | 1 + .../backstage/files/create-backend-dbs.sql | 11 + .../chart/backstage/templates/_helpers.tpl | 279 ++++++++++++++++++ .../templates/backend-deployment.yaml | 71 +++++ .../backstage/templates/backend-secret.yaml | 20 ++ .../templates/backstage-app-config.yaml | 27 ++ .../templates/backstage-auth-config.yaml | 19 ++ .../templates/frontend-deployment.yaml | 51 ++++ .../chart/backstage/templates/ingress.yaml | 37 +++ .../templates/lighthouse-config.yaml | 10 + .../templates/lighthouse-deployment.yaml | 72 +++++ .../templates/postgresql-ca-config.yaml | 21 ++ .../templates/postgresql-certs-secret.yaml | 16 + .../templates/postgresql-initdb-secret.yaml | 14 + .../templates/postgresql-password-secret.yaml | 30 ++ .../templates/tests/test-app-connection.yaml | 23 ++ .../templates/tests/test-postgresql.yaml | 33 +++ contrib/chart/backstage/values.yaml | 240 +++++++++++++++ 20 files changed, 1011 insertions(+) create mode 100644 contrib/chart/backstage/Chart.lock create mode 100644 contrib/chart/backstage/Chart.yaml create mode 100644 contrib/chart/backstage/README.md create mode 100644 contrib/chart/backstage/files/create-backend-dbs.sql create mode 100644 contrib/chart/backstage/templates/_helpers.tpl create mode 100644 contrib/chart/backstage/templates/backend-deployment.yaml create mode 100644 contrib/chart/backstage/templates/backend-secret.yaml create mode 100644 contrib/chart/backstage/templates/backstage-app-config.yaml create mode 100644 contrib/chart/backstage/templates/backstage-auth-config.yaml create mode 100644 contrib/chart/backstage/templates/frontend-deployment.yaml create mode 100644 contrib/chart/backstage/templates/ingress.yaml create mode 100644 contrib/chart/backstage/templates/lighthouse-config.yaml create mode 100644 contrib/chart/backstage/templates/lighthouse-deployment.yaml create mode 100644 contrib/chart/backstage/templates/postgresql-ca-config.yaml create mode 100644 contrib/chart/backstage/templates/postgresql-certs-secret.yaml create mode 100644 contrib/chart/backstage/templates/postgresql-initdb-secret.yaml create mode 100644 contrib/chart/backstage/templates/postgresql-password-secret.yaml create mode 100644 contrib/chart/backstage/templates/tests/test-app-connection.yaml create mode 100644 contrib/chart/backstage/templates/tests/test-postgresql.yaml create mode 100644 contrib/chart/backstage/values.yaml diff --git a/contrib/chart/backstage/Chart.lock b/contrib/chart/backstage/Chart.lock new file mode 100644 index 0000000000..e390bf21ba --- /dev/null +++ b/contrib/chart/backstage/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 9.4.1 +digest: sha256:f949ec0fe7d146610ce2ee78fbfb4e52d235883a797968b0a1e61aa88ada2786 +generated: "2020-09-25T08:59:54.255582519+02:00" diff --git a/contrib/chart/backstage/Chart.yaml b/contrib/chart/backstage/Chart.yaml new file mode 100644 index 0000000000..92b5e3e309 --- /dev/null +++ b/contrib/chart/backstage/Chart.yaml @@ -0,0 +1,30 @@ +apiVersion: v2 +name: backstage +description: A Helm chart for Spotify Backstage +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. +appVersion: v0.1.1-alpha.23 + +sources: + - https://github.com/spotify/backstage + - https://github.com/spotify/lighthouse-audit-service + +dependencies: + - name: postgresql + condition: postgresql.enabled + version: 9.4.1 + repository: https://charts.bitnami.com/bitnami + +maintainers: + - name: Martina Iglesias Fernandez + email: martina@roadie.io + url: https://roadie.io + - name: David Tuite + email: david@roadie.io + url: https://roadie.io diff --git a/contrib/chart/backstage/README.md b/contrib/chart/backstage/README.md new file mode 100644 index 0000000000..bb2ff84411 --- /dev/null +++ b/contrib/chart/backstage/README.md @@ -0,0 +1 @@ +# TO DO diff --git a/contrib/chart/backstage/files/create-backend-dbs.sql b/contrib/chart/backstage/files/create-backend-dbs.sql new file mode 100644 index 0000000000..e8124dbd22 --- /dev/null +++ b/contrib/chart/backstage/files/create-backend-dbs.sql @@ -0,0 +1,11 @@ +{{ $backendDb := .Values.appConfig.backend.database.connection.database }} +{{ $lighthouseDb := .Values.lighthouse.database.connection.database }} +{{ $user := .Values.global.postgresql.postgresqlUsername }} + +create database {{ $backendDb }}; +grant all privileges on database {{ $backendDb }} to {{ $user }}; + +{{ if not (eq $backendDb $lighthouseDb) }} +create database {{ $lighthouseDb }}; +grant all privileges on database {{ $lighthouseDb }} to {{ $user }}; +{{ end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/_helpers.tpl b/contrib/chart/backstage/templates/_helpers.tpl new file mode 100644 index 0000000000..9f3b1cfbdc --- /dev/null +++ b/contrib/chart/backstage/templates/_helpers.tpl @@ -0,0 +1,279 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "backstage.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "backstage.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "backstage.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common App labels +*/}} +{{- define "backstage.app.labels" -}} +app.kubernetes.io/name: {{ include "backstage.name" . }}-app +helm.sh/chart: {{ include "backstage.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Common Backend labels +*/}} +{{- define "backstage.backend.labels" -}} +app.kubernetes.io/name: {{ include "backstage.name" . }}-backend +helm.sh/chart: {{ include "backstage.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Name for postgresql dependency +See https://github.com/helm/helm/issues/3920#issuecomment-686913512 +*/}} +{{- define "backstage.postgresql.fullname" -}} +{{ printf "%s-%s" .Release.Name .Values.postgresql.nameOverride }} +{{- end -}} + + +{{/* +Create the name of the service account to use for the app +*/}} +{{- define "backstage.app.serviceAccountName" -}} +{{- if .Values.app.serviceAccount.create -}} + {{ default "default" .Values.app.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.app.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the backend +*/}} +{{- define "backstage.backend.serviceAccountName" -}} +{{- if .Values.backend.serviceAccount.create -}} + {{ default default .Values.backend.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.backend.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Path to the CA certificate file in the backend +*/}} +{{- define "backstage.backend.postgresCaFilename" -}} +{{ include "backstage.backend.postgresCaDir" . }}/{{- required "The name for the CA certificate file for postgresql is required" .Values.global.postgresql.caFilename }} +{{- end -}} +{{/* + +{{/* +Directory path to the CA certificate file in the backend +*/}} +{{- define "backstage.backend.postgresCaDir" -}} +{{- if .Values.appConfig.backend.database.connection.ssl.ca -}} + {{ .Values.appConfig.backend.database.connection.ssl.ca }} +{{- else -}} +/etc/postgresql +{{- end -}} +{{- end -}} +{{/* + +Path to the CA certificate file in lighthouse +*/}} +{{- define "backstage.lighthouse.postgresCaFilename" -}} +{{ include "backstage.lighthouse.postgresCaDir" . }}/{{- required "The name for the CA certificate file for postgresql is required" .Values.global.postgresql.caFilename }} +{{- end -}} + +{{/* +Directory path to the CA certificate file in lighthouse +*/}} +{{- define "backstage.lighthouse.postgresCaDir" -}} +{{- if .Values.lighthouse.database.pathToDatabaseCa -}} + {{ .Values.lighthouse.database.pathToDatabaseCa }} +{{- else -}} +/etc/postgresql +{{- end -}} +{{- end -}} +{{/* + +{{/* +Generate ca for postgresql +*/}} +{{- define "backstage.postgresql.generateCA" -}} +{{- $ca := .ca | default (genCA (include "backstage.postgresql.fullname" .) 365) -}} +{{- $_ := set . "ca" $ca -}} +{{- $ca.Cert -}} +{{- end -}} + +{{/* +Generate certificates for postgresql +*/}} +{{- define "generateCerts" -}} +{{- $postgresName := (include "backstage.postgresql.fullname" .) }} +{{- $altNames := list $postgresName ( printf "%s.%s" $postgresName .Release.Namespace ) ( printf "%s.%s.svc" ( $postgresName ) .Release.Namespace ) -}} +{{- $ca := .ca | default (genCA (include "backstage.postgresql.fullname" .) 365) -}} +{{- $_ := set . "ca" $ca -}} +{{- $cert := genSignedCert ( $postgresName ) nil $altNames 365 $ca -}} +tls.crt: {{ $cert.Cert | b64enc }} +tls.key: {{ $cert.Key | b64enc }} +{{- end -}} + +{{/* +Generate a password for the postgres user used for the connections from the backend and lighthouse +*/}} +{{- define "postgresql.generateUserPassword" -}} +{{- $pgPassword := .pgPassword | default ( randAlphaNum 12 ) -}} +{{- $_ := set . "pgPassword" $pgPassword -}} +{{ $pgPassword}} +{{- end -}} + +{{/* +Name of the backend service +*/}} +{{- define "backend.serviceName" -}} +{{ include "backstage.fullname" . }}-backend +{{- end -}} + +{{/* +Name of the frontend service +*/}} +{{- define "frontend.serviceName" -}} +{{ include "backstage.fullname" . }}-frontend +{{- end -}} + +{{/* +Name of the lighthouse backend service +*/}} +{{- define "lighthouse.serviceName" -}} +{{ include "backstage.fullname" . }}-lighthouse +{{- end -}} + +{{/* +Name of the postgresql service +*/}} +{{- define "postgresql.serviceName" -}} +{{- include "backstage.postgresql.fullname" . }} +{{- end -}} + +{{/* +Postgres host for lighthouse +*/}} +{{- define "lighthouse.postgresql.host" -}} +{{- if .Values.postgresql.enabled }} +{{- include "postgresql.serviceName" . }} +{{- else -}} +{{- required "A valid .Values.lighthouse.database.connection.host is required when postgresql is not enabled" .Values.lighthouse.database.connection.host -}} +{{- end -}} +{{- end -}} + +{{/* +Postgres host for the backend +*/}} +{{- define "backend.postgresql.host" -}} +{{- if .Values.postgresql.enabled }} +{{- include "postgresql.serviceName" . }} +{{- else -}} +{{- required "A valid .Values.appConfig.backend.database.connection.host is required when postgresql is not enabled" .Values.appConfig.backend.database.connection.host -}} +{{- end -}} +{{- end -}} + +{{/* +Postgres port for the backend +*/}} +{{- define "backend.postgresql.port" -}} +{{- if .Values.postgresql.enabled }} +{{- .Values.postgresql.service.port }} +{{- else if .Values.appConfig.backend.database.connection.port -}} +{{- .Values.appConfig.backend.database.connection.port }} +{{ else }} +5432 +{{- end -}} +{{- end -}} + +{{/* +Postgres port for lighthouse +*/}} +{{- define "lighthouse.postgresql.port" -}} +{{- if .Values.postgresql.enabled }} +{{- .Values.postgresql.service.port }} +{{- else if .Values.lighthouse.database.connection.port -}} +{{- .Values.lighthouse.database.connection.port }} +{{- else -}} +5432 +{{- end -}} +{{- end -}} + +{{/* +Postgres user for backend +*/}} +{{- define "backend.postgresql.user" -}} +{{- if .Values.postgresql.enabled }} +{{- .Values.global.postgresql.postgresqlUsername }} +{{- else -}} +{{- required "A valid .Values.appConfig.backend.database.connection.user is required when postgresql is not enabled" .Values.appConfig.backend.database.connection.user -}} +{{- end -}} +{{- end -}} + +{{/* +Postgres user for lighthouse +*/}} +{{- define "lighthouse.postgresql.user" -}} +{{- if .Values.postgresql.enabled }} +{{- .Values.global.postgresql.postgresqlUsername }} +{{- else -}} +{{- required "A valid .Values.lighthouse.database.connection.user is required when postgresql is not enabled" .Values.lighthouse.database.connection.user -}} +{{- end -}} +{{- end -}} + +{{/* +Postgres password secret for backend +*/}} +{{- define "backend.postgresql.passwordSecret" -}} +{{- if .Values.postgresql.enabled }} +{{- template "backstage.postgresql.fullname" . }} +{{- else -}} +{{ $secretName := (printf "%s-backend-postgres" (include "backstage.fullname" . )) }} +{{- required "A valid .Values.appConfig.backend.database.connection.password is required when postgresql is not enabled" $secretName -}} +{{- end -}} +{{- end -}} + +{{/* +Postgres password for lighthouse +*/}} +{{- define "lighthouse.postgresql.passwordSecret" -}} +{{- if .Values.postgresql.enabled }} +{{- template "backstage.postgresql.fullname" . }} +{{- else -}} +{{ $secretName := (printf "%s-lighthouse-postgres" (include "backstage.fullname" . )) }} +{{- required "A valid .Values.lighthouse.database.connection.password is required when postgresql is not enabled" $secretName -}} +{{- end -}} +{{- end -}} diff --git a/contrib/chart/backstage/templates/backend-deployment.yaml b/contrib/chart/backstage/templates/backend-deployment.yaml new file mode 100644 index 0000000000..67177d7923 --- /dev/null +++ b/contrib/chart/backstage/templates/backend-deployment.yaml @@ -0,0 +1,71 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "backstage.fullname" . }}-backend + +spec: + replicas: {{ .Values.backend.replicaCount }} + + selector: + matchLabels: + app: backstage + component: backend + + template: + metadata: + annotations: + ad.datadoghq.com/backstage.logs: '[{"source":"backstage","service":"backend"}]' + labels: + app: backstage + component: backend + + spec: + containers: + - name: {{ .Chart.Name }}-backend + image: {{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag }} + imagePullPolicy: {{ .Values.backend.image.pullPolicy }} + ports: + - containerPort: {{ .Values.backend.containerPort }} + resources: + {{- toYaml .Values.backend.resources | nindent 12 }} + + envFrom: + - configMapRef: + name: {{ include "backstage.fullname" . }}-app + - configMapRef: + name: {{ include "backstage.fullname" . }}-auth + - secretRef: + name: {{ include "backstage.fullname" . }}-backend + env: + - name: APP_CONFIG_backend_postgresPassword + valueFrom: + secretKeyRef: + name: {{ include "backend.postgresql.passwordSecret" .}} + key: postgresql-password + volumeMounts: + - name: postgres-ca + mountPath: {{ include "backstage.backend.postgresCaDir" . }} + + volumes: + - name: postgres-ca + configMap: + name: {{ include "backstage.fullname" . }}-postgres-ca + +{{- if .Values.backend.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "backend.serviceName" . }} + +spec: + ports: + - port: 80 + targetPort: {{ .Values.backend.containerPort }} + + selector: + app: backstage + component: backend + + type: ClusterIP +{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/backend-secret.yaml b/contrib/chart/backstage/templates/backend-secret.yaml new file mode 100644 index 0000000000..3acb220d81 --- /dev/null +++ b/contrib/chart/backstage/templates/backend-secret.yaml @@ -0,0 +1,20 @@ +{{- if .Values.backend.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "backstage.fullname" . }}-backend +type: Opaque +stringData: + AUTH_GOOGLE_CLIENT_SECRET: {{ .Values.auth.google.clientSecret }} + AUTH_GITHUB_CLIENT_SECRET: {{ .Values.auth.github.clientSecret }} + AUTH_GITLAB_CLIENT_SECRET: {{ .Values.auth.gitlab.clientSecret }} + AUTH_OKTA_CLIENT_SECRET: {{ .Values.auth.okta.clientSecret }} + AUTH_OAUTH2_CLIENT_SECRET: {{ .Values.auth.oauth2.clientSecret }} + AUTH_AUTH0_CLIENT_SECRET: {{ .Values.auth.auth0.clientSecret }} + AUTH_MICROSOFT_CLIENT_SECRET: {{ .Values.auth.microsoft.clientSecret }} + SENTRY_TOKEN: {{ .Values.auth.sentryToken }} + ROLLBAR_ACCOUNT_TOKEN: {{ .Values.auth.rollbarAccountToken }} + CIRCLECI_AUTH_TOKEN: {{ .Values.auth.circleciAuthToken }} + GITHUB_ACCESS_TOKEN: {{ .Values.auth.githubAccessToken }} + GITLAB_ACCESS_TOKEN: {{ .Values.auth.gitlabAccessToken }} +{{- end }} diff --git a/contrib/chart/backstage/templates/backstage-app-config.yaml b/contrib/chart/backstage/templates/backstage-app-config.yaml new file mode 100644 index 0000000000..be937cee13 --- /dev/null +++ b/contrib/chart/backstage/templates/backstage-app-config.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "backstage.fullname" . }}-app +data: + APP_CONFIG_app_baseUrl: {{ .Values.appConfig.app.baseUrl | quote | quote }} + APP_CONFIG_app_title: {{ .Values.appConfig.app.title | quote | quote }} + APP_CONFIG_backend_baseUrl: {{ .Values.appConfig.backend.baseUrl | quote | quote }} + APP_CONFIG_backend_lighthouseHostname: {{ include "lighthouse.serviceName" . | quote | quote }} + APP_CONFIG_backend_listen: {{ .Values.appConfig.backend.listen | quote | quote }} + APP_CONFIG_backend_cors_origin: {{ .Values.appConfig.backend.cors.origin | quote | quote }} + APP_CONFIG_backend_database_client: {{ .Values.appConfig.backend.database.client | quote | quote }} + APP_CONFIG_backend_database_connection_port: {{ include "backend.postgresql.port" . | quote }} + APP_CONFIG_backend_database_connection_host: {{ include "backend.postgresql.host" . | quote | quote }} + APP_CONFIG_backend_database_connection_user: {{ include "backend.postgresql.user" . | quote | quote }} + APP_CONFIG_backend_database_connection_database: {{ .Values.appConfig.backend.database.connection.database | quote | quote }} + APP_CONFIG_backend_database_connection_ssl_rejectUnauthorized: {{ .Values.appConfig.backend.database.connection.ssl.rejectUnauthorized | quote }} + APP_CONFIG_backend_database_connection_ssl_ca: {{ include "backstage.backend.postgresCaFilename" . | quote | quote }} + APP_CONFIG_sentry_organization: {{ .Values.appConfig.sentry.organization | quote | quote }} + APP_CONFIG_techdocs_storageUrl: {{ .Values.appConfig.techdocs.storageUrl | quote | quote }} + APP_CONFIG_techdocs_requestUrl: {{ .Values.appConfig.techdocs.requestUrl | quote | quote }} + APP_CONFIG_auth_providers_github_development_appOrigin: {{ .Values.appConfig.auth.providers.github.development.appOrigin | quote | quote }} + APP_CONFIG_auth_providers_google_development_appOrigin: {{ .Values.appConfig.auth.providers.google.development.appOrigin | quote | quote }} + APP_CONFIG_auth_providers_gitlab_development_appOrigin: {{ .Values.appConfig.auth.providers.gitlab.development.appOrigin | quote | quote }} + APP_CONFIG_auth_providers_okta_development_appOrigin: {{ .Values.appConfig.auth.providers.okta.development.appOrigin | quote | quote }} + APP_CONFIG_auth_providers_oauth2_development_appOrigin: {{ .Values.appConfig.auth.providers.oauth2.development.appOrigin | quote | quote }} + APP_CONFIG_lighthouse_baseUrl: {{ .Values.appConfig.lighthouse.baseUrl | quote | quote }} diff --git a/contrib/chart/backstage/templates/backstage-auth-config.yaml b/contrib/chart/backstage/templates/backstage-auth-config.yaml new file mode 100644 index 0000000000..5a2023bf3e --- /dev/null +++ b/contrib/chart/backstage/templates/backstage-auth-config.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "backstage.fullname" . }}-auth +data: + AUTH_GOOGLE_CLIENT_ID: {{ .Values.auth.google.clientId }} + AUTH_GITHUB_CLIENT_ID: {{ .Values.auth.github.clientId }} + AUTH_GITLAB_CLIENT_ID: {{ .Values.auth.gitlab.clientId }} + # This should not be prefixed with AUTH_. This could be a typo in the Backstage app config. + GITLAB_BASE_URL: {{ .Values.auth.gitlab.baseUrl }} + AUTH_OKTA_CLIENT_ID: {{ .Values.auth.okta.clientId }} + AUTH_OKTA_AUDIENCE: {{ .Values.auth.okta.audience }} + AUTH_OAUTH2_CLIENT_ID: {{ .Values.auth.oauth2.clientId }} + AUTH_OAUTH2_AUTH_URL: {{ .Values.auth.oauth2.authUrl }} + AUTH_OAUTH2_TOKEN_URL: {{ .Values.auth.oauth2.tokenUrl }} + AUTH_AUTH0_CLIENT_ID: {{ .Values.auth.auth0.clientId }} + AUTH_AUTH0_DOMAIN: {{ .Values.auth.auth0.domain }} + AUTH_MICROSOFT_CLIENT_ID: {{ .Values.auth.microsoft.clientId }} + AUTH_MICROSOFT_TENANT_ID: {{ .Values.auth.microsoft.tenantId }} diff --git a/contrib/chart/backstage/templates/frontend-deployment.yaml b/contrib/chart/backstage/templates/frontend-deployment.yaml new file mode 100644 index 0000000000..b494738758 --- /dev/null +++ b/contrib/chart/backstage/templates/frontend-deployment.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "backstage.fullname" . }}-frontend + +spec: + replicas: {{ .Values.frontend.replicaCount }} + + selector: + matchLabels: + app: backstage + component: frontend + + template: + metadata: + annotations: + ad.datadoghq.com/backstage.logs: '[{"source":"backstage","service":"frontend"}]' + labels: + app: backstage + component: frontend + + spec: + containers: + - name: {{ .Chart.Name }}-frontend + image: {{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag }} + imagePullPolicy: {{ .Values.frontend.image.pullPolicy }} + ports: + - containerPort: {{ .Values.frontend.containerPort }} + resources: + {{- toYaml .Values.backend.resources | nindent 12 }} + envFrom: + - configMapRef: + name: {{ include "backstage.fullname" . }}-app +{{- if .Values.frontend.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "frontend.serviceName" . }} + +spec: + ports: + - port: 80 + targetPort: {{ .Values.frontend.containerPort }} + + selector: + app: backstage + component: frontend + + type: ClusterIP +{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/ingress.yaml b/contrib/chart/backstage/templates/ingress.yaml new file mode 100644 index 0000000000..6996bb5d8d --- /dev/null +++ b/contrib/chart/backstage/templates/ingress.yaml @@ -0,0 +1,37 @@ +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + name: {{ include "backstage.fullname" . }}-ingress-backend + {{- with .Values.ingress.annotations }} + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + - http: + paths: + - backend: + serviceName: {{ include "backend.serviceName" . }} + servicePort: 80 + path: /api(/|$)(.*) +--- +# Having rewrite rules in an ingress with a '/' path results in an error when loading the +# site "Unexpected token: <". That's why we need two ingress resources +# See https://stackoverflow.com/questions/59931177/gke-install-nginx-ingress-with-static-ip-and-fanout +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + name: {{ include "backstage.fullname" . }}-ingress-frontend + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + rules: + - http: + paths: + - backend: + serviceName: {{ include "frontend.serviceName" . }} + servicePort: 80 + path: / diff --git a/contrib/chart/backstage/templates/lighthouse-config.yaml b/contrib/chart/backstage/templates/lighthouse-config.yaml new file mode 100644 index 0000000000..fdf4bd8b06 --- /dev/null +++ b/contrib/chart/backstage/templates/lighthouse-config.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "backstage.fullname" . -}}-lighthouse +data: + PGDATABASE: {{ .Values.lighthouse.database.connection.database | quote }} + PGUSER: {{ include "lighthouse.postgresql.user" . | quote }} + PGPORT: {{ include "lighthouse.postgresql.port" . | quote }} + PGHOST: {{ include "lighthouse.postgresql.host" . | quote }} + PGPATH_TO_CA: {{ include "backstage.lighthouse.postgresCaFilename" . | quote }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/lighthouse-deployment.yaml b/contrib/chart/backstage/templates/lighthouse-deployment.yaml new file mode 100644 index 0000000000..b727f5d242 --- /dev/null +++ b/contrib/chart/backstage/templates/lighthouse-deployment.yaml @@ -0,0 +1,72 @@ +{{- if .Values.lighthouse.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "backstage.fullname" . }}-lighthouse + +spec: + replicas: {{ .Values.lighthouse.replicaCount }} + + selector: + matchLabels: + app: backstage + component: lighthouse-audit-service + + template: + metadata: + annotations: + ad.datadoghq.com/backstage.logs: '[{"source":"backstage","service":"lighthouse"}]' + labels: + app: backstage + component: lighthouse-audit-service + + spec: + containers: + - name: lighthouse-audit-service + image: {{ .Values.lighthouse.image.repository }}:{{ .Values.lighthouse.image.tag }} + imagePullPolicy: {{ .Values.lighthouse.image.pullPolicy }} + ports: + - containerPort: {{ .Values.lighthouse.containerPort }} + resources: + {{- toYaml .Values.lighthouse.resources | nindent 12 }} + + envFrom: + - configMapRef: + name: backstage-lighthouse + + env: + - name: LAS_PORT + value: {{ .Values.lighthouse.containerPort | quote }} + - name: LAS_CORS + value: "true" + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ include "lighthouse.postgresql.passwordSecret" . }} + key: postgresql-password + + volumeMounts: + - name: postgres-ca + mountPath: {{ include "backstage.lighthouse.postgresCaDir" . }} + + volumes: + - name: postgres-ca + configMap: + name: {{ include "backstage.fullname" . }}-postgres-ca +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "lighthouse.serviceName" . }} + +spec: + ports: + - port: 80 + targetPort: {{ .Values.lighthouse.containerPort }} + + selector: + app: backstage + component: lighthouse-audit-service + + type: ClusterIP +{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/postgresql-ca-config.yaml b/contrib/chart/backstage/templates/postgresql-ca-config.yaml new file mode 100644 index 0000000000..2631989f4e --- /dev/null +++ b/contrib/chart/backstage/templates/postgresql-ca-config.yaml @@ -0,0 +1,21 @@ +{{- if .Values.postgresql.enabled }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "backstage.fullname" . }}-postgres-ca + labels: + app: {{ include "backstage.postgresql.fullname" . }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" +data: + {{ .Values.global.postgresql.caFilename }}: | +{{ include "backstage.postgresql.generateCA" . | indent 4}} +{{- else }} +{{- $caConfig := printf "%s-postgres-ca" (include "backstage.fullname" .) }} +{{- if not ( lookup "v1" "ConfigMap" .Release.Namespace $caConfig ) }} +{{- fail (printf "\n\nPlease create the '%s' configmap with the CA certificate for your existing postgresql: kubectl create configmap %s --from-file=ca.crt" $caConfig $caConfig) }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/postgresql-certs-secret.yaml b/contrib/chart/backstage/templates/postgresql-certs-secret.yaml new file mode 100644 index 0000000000..c6845caa7e --- /dev/null +++ b/contrib/chart/backstage/templates/postgresql-certs-secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.postgresql.enabled }} +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/tls +metadata: + name: {{ required ".Values.postgresql.tls.certificatesSecret is required" .Values.postgresql.tls.certificatesSecret }} + labels: + app: {{ include "backstage.postgresql.fullname" . }} + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" +data: +{{ include "generateCerts" . | indent 2 }} +{{- end }} diff --git a/contrib/chart/backstage/templates/postgresql-initdb-secret.yaml b/contrib/chart/backstage/templates/postgresql-initdb-secret.yaml new file mode 100644 index 0000000000..d1c446f79f --- /dev/null +++ b/contrib/chart/backstage/templates/postgresql-initdb-secret.yaml @@ -0,0 +1,14 @@ +{{- if .Values.postgresql.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ required ".Values.postgresql.initdbScriptsSecret is required" .Values.postgresql.initdbScriptsSecret }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" +type: Opaque +data: + create-backend-dbs.sql: | + {{ tpl (.Files.Get "files/create-backend-dbs.sql") . | b64enc }} +{{- end }} + diff --git a/contrib/chart/backstage/templates/postgresql-password-secret.yaml b/contrib/chart/backstage/templates/postgresql-password-secret.yaml new file mode 100644 index 0000000000..7e72888607 --- /dev/null +++ b/contrib/chart/backstage/templates/postgresql-password-secret.yaml @@ -0,0 +1,30 @@ +{{- if not .Values.postgresql.enabled }} +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "backend.postgresql.passwordSecret" . }} + labels: + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" +data: + postgresql-password: {{ .Values.appConfig.backend.database.connection.password }} +{{- end }} +{{- if not .Values.postgresql.enabled }} +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "lighthouse.postgresql.passwordSecret" . }} + labels: + release: {{ .Release.Name }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" +data: + postgresql-password: {{ .Values.lighthouse.database.connection.password }} +{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/templates/tests/test-app-connection.yaml b/contrib/chart/backstage/templates/tests/test-app-connection.yaml new file mode 100644 index 0000000000..93f51f3f09 --- /dev/null +++ b/contrib/chart/backstage/templates/tests/test-app-connection.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "backstage.fullname" . -}}-test-app-connection + annotations: + "helm.sh/hook": test +spec: + containers: + - name: test-app + image: busybox + command: + - /bin/sh + - -ecx + - | + echo -e "===== Testing the connection with the frontend...\n" + wget -q -O - {{ printf "%s.%s" (include "frontend.serviceName" .) .Release.Namespace | quote }} + echo -e "\n\n===== Testing the connection with the backend...\n" + wget -q -O - {{ printf "http://%s.%s/catalog/entities" (include "backend.serviceName" .) .Release.Namespace | quote }} + echo -e "\n\n===== Testing the connection with the lighthouse plugin...\n" + wget -q -O - {{ printf "%s.%s/v1/audits" (include "lighthouse.serviceName" .) .Release.Namespace | quote }} + echo -e "\n" + restartPolicy: Never \ No newline at end of file diff --git a/contrib/chart/backstage/templates/tests/test-postgresql.yaml b/contrib/chart/backstage/templates/tests/test-postgresql.yaml new file mode 100644 index 0000000000..8eec1db452 --- /dev/null +++ b/contrib/chart/backstage/templates/tests/test-postgresql.yaml @@ -0,0 +1,33 @@ +{{- if .Values.postgresql.enabled}} +--- +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "backstage.name" . -}}-test-postgres + annotations: + "helm.sh/hook": test +spec: + containers: + - name: postgresql-client + image: bitnami/postgresql + env: + - name: PG_HOST + value: {{ include "postgresql.serviceName" . | quote }} + - name: PG_PORT + value: {{ .Values.postgresql.service.port | quote }} + - name: PG_USER + value: {{ .Values.global.postgresql.postgresqlUsername | quote }} + - name: PGPASSWORD + valueFrom: + secretKeyRef: + name: {{ include "backend.postgresql.passwordSecret" .}} + key: postgresql-password + - name: PG_DBNAME + value: {{ .Values.appConfig.backend.database.connection.database }} + command: + - /bin/bash + - -ecx + - | + psql --host=$PG_HOST --port=$PG_PORT --username=$PG_USER --dbname=$PG_DBNAME --no-password + restartPolicy: Never +{{- end }} \ No newline at end of file diff --git a/contrib/chart/backstage/values.yaml b/contrib/chart/backstage/values.yaml new file mode 100644 index 0000000000..5e22b9ac8a --- /dev/null +++ b/contrib/chart/backstage/values.yaml @@ -0,0 +1,240 @@ +# Default values for backstage. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +frontend: + enabled: true + replicaCount: 1 + image: + repository: roadiehq/backstage-k8s-demo-frontend + tag: latest + pullPolicy: IfNotPresent + containerPort: 80 + resources: + requests: + memory: 128Mi + limits: + memory: 256Mi + +backend: + enabled: true + replicaCount: 1 + image: + repository: roadiehq/backstage-k8s-demo-backend + tag: latest + pullPolicy: IfNotPresent + containerPort: 7000 + resources: + requests: + memory: 512Mi + limits: + memory: 1024Mi + +lighthouse: + enabled: true + replicaCount: 1 + image: + repository: roadiehq/lighthouse-audit-service + tag: latest + pullPolicy: IfNotPresent + containerPort: 3003 + resources: + requests: + memory: 128Mi + limits: + memory: 256Mi + database: + connection: + port: + host: + user: + password: + database: lighthouse_audit_service + pathToDatabaseCa: + +nameOverride: "" +fullnameOverride: "" + +ingress: + annotations: + kubernetes.io/ingress.class: nginx + +global: + postgresql: + postgresqlUsername: backend-user + caFilename: ca.crt + +postgresql: + enabled: true + nameOverride: postgresql + tls: + enabled: true + certificatesSecret: backstage-postgresql-certs + certFilename: tls.crt + certKeyFilename: tls.key + volumePermissions: + enabled: true + initdbScriptsSecret: backstage-postgresql-initdb + +appConfig: + app: + baseUrl: https://demo.example.com + title: Backstage + backend: + baseUrl: /api + listen: 0.0.0.0:7000 + cors: + origin: https://demo.example.com + database: + client: pg + connection: + database: backend + host: + user: + port: + password: + ssl: + rejectUnauthorized: false + ca: + sentry: + organization: spotify + techdocs: + storageUrl: https://backend.example.com/techdocs/static/docs + requestUrl: https://backend.example.com/techdocs/docs + lighthouse: + baseUrl: https://lighthouse.example.com + rollbar: + organization: roadie + + # Auth config has recently moved into the app config file in upstream Backstage. However, + # most of this config simply mandates that items like the client id and client secret should + # be picked up from the environment variables named below. Those environment variables are + # set in this helm controlled environment by the 'auth' configuration below this section. + # Thus, the only key in this config which directly controls an app config is the + # auth.providers.github.development.appOrigin property. + auth: + providers: + google: + development: + appOrigin: "http://localhost:3000/" + secure: false + clientId: + $secret: + env: AUTH_GOOGLE_CLIENT_ID + clientSecret: + $secret: + env: AUTH_GOOGLE_CLIENT_SECRET + github: + development: + appOrigin: "http://localhost:3000/" + secure: false + clientId: + $secret: + env: AUTH_GITHUB_CLIENT_ID + clientSecret: + $secret: + env: AUTH_GITHUB_CLIENT_SECRET + enterpriseInstanceUrl: + $secret: + env: AUTH_GITHUB_ENTERPRISE_INSTANCE_URL + gitlab: + development: + appOrigin: "http://localhost:3000/" + secure: false + clientId: + $secret: + env: AUTH_GITLAB_CLIENT_ID + clientSecret: + $secret: + env: AUTH_GITLAB_CLIENT_SECRET + audience: + $secret: + env: GITLAB_BASE_URL + okta: + development: + appOrigin: "http://localhost:3000/" + secure: false + clientId: + $secret: + env: AUTH_OKTA_CLIENT_ID + clientSecret: + $secret: + env: AUTH_OKTA_CLIENT_SECRET + audience: + $secret: + env: AUTH_OKTA_AUDIENCE + oauth2: + development: + appOrigin: "http://localhost:3000/" + secure: false + clientId: + $secret: + env: AUTH_OAUTH2_CLIENT_ID + clientSecret: + $secret: + env: AUTH_OAUTH2_CLIENT_SECRET + authorizationURL: + $secret: + env: AUTH_OAUTH2_AUTH_URL + tokenURL: + $secret: + env: AUTH_OAUTH2_TOKEN_URL + auth0: + development: + clientId: + $secret: + env: AUTH_AUTH0_CLIENT_ID + clientSecret: + $secret: + env: AUTH_AUTH0_CLIENT_SECRET + domain: + $secret: + env: AUTH_AUTH0_DOMAIN + microsoft: + development: + clientId: + $secret: + env: AUTH_MICROSOFT_CLIENT_ID + clientSecret: + $secret: + env: AUTH_MICROSOFT_CLIENT_SECRET + tenantId: + $secret: + env: AUTH_MICROSOFT_TENANT_ID + +auth: + google: + clientId: a + clientSecret: a + github: + clientId: c + clientSecret: c + gitlab: + clientId: b + clientSecret: b + baseUrl: b + okta: + clientId: b + clientSecret: b + audience: b + oauth2: + clientId: b + clientSecret: b + authUrl: b + tokenUrl: b + auth0: + clientId: b + clientSecret: b + domain: b + microsoft: + clientId: f + clientSecret: f + tenantId: f + sentryToken: e + rollbarAccountToken: f + # This is a 'Personal Access Token' + circleciAuthToken: r + # Used by the scaffolder to create GitHub repos. Must have 'repo' scope. + githubAccessToken: g + gitlabAccessToken: g +