When deploying Cassandra to Kubernetes, it's a common requirement to initialize databases, including the creation of key spaces and tables. This post shows how to do this with helmfile and Bitnami Cassandra helm chart.

On Kubernetes, the Cassandra init scripts should be stored in a config map. The easiest way is to create a new helm chart to manage these init scripts. After creating a new helm chart using helm create db-config, delete all files in the templates directory except _helpers.tpl and add a new one called configmap.yaml.

In the configmap.yaml file below, each key-value pair is a Cassandra CQL file. These init scripts will be executed using alphabetical order of the file names, so you should prefix the file names with numbers like 01- to ensure the execution order.

apiVersion: v1
kind: ConfigMap
metadata:
  name: init-db
  labels:
    {{- include "db-config.labels" . | nindent 4 }}
data:
  "01-init.cql": |
    CREATE KEYSPACE IF NOT EXISTS myapp
      WITH REPLICATION = {
        'class': 'SimpleStrategy',
        'replication_factor' : 1
      };

    CREATE TABLE IF NOT EXISTS myapp.sample (
        id int,
        value text,
        PRIMARY KEY(id)
      )
      WITH gc_grace_seconds = 0;

Below is the helmfile.yaml to create Cassandra deployment. The value initDBConfigMap specifies the name of config map of init scripts. needs is used to specify that Cassandra release depends on db-config release.

repositories:
- name: bitnami
  url: https://charts.bitnami.com/bitnami

releases:
  - name: cassandra
    namespace: {{ env "NAMESPACE" | default "myapp" }}
    chart: bitnami/cassandra
    version: 6.0.1
    needs:
      - {{ env "NAMESPACE" | default "myapp" }}/db-config
    values:
      - cluster:
          seedCount: 1
          minimumAvailable: 1
        replicaCount: 1
        dbUser:
          user: cassandra
          password: cassandra
        initDBConfigMap: init-db
  - name: db-config
    namespace: {{ env "NAMESPACE" | default "myapp" }}
    chart: ./charts/db-config

After using helmfile apply to apply this helmfile.yaml file, you should see Cassandra statefulset in Kubernetes with database initialized.