Search code examples
yamlkubernetes-helm

Helm values.yaml: Use Anchors in multiline string


When setting a multiline string, f.e.

mariadb:
  database: &databaseName keycloakdb
  port: &databaseServicePort 3306

extraEnv: |
  - name: DB_PORT
    value: *databaseServicePort
  - name: DB_DATABASE
    value: *databaseName

The anchors in extraEnv are not expanded while building the values.yaml. They are passed "as is" to the template where the parser throws an error because it can not find the anchor. Changing extraEnv to Array instead of string is not an option because it needs to be passed to an external helm chart.


Solution

  • That is in fact how YAML works. Anchors aren't a general-purpose substitution mechanism; they're a way to specify that the same complete list, mapping, or scalar value appears in multiple places in the file. You can only use an alias node as the complete value of some other field.

    mariadb: &mariadb
      database: &databaseName keycloakdb
    
    options: *mariadb                     # the mapping including a `database:` key
    dbName: *databaseName                 # the scalar string "keycloakdb"
    aString: text including *databaseName # literally the string "*databaseName"
    

    In most cases I would avoid YAML anchors. This is doubly true in a Helm context, where you can use its templating system to fill in the content.

    Here I'd avoid trying to provide large arbitrary blocks of Kubernetes YAML in Helm values. Instead, set the environment variables in your template file:

    # templates/deployment.yaml
    env:
      - name: DB_PORT
        value: {{ .Values.mariadb.port }}
      - name: DB_DATABASE
        value: {{ .Values.mariadb.database }}
    {{- with .Values.extraEnv }}
    {{- toYaml . | indent 2 }}
    {{- end }}