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 }}"
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 }}"
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
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
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.gotmplfile over setting many values in thedefault-environment.yaml.gotmplThese values can be overridden in the environment via<component>.<part>.rawValuesif 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
globalvalues for settings which are relevant for multiple components.