Cloud Deployment (Scaleway)
This runbook uses OpenTofu to provision infrastructure and Helm to deploy the chart on Scaleway Kapsule (mutualized). All just commands should be run from the repository root. Steps that require manual commands specify their working directory explicitly.
If you are new to Kubernetes, read the Kubernetes primer first. It explains each concept next to its Docker Compose equivalent.
What OpenTofu provisions
OpenTofu creates the following resources on Scaleway (nl-ams region): - A VPC and private network - A Kapsule cluster (mutualized, k8s v1.32) with an autoscaling node pool (PLAY2-MICRO, 1-3 nodes) - A security group allowing HTTP/HTTPS traffic
PostgreSQL runs in-cluster via the Bitnami Helm chart (not as a Scaleway managed database). The container registry (srdp-registry) must be created beforehand via the Scaleway Console.
1) Prepare cloud credentials
- Copy
deploy/opentofu/scaleway/secrets.sh.exampletodeploy/opentofu/scaleway/secrets.shand fill in your Scaleway credentials (SCW_ACCESS_KEY, SCW_SECRET_KEY, SCW_DEFAULT_PROJECT_ID). - Load them before running OpenTofu:
cd deploy/opentofu/scaleway source ./secrets.sh
2) Build and push container images
Run the build recipe from the repository root. It sources deploy/opentofu/scaleway/secrets.sh for the credentials and logs into the registry:
just build-and-push
srdp.toml under [deploy] registry.
Quarto is disabled by default (quarto.enabled: false).
docs/02-configuration.md explains why.
3) Provision infrastructure with OpenTofu
cd deploy/opentofu/scaleway
tofu init -upgrade # first run only, from deploy/opentofu/scaleway/
cd ../.. # back to repo root
just prod-apply
4) Export kubeconfig
just prod-use-kubeconfig # from repo root
5) Prepare production Helm values
- Copy
deploy/kubernetes/srdp-chart/values-prod.example.yamltodeploy/kubernetes/srdp-chart/values-prod.yamlif you are starting fresh. - Fill in
global.domain, theoauth2-proxycookie and whitelist domains, and the ACME email for Traefik. Use a real domain or<lb-ip>.nip.ioonce you know the load balancer IP. Let's Encrypt's HTTP and TLS challenges need the machine to be publicly reachable on that domain. A machine that isn't reachable can still use Let's Encrypt through a DNS challenge, if the organisation controls the public DNS of a real domain. A machine with only an internal name needs the organisation's own certificate. - Set the registry in
srdp.tomlunder[deploy] registry. Theprod-*recipes pass it to the chart asglobal.srdpRegistryand as thesrdp-etlrepository. - The values files hold no passwords or keys.
Before you install, create these Secrets in the
srdpnamespace, for example with External Secrets. Every consumer reads them by these fixed names.
| Secret | Keys |
|---|---|
srdp-postgres |
postgres-password (superuser), password (zitadel user), replication-password (replication only) |
srdp-zitadel |
masterkey, config-yaml |
srdp-oauth2-proxy |
client-id, client-secret, cookie-secret |
srdp-dagster-postgresql |
postgresql-password |
srdp-marquez |
db-password |
config-yamlinsrdp-zitadelis a Zitadel config fragment withDatabase.Postgres.User.Password,Database.Postgres.Admin.PasswordandFirstInstance.Org.Human.Password. The two database passwords must matchpasswordandpostgres-passwordinsrdp-postgres.- The
srdp-setupJob readssrdp-dagster-postgresqlandsrdp-marqueztoo, and applies them to their roles on every install and upgrade. - Changing an internal password: these are service-to-service credentials, so change one only as a deliberate rotation.
Change the value in its Secret, run
helm upgrade, then restart the services that use it. Marquez restarts by itself. For Dagster, runkubectl -n srdp rollout restart deploy/srdp-dagster-webserver deploy/srdp-dagster-webserver-read-only deploy/srdp-dagster-daemon deploy/srdp-dagster-user-deployments-srdp-etl. - Master key format: ZITADEL expects a 32-character master key string. Generate one, for example, with `tr -dc 'A-Za-z0-9'