Iterate on object map/list in helm template file using terraform helm release deployment

91 Views Asked by At

I have this variable in terraform :

variable "users" {
  description = "List of users with their roles and databases."

  type = list(object({
    name      = string
    roles     = list(string)
    databases = list(string)
  }))
  default = [
    {
      name      = "user_1"
      roles     = ["superuser", "createdb"]
      databases = ["db1", "db2"]
    },
    {
      name      = "user_2"
      roles     = ["createdb"]
      databases = ["db3"]
    }
  ]
}

This variable gives default values for my values.yaml file in order to set the users entry who looks like this:

users:
  - name: ""
    roles: []
    databases: []

This values.yaml file have to set my deployment.yaml like this:

kind: deployment
apiVersion: deployment/v1
metadata:
  name: {{ .Values.name }}
  namespace: {{ .Release.namespace }}
spec:
  ...
  users:
    user_1:
      - superuser
      - createdb
    user_2:
      - createdb
  databases:
    db_1: user_1
    db_2: user_1
    db_3: user_2

I have made this in my deployment.yaml file in order to range over users entries :

kind: deployment
apiVersion: deployment/v1
metadata:
  name: {{ .Values.name }}
  namespace: {{ .Release.namespace }}
spec:
  ...
  users:
  {{- range .Values.users }}
    {{ .name }}:
    {{- range .roles }}
    - {{ . }}
    {{- end }}
  {{- end }}
  databases:
  {{- range .Values.users }}
  {{- $currentUser := . }}
  {{- range $currentUser.databases }}
    {{ . }}: {{ $currentUser.name }}
  {{- end }}
  {{- end }}

This is how I need the values from my terraform variable var.users have to be.

In my terraform code, I have made this :

resource "helm_release" "my_release" {
  name       = "${var.namespace}-my-release"
  repository = "${path.module}/helm"
  ...

  set {
    name = "users"
    value = replace(yamlencode([
      for user in var.users : {
        name      = user.name
        roles     = tolist(user.roles)
        databases = tolist(user.databases)
      }
    ]), "\"", "")
  }

Using this terraform code provides this result :

<<EOT
- name: user_1
  roles:
  - superuser
  - createdb
- name: user_2
  roles:
  - createdb

EOT

But I have this error :

error running dry run for a diff: template: deployment.yaml:28:19: executing "deployment.yaml" at <.Values.users>: range can't iterate over - databases:
│   - db1
│   - db2
│   name: user_1
│   roles:
│   - superuser
│   - createdb
│ - databases:
│   - db3
│   name: user_2
│   roles:
│   - createdb

I test my code using the online tool helm-playground.com here and it seems that my range iteration is good.

How to format or iterate correctly on the object users ?

0

There are 0 best solutions below