Skip to main content

Platform Base architecture

Platform Base is a Jsonnet library, not a running service. It renders Argo CD Applications, and Argo CD does the work of installing and syncing the components.

From Git to a running cluster​

You render your cluster/main.jsonnet twice with different arguments:

  • root=true produces the bootstrap, which you apply by hand once. It contains the argocd Namespace, the Argo CD installation with argocd-cm and argocd-cmd-params-cm already patched, the repository credentials Secret if you enabled argocd.platformRepoCreds, the sidecars of enabled Config Management Plugins, and the bootstrap Application.
  • root=false produces one Argo CD Application for each component. The bootstrap Application keeps syncing this output from Git, so a change to your repository changes the cluster.

The bootstrap Application forwards $ARGOCD_APP_SOURCE_REPO_URL, $ARGOCD_APP_REVISION and $ARGOCD_APP_SOURCE_PATH to main.jsonnet as repoURL, revision and pathPrefix. It also passes the dynamicConfig you rendered the bootstrap with. Every component Application therefore points at the same repository and revision as the bootstrap.

The Application contract​

All Applications are built the same way:

  • They live in the argocd namespace and use the default project.
  • They deploy to the local cluster.
  • They sync automatically, with prune and self-heal on, and with server-side apply.
  • They carry the resources-finalizer.argocd.argoproj.io finalizer, so deleting an Application deletes what it deployed. argo-cd-core is the exception: it has no finalizer, so deleting it leaves Argo CD installed.

A component Application either renders a Jsonnet directory of Platform Base (main.jsonnet, with its configuration passed as a top-level argument), or a vendored Helm chart (Traefik, the Keycloak operator of EDP, Grafana Operator, Alloy, kube-state-metrics, node-exporter, Loki and Mimir), with Helm values generated from the configuration. In both cases the configuration is part of the Application spec. The applications reference lists them all.

Ordering​

There are no sync waves, so the Applications are independent of each other. Some of them need another one first, and converge through retries:

ApplicationWaits for
iamkeycloak-operator and keycloak-operator-edp to reconcile its Keycloak and realm resources
argocd-config, grafanaThe EDP operator's CRDs and the realms from iam, for their Keycloak clients
loki, mimir-distributedcarvel-secret-gen, which generates the credentials of the bundled MinIO
tlscert-manager for the Issuer and Certificate, traefik for the TLSStore
Monitors, rules and alertsprometheus-crds, which installs the Prometheus Operator CRDs

The admission webhooks of the EDP operator need cert-manager, so creating a Keycloak client fails until the webhook certificate is issued.

How configuration flows​

Configuration flows in one direction. config.libsonnet holds the options you override, apps.libsonnet wires them into the components, and each component's defaults.libsonnet holds its own settings. Components never read the global configuration, they only share what they publish as outputs. For example, Grafana learns the Mimir and Loki endpoints from their outputs.

Hostnames and certificates​

Argo CD, Grafana and Keycloak get an Ingress with a hostname derived from baseDomains, as do the optional Loki and Mimir endpoints. Traefik redirects HTTP to HTTPS.

The tls Application creates one Certificate for all baseDomains and their wildcards, and a Traefik TLSStore named default that uses it as the default certificate. The Ingresses do not name a TLS Secret, so they all use that certificate. With the default issuer the certificate is self-signed.