Skip to main content

Component Configuration

How to create and configure components for deployment in Civitas.

Creating/Updating components

Create a new component

make new-component

Update existing components to the latest template versions

make update-components

Folder Structure

A component includes:

components/<component>/
├── civitas-component.yaml # Component definition
├── charts.yaml # Helm chart sources and versions
├── default-environment.yaml.gotmpl # Calues, which can/should be set per environment
├── helmfile.yaml.gotmpl # Helmfile (auto-generated, usually no changes needed)
├── images.yaml # Container image definitions
├── values/ # Helm values per component part
│ ├── <part> # e.g., app, ui, worker
│ │ ├── base-values.yaml.gotmpl # Helm Values common to all environments
│ │ ├── development-values.yaml.gotmpl # Development-specific overrides
│ │ └── production-values.yaml.gotmpl # Production-specific overrides
│ └── ...
├── charts/ # Custom Helm charts (optional)
├── databases.yaml # Database configuration (optional)
├── secrets.yaml # Secret generation config (optional)
└── README.md # Component documentation

Configuring values

We work with Helm charts and therefore must primarily configure the components via Helm values. These values are set components/<component>/values/<part>/<profile>-values.yaml.gotmpl files.

Using Defaults

Some value settings are used in multiple components and have default values defined. These defaults can be found in the defaults/environments/.yaml.gotmpl files. For example for security there is security.yaml.gotmpl with securityDefaults object. You can access these defaults in your component values files like this:

securityContext:
{{ .Values.securityDefaults.securityContext | toYaml | nindent 2 }}

podSecurityContext:
{{ .Values.securityDefaults.podSecurityContext | toYaml | nindent 2 }}

Connect with Keycloak (OIDC/OAuth2)

You can configure other components to connect to Keycloak by constructing the Keycloak URL based on the configured subdomain and path prefix.

{{- $keycloakHost := printf "%s.%s" (default "" .Values.keycloak.app.subdomain) $global.domain | trimPrefix "." }}
{{- $keycloakPath := .Values.keycloak.app.pathPrefix -}}
{{- $keycloakUrl := printf "https://%s%s" $keycloakHost $keycloakPath -}}
{{- $realmName := $global.instanceSlug }}
authServerUrl: "{{ $keycloakUrl }}realms/{{ $realmName }}"
warning

TODO: Currently, there is no standard way to configure clients, roles etc. in Keycloak

Connecting to Kafka Cluster

bootstrapServers: "{{ .Values.kafka.cluster.bootstrapService }}:{{ .Values.kafka.cluster.bootstrapPort }}"
warning

Currently, there is no standard way to configure Kafka authentication and TLS settings.

Connecting to Database

Create a file in components/<component>/databases.yaml with the following content:

keycloak:
name: 'keycloak'
embedded: true # set to false, if an external database is used
user: 'keycloak'
secret:
name: 'db-keycloak'
key: 'password'
generate: true # indicates that this value should be generated
host: 'postgres-cluster-rw' # set to external hostname, if an external database is used
port: 5432
warning

Currently multi namespaces do not yet work. Namespace of the cluster is not known, when rendering this.

You can access the credentials and connection details via the .Values.databases.<component> object like this:

database:
vendor: postgres
hostname: {{ .Values.databases.keycloak.host }}
port: {{ .Values.databases.keycloak.port }}
database: {{ .Values.databases.keycloak.name }}
username: {{ .Values.databases.keycloak.user }}
existingSecret: {{ .Values.databases.keycloak.secret.name }}
existingSecretKey: "password"

Setting Docker Images

To adjust/set where a docker image is pulled from and which version is used, create a file in components/<component>/images.yaml with content like this:

keycloak:
app:
repository: 'quay.io/keycloak/keycloak'
tag: '26.4.0'
configCli:
repository: 'docker.io/adorsys/keycloak-config-cli'
tag: '6.4.0-26'

You can access these values via the .Values.images.<component>.<imageKey> object like this:

image:
repository: {{ .Values.images.keycloak.app.repository }}
tag: {{ .Values.images.keycloak.app.tag }}

Generating Secrets

For generating and using secrets in a component, create a file in components/<component>/secrets.yaml with content like this:

---
keycloak:
app:
keycloak-admin-user: # name of the secret in kubernetes
password: # key in the secret
length: 16
generate: true # indicates that this value should be generated
warning

Currently, you have to ensure that the secret name and key match what the component expects or is set in the values files.

Exposing UIs and APIs

In the components/<component>/default-environment.yaml.gotmpl file add two new values under the part which is exposed:

kafka:
ui:
enabled: true
namespace: {{ include "civitas.namespace" (dict "global" .Values.global "suffix" "kafka") }}
# subdomain to use for accessing the UI. Can be null/empty to use the base domain with path
# pathPrefix is expected to start and end with /
subdomain: kafka-ui
pathPrefix: /

You can access these values via the .Values.<component>.<part> object like this:

ingress:
enabled: {{ $global.ingress.enabled }}
annotations:
cert-manager.io/cluster-issuer: {{ $global.ingress.clusterIssuer }}
{{- $host := printf "%s.%s" (default "" $this.subdomain) $global.domain | trimPrefix "." }}
host: {{ $host }}
path: '{{ $this.pathPrefix }}'
ingressClassName: {{ $global.ingress.ingressClass }}

Configuring Resources

For now: Set resource requests and limits directly in the <part>-values.yaml.gotmpl file of the component with sensible defaults. Defaults should be appropriate for a development and test environment and not much more.

Creating custom Helm charts

When creating a helm chart ensure that all deployment requirements can be fulfilled either by setting directly or via values. The helm chart should be opinionated, since only we use it in this specific context. It is important to follow standards across this project and helm charts in general how which values are set if possible. This way we can define global defaults and use them across multiple components.

The following (incomplete) list shows some of the values which should be supported in the helm chart:

  • In general
    • labels/annotations
  • Deployment/StatefulSet
    • resource requests/limits
    • securityContext/podSecurityContext
    • liveness/readiness probes (can be set directly)
    • image repository/tag/pullPolicy
    • rollingUpdate
    • replicas
    • podDisruptionBudget
    • autoscaling
    • importing self-signed TLS certificates (if applicable)
  • Service
    • type/port named (can be set directly)
  • ServiceAccount
    • create/name/annotations
  • Ingress
    • enabled
    • host/path
    • ingressClassName/annotations
    • tls

Setting other values

Here some guidelines which should help setting other values:

  • Prefer sensible defaults directly in the <part>-values.yaml.gotmpl file over setting many values in the default-environment.yaml.gotmpl These values can be overridden in the environment via <component>.<part>.rawValues if needed. We want to avoid too many values being set in the environment files to keep them clean and easy to read.
  • Security relevant values must be secure by default. E.g. if TLS can be enabled/disabled, it must be enabled by default.
  • Use the global values for settings which are relevant for multiple components.