# Backstage Helm Chart Helm chart for deploying the Backstage Developer Portal for the OnlineSales ephemeral testing platform. ## Overview This chart deploys Backstage with: - Cloud SQL PostgreSQL database (via Cloud SQL Proxy) - External Secrets Operator integration for GCP Secret Manager - Ingress configuration for external access - ServiceAccount with Workload Identity for GCP integration ## Prerequisites - Kubernetes cluster 1.25+ - Helm 3.0+ - [External Secrets Operator](https://external-secrets.io/) installed - Cloud SQL PostgreSQL instance provisioned - GCP Service Account for Workload Identity - ClusterSecretStore configured (see below) ## Installation ### Quick Install ```bash helm install backstage ./backstage-chart \ --namespace backstage \ --create-namespace \ -f values.yaml ``` ### With Custom Values ```bash helm install backstage ./backstage-chart \ --namespace backstage \ --create-namespace \ --set image.tag=latest \ --set ingress.hosts[0].host=backstage.example.com ``` ## Configuration ### Key Values | Parameter | Description | Default | |-----------|-------------|---------| | `image.repository` | Backstage image repository | `gcr.io/prj-onlinesales-test-framework/backstage` | | `image.tag` | Backstage image tag | `latest` | | `replicaCount` | Number of replicas | `1` | | `serviceAccount.name` | ServiceAccount name | `backstage` | | `serviceAccount.annotations` | SA annotations (Workload Identity) | `{}` | | `ingress.enabled` | Enable ingress | `true` | | `ingress.hosts` | Ingress hostnames | `[]` | | `externalSecrets.enabled` | Enable External Secrets | `true` | | `externalSecrets.secretStore` | SecretStore reference | `gcp-secret-store` | | `cloudSqlProxy.enabled` | Enable Cloud SQL Proxy sidecar | `true` | | `cloudSqlProxy.instanceConnectionName` | Cloud SQL connection string | `""` | ### External Secrets Configuration The chart uses External Secrets Operator to sync secrets from GCP Secret Manager: ```yaml externalSecrets: enabled: true secretStore: gcp-secret-store # ClusterSecretStore name refreshInterval: 1h secrets: # Backstage database credentials POSTGRES_HOST: backstage-db/host POSTGRES_PORT: backstage-db/port POSTGRES_USER: backstage-db/username POSTGRES_PASSWORD: backstage-db/password # Integration credentials GITEA_URL: backstage-secrets/GITEA_URL GITEA_USERNAME: backstage-secrets/GITEA_USERNAME GITEA_PASSWORD: backstage-secrets/GITEA_PASSWORD ARGOCD_AUTH_TOKEN: backstage-secrets/ARGOCD_AUTH_TOKEN ARGO_WORKFLOWS_TOKEN: backstage-secrets/ARGO_WORKFLOWS_TOKEN ``` ### Cloud SQL Proxy Setup The chart deploys Cloud SQL Proxy as a sidecar: ```yaml cloudSqlProxy: enabled: true image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.8.0 instanceConnectionName: "project:region:instance" port: 5432 resources: requests: cpu: 100m memory: 256Mi limits: cpu: 500m memory: 512Mi ``` **Workload Identity Setup:** ```bash # Create GCP service account gcloud iam service-accounts create backstage-sa \ --display-name="Backstage Service Account" # Grant Cloud SQL Client role gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:backstage-sa@$PROJECT_ID.iam.gserviceaccount.com" \ --role="roles/cloudsql.client" # Configure Workload Identity gcloud iam service-accounts add-iam-policy-binding \ backstage-sa@$PROJECT_ID.iam.gserviceaccount.com \ --role="roles/iam.workloadIdentityUser" \ --member="serviceAccount:$PROJECT_ID.svc.id.goog[backstage/backstage]" # Annotate Kubernetes SA kubectl annotate serviceaccount backstage \ --namespace backstage \ iam.gke.io/gcp-service-account=backstage-sa@$PROJECT_ID.iam.gserviceaccount.com ``` ## Database Setup 1. **Create Cloud SQL Instance:** ```bash gcloud sql instances create backstage-db \ --database-version=POSTGRES_14 \ --tier=db-f1-micro \ --region=$REGION \ --root-password=$ROOT_PASSWORD ``` 2. **Create Database:** ```bash gcloud sql databases create backstage --instance=backstage-db ``` 3. **Create User:** ```bash gcloud sql users create backstage_user \ --instance=backstage-db \ --password=$USER_PASSWORD ``` 4. **Store Credentials in Secret Manager:** ```bash echo -n "backstage_user" | gcloud secrets create backstage-db-username --data-file=- echo -n "$USER_PASSWORD" | gcloud secrets create backstage-db-password --data-file=- ``` ## RBAC Setup Backstage requires cluster-wide permissions for environment provisioning: ```bash kubectl apply -f - < -c backstage -- \ psql -h localhost -U backstage_user -d backstage -c "SELECT 1" ``` ### Database migration issues ```bash # Check Backstage logs for migration errors kubectl logs -n backstage -l app.kubernetes.io/name=backstage | grep -i migration ``` ## Upgrading ```bash helm upgrade backstage ./backstage-chart \ --namespace backstage \ -f values.yaml ``` ## Uninstalling ```bash helm uninstall backstage --namespace backstage kubectl delete namespace backstage ``` ## Related Documentation - [GCP Deployment Guide](../GCP-DEPLOYMENT-GUIDE.md) - [Backstage App README](../backstage-app/README.md) - [External Secrets Operator](https://external-secrets.io/) - [Cloud SQL Proxy](https://cloud.google.com/sql/docs/mysql/sql-proxy) ## License Proprietary - OnlineSales.ai