# Component Anatomy (/docs/deployment/component-anatomy)



Every deployable service in the platform is defined as a component. A component is a directory containing a TOML configuration file and one or more templates. The CLI reads these definitions, resolves variables, renders templates, and produces the manifests that ArgoCD deploys.

Directory structure [#directory-structure]

Components live under `src/manifests/source/<group>/<component>/`:

```text
src/manifests/source/
├── common/
│   ├── keycloak/
│   │   ├── variables.toml
│   │   ├── values.yaml.j2
│   │   └── extra/
│   │       ├── gateway-httproute.yaml.j2
│   │       └── db-credentials.yaml.j2
│   ├── grafana/
│   │   ├── variables.toml
│   │   └── values.yaml.j2
│   └── ...
├── coreai/
│   └── ...
└── proai/
    └── ...
```

The three groups (`common`, `coreai`, `proai`) map directly to ArgoCD parent applications and sync wave tiers.

Component formats [#component-formats]

The `format` field in `variables.toml` determines what the CLI expects:

| Format      | Required files                         | How ArgoCD deploys                                                                 |
| ----------- | -------------------------------------- | ---------------------------------------------------------------------------------- |
| `helm`      | `variables.toml`, `values.yaml.j2`     | Pulls the chart from the OCI registry, applies the rendered `values.yaml` from Git |
| `kustomize` | `variables.toml`, `kustomization.yaml` | Applies the kustomization from Git                                                 |
| `yaml`      | `variables.toml`                       | Applies raw YAML manifests from the `resources/` directory                         |

The component table [#the-component-table]

Every `variables.toml` has a required `[component]` table:

```toml
[component]
name          = "keycloak"
namespace     = "keycloak"
version       = "26.5.2"

format        = "helm"
chart_name    = "keycloak"
chart_version = "18.10.0"
release_name  = "keycloak"

url_prefix    = "iam"

parent_app       = "common"
sync_wave        = "7"
sync_options     = "- SkipDryRunOnMissingResource=true"
sync_annotations = ""
```

| Field              | Purpose                                                                                     |
| ------------------ | ------------------------------------------------------------------------------------------- |
| `name`             | Unique component identifier. Must match the directory name.                                 |
| `namespace`        | Kubernetes namespace where the component is deployed. Created automatically by ArgoCD.      |
| `version`          | Application version. Also used as an image tag in some component templates.                 |
| `format`           | One of `helm`, `kustomize`, or `yaml`.                                                      |
| `chart_name`       | Helm chart name in the OCI registry.                                                        |
| `chart_version`    | Helm chart version to deploy.                                                               |
| `release_name`     | Helm release name.                                                                          |
| `url_prefix`       | Subdomain prefix for the component's endpoint (`<url_prefix>.<base_domain>`).               |
| `parent_app`       | Which parent application this component belongs to: `common`, `coreai`, or `proai`.         |
| `sync_wave`        | Integer (0–99). Controls deployment order within the parent app. Lower values deploy first. |
| `sync_options`     | Additional ArgoCD sync options.                                                             |
| `sync_annotations` | Additional ArgoCD annotations.                                                              |

Extra tables [#extra-tables]

Tables beyond `[component]` are optional and component-specific. Not every component has all of these — each component defines only the tables it needs. The following are common examples.

Database configuration (optional) [#database-configuration-optional]

```toml
[database]
postgresql_name     = "keycloak"
postgresql_owner    = "keycloak"
postgresql_password = {value = "", secret = true}
```

These variables are available in templates following the naming pattern:

```text
<component_name>_<table>_<variable>
```

For example, the `[database]` table above produces `keycloak_database_postgresql_name`, `keycloak_database_postgresql_owner`, etc.

The `[component]` table is the exception — it omits the table segment: `keycloak_namespace`, `keycloak_chart_version`.

SSO configuration (optional) [#sso-configuration-optional]

Keycloak is the SSO provider, so it does not have an `[sso]` table itself. The following example is from the Grafana component, which enrolls as an SSO consumer:

```toml
[sso]
enabled       = true
client_id     = "grafana"
client_secret = {value = "", secret = true}
description   = "Grafana OAuth client"

default_scope                = ["openid", "profile", "email"]
standard_flow_enabled        = true
redirect_uris                = ["*"]
groups                       = [{name = "Grafana-Viewer"}]
```

When `[sso] enabled = true`, the CLI generates Keycloak enrollment resources from shared templates: an SSO config secret, a registration job (deployed at a negative sync wave to run before the component), and a PostDelete cleanup job. See [Configuration model — SSO scope](/docs/deployment/configuration-model#sso-scope) for details.

Resource sizing (optional) [#resource-sizing-optional]

The Keycloak component defines its own sizing through a `[server]` table:

```toml
[server]
cpu_request    = "1"
memory_request = "4Gi"
cpu_limit      = "2"
memory_limit   = "8Gi"
```

When a component does not define its own sizing, the `[default]` section in `platform.toml` provides fallback values.

Template rendering [#template-rendering]

The CLI uses Jinja2 to render templates. All resolved variables from `platform.toml` and every component's `variables.toml` are available in the template context as a flat dictionary.

Variable naming in templates [#variable-naming-in-templates]

Both global and component variables follow the same `<table>_<variable>` pattern. Global variables from `platform.toml` use the section name as prefix, without a component name:

```text
common_base_domain                    # [common] base_domain
common_registry_name                  # [common] registry_name
git_repo_url                          # [git] repo_url
git_branch                            # [git] branch
```

Component variables add the component name: `<component_name>_<table>_<variable>`. The `[component]` table is the exception — it omits the table segment:

```text
keycloak_namespace                    # [component] name     → no table segment
keycloak_chart_version                # [component] chart_version → no table segment
keycloak_database_postgresql_name     # [database] postgresql_name
keycloak_auth_admin_password          # [auth] admin_password
```

Additional template directories [#additional-template-directories]

Beyond `values.yaml.j2`, a component can include additional manifests in a subdirectory. The directory name depends on the component format:

* **`helm`** components use `extra/`. These manifests are included as additional ArgoCD sources on top the Helm chart pulled from the upstream OCI registry and the rendered values file.
* **`yaml`*&#x2A; and &#x2A;*`kustomize`** components use `resources/`. Nothing is pulled from an upstream registry — all resources are declared locally in the component directory and applied directly by ArgoCD from Git.

Any rendered `kind: Secret` in either directory is automatically sealed with `kubeseal`. All `.yaml.j2` files are rendered with the same variable context as `values.yaml.j2`.

Overriding values [#overriding-values]

Per-component environment overrides [#per-component-environment-overrides]

Any variable can be overridden via environment variable. The key format is uppercase, with hyphens replaced by underscores:

| TOML path                                   | Environment variable                |
| ------------------------------------------- | ----------------------------------- |
| `[component] chart_version` in `keycloak/`  | `KEYCLOAK_CHART_VERSION`            |
| `[database] postgresql_name` in `keycloak/` | `KEYCLOAK_DATABASE_POSTGRESQL_NAME` |
| `[auth] admin_password` in `keycloak/`      | `KEYCLOAK_AUTH_ADMIN_PASSWORD`      |

Global overrides [#global-overrides]

Global variables from `platform.toml` follow the same pattern but without a component prefix:

| TOML path              | Environment variable |
| ---------------------- | -------------------- |
| `[common] base_domain` | `COMMON_BASE_DOMAIN` |
| `[git] repo_url`       | `GIT_REPO_URL`       |

Component inventory [#component-inventory]

The platform currently includes 46 components across three groups:

| Group    | Count | Purpose                                                                       |
| -------- | ----- | ----------------------------------------------------------------------------- |
| `common` | 21    | Cluster infrastructure: networking, identity, storage, observability, secrets |
| `coreai` | 17    | AI platform: portal, backend API, model serving, vector DB, workflows         |
| `proai`  | 8     | Data and ML extensions: pipelines, BI, data ingestion, policy                 |

Run `uv run -m src.cli.main list-components` to see the full list for the current version.

Related pages [#related-pages]

* [Configuration model](/docs/deployment/configuration-model)
* [Platform CLI](/docs/deployment/platform-cli)
* [GitOps workflow](/docs/deployment/gitops-workflow)
