Skip to main content
Version: 2.0

GitOps Scaffolder

Service: gitops-scaffolder · Namespace: kubeopera-core · Jobs run in: kubeopera-provisioning

gitops-scaffolder writes the GitOps environment for a new cluster. Given a cluster's name, domain and region, it generates a complete Flux tree and pushes it to Git. The tree covers ingress, certificates, storage, database, monitoring, security and every Tantilium Cloud Runner (TCR) service, all configured for that cluster's domain, with freshly generated and sealed credentials. host-cluster-controller calls it during the GeneratingGitOpsTree phase.

How a run works​

Each run is a Kubernetes Job running scaffold-runner (packaged with the generate-gitops-env tool):

A scaffold run

Every step after the request runs inside the Job scaffold-<id> in kubeopera-provisioning.

POST /api/v1/scaffolds
Clone the target Git repository
Generate the infrastructure layer only
Nothing is sealed yet.
Commit and push
Wait for the new cluster's Sealed Secrets controller to be Available
Fetch its public certificate
Through the Kubernetes API, without a port-forward.
Generate everything else
Fresh credentials are sealed with that certificate.
Commit and push
host-cluster-controller polls the job for its result

Why two passes?​

Credentials must be sealed with the new cluster's own Sealed Secrets key, but the Sealed Secrets controller is itself part of the infrastructure layer being generated. So the scaffolder pushes the infrastructure first, waits for Flux to bring Sealed Secrets up on the cluster, and only then seals and pushes the rest.

The generated tree encodes the same order for Flux: the infrastructure Kustomization has no dependencies, and apps, database and cert-manager-config each depend on infrastructure.

What gets generated​

Using the reference environment as a template:

  • the infrastructure layer (cert-manager, ingress-nginx, storage classes, monitoring, Kyverno, Falco and Sealed Secrets), with external-dns pointed at the new cluster's domain and region;
  • a hostname for every service under the cluster's domain, as overlay patches (the shared base/ manifests are never edited);
  • fresh credentials for PostgreSQL, RabbitMQ and a registry pull secret (or your own, if you supplied one), sealed before they're committed.

See Setup: creating more environments.

The target can be the platform's shared GitOps repository or your own repository, with credentials supplied when the cluster is created.

API​

Only TCR's own services call this API, using their service identities.

MethodPathDescription
POST/api/v1/scaffoldsStart a run. Returns 202 immediately with the job.
GET/api/v1/scaffolds/{id}Status, message and the generated gitops_path.
GET/api/v1/scaffolds/{id}/logsJob logs.
GET/healthzHealth check.

Operating it​

kubectl logs -n kubeopera-core deploy/gitops-scaffolder -f
kubectl get jobs -n kubeopera-provisioning
kubectl logs -n kubeopera-provisioning job/scaffold-<id> -f

Configuration​

VariableDefaultDescription
DATABASE_URL—PostgreSQL connection.
JOB_NAMESPACEkubeopera-provisioningWhere scaffolding Jobs run.
SCAFFOLD_RUNNER_IMAGEpinned releaseThe scaffold-runner image.
DEFAULT_GITOPS_REPO_URL—The platform's shared GitOps repository.
REFERENCE_ENVIRONMENTdevelopmentThe environment used as the template.