Terraform-provider-helm: Add functionality to set a list

Created on 17 Jul 2018  路  22Comments  路  Source: hashicorp/terraform-provider-helm

It would be nice if the set command could take a list as an input parameter and turn it into a list in configuration EX

set {
name = "controller.service.loadBalancerSourceRanges"
value = ["${var.internal_ip_addr_cidrs}"]
}

should turn into

loadBalancerSourceRanges:

  • 130.211.204.1/32
  • 130.211.204.2/32

This doesn't solve the problem when you need to build more complex lists though

acknowledged breaking-change enhancement themcoverage

Most helpful comment

The following works for me:

variable "plugins" { default = [
  "kubernetes:1.12.0",
  "workflow-job:2.23",
  "workflow-aggregator:2.5",
  "credentials-binding:1.16",
  "git:3.9.1",
  "blueocean:1.7.1"
]}

resource "helm_release" "jenkins" {
  set {
    name = "Master.InstallPlugins"
    value = "{${join(",", var.plugins)}}"
  }
}

All 22 comments

This should work:

set {
  name = "controller.service.loadBalancerSourceRanges"
  value = "{${join(",", var.internal_ip_addr_cidrs)}}"
}

@sebastien-prudhomme tried this, get the following error

key map "ran" has no value

@aaronmell Can you dump the content of var.internal_ip_addr_cidrs?

The following works for me:

variable "plugins" { default = [
  "kubernetes:1.12.0",
  "workflow-job:2.23",
  "workflow-aggregator:2.5",
  "credentials-binding:1.16",
  "git:3.9.1",
  "blueocean:1.7.1"
]}

resource "helm_release" "jenkins" {
  set {
    name = "Master.InstallPlugins"
    value = "{${join(",", var.plugins)}}"
  }
}

@sebastien-prudhomme How I supposed to use this?

variable "volumes" { default = [
  {
    type = "HostPath"
    hostPath = "/var/run/docker.sock"
    mountPath = "/var/run/docker.sock"
  }
]}

... 

set {
    name = "Agent.volumes"
    value = "{${join(",", var.volumes)}}"
  }

I got an error:

* helm_release.jenkins: join: only works on flat lists, this list contains elements of type map in:

{${join(",", var.volumes)}}

@BrunoQuaresma It works for simple list, not for map

@sebastien-prudhomme Ok, but how can I work with a list of maps using the plugin? Is it possible?

The plugin only accept string but with a "join" you can transform a list a string compatible with Helm list syntax.

What is "Agent.volumes"? Which Helm chart are you using?

@BrunoQuaresma Ok i see, it will be hard to do it with the "set" attribute. Either wait for Terraform 0.12 which can build complex structure, or try to generate portions of files that you can import with the "values" attribute.

@sebastien-prudhomme I didn't find anything about the "values" attributes in the docs -> https://github.com/mcuadros/terraform-provider-helm/blob/master/docs/README.md

There https://github.com/mcuadros/terraform-provider-helm/blob/master/docs/release.md

It's the same thing as using "helm install" with the "--values" option.

Thanks.

+1 for adding this to the provider

+1 for this. It would be very useful.

In case of external-dns chart, list can work as follows:

resource "helm_release" "externaldns" {
  name  = "externaldns"
  chart = "stable/external-dns"
  set {
    name  = "sources"
    value = "{service, ingress}"
  }
  set {
    name  = "domainFilters"
    value = "{${local.dns_zone_name}}"
  }

Hope it works for others. I think it's for golang spec.

@joanayma is it really "working"? Which versions are you running? I have the same issue with external-dns but when I use this syntax I get a comma separated list in the domain filter which does not work. It needs to be multiple --domain-filter arguments/an array.

It would be great if set could work with list and map values, performing the necessary conversion (i.e. from ["x", "y", "z"] to {x,y,z}).

for anyone else that comes across this I ended up with
values.yaml

controller:
  service:
    annotations:
      service.beta.kubernetes.io/azure-dns-label-name: ""

main.tf

  set_string {
    name  = "controller.service.annotations.service\\.beta\\.kubernetes\\.io/azure-dns-label-name"
    value = "${var.domain_name_label}"
  }

Here's a work around I found for setting deeply nested values less painfully (tf 12+ only)

resource helm_release my-app {
  name = "my-app"
  namespace = "my-app-ns"
  chart = "/path/to/chart"

  values = [
    file("/path/to/default/values.yaml"),
    yamlencode(yamldecode(file("/path/to/env/specific/values.yaml"),["optional_multipackage_yaml_key"]_
    yamlencode(
        {
          some = {
            deeply = [
               { nested_option = data.foobar.baz.result }
            ]
          }
        }
      })
  ]
}

I've managed to solve the issue, but creating yaml file on the fly from local complex object:

locals {
    helmChartValues = {
        someProperty= {
            someArray = [
                "a", "b"
            ]
        }
        someOtherProperty = {
            a = "b"
        }
    }
}

resource "local_file" "foo" {
    content     = yamlencode(local.helmChartValues)
    filename = "${path.module}/values.yaml"
}

resource "helm_release" "this" {
  name       = "helm-release"
  chart      = "ChartPath"

  values = [
      local_file.chart_values.content
  ]
}

When I set an array value for a helm_release resource from my TF code like below:

set {
    name  = "ObjectIds"
    value = "{${join(",", local.rbac_config.group_oid_list)}}"
}

My TF Plan shows the value being passed like whats shown below:

 + set {
      + name  = "ObjectIds"
      + value = "{"Id1-xxxxxxxxxxx,Id2-yyyyyyyyyyyyyyyyyyy,Id3-zzzzzzzzzzzzzzzz"}"
    }

Why I need the format to be like this?

When the helm chart is installed manually from the command line using helm install, it throws an error if i specify --set ObjectIds={Id1-xxxxxxxx,Id2-yyyyyyyy,Id3-zzzzzz}

Helm Error: Error: This command needs 2 arguments: release name, chart path

Fix: It works just fine when I specify --set ObjectIds={"Id1-xxxxxxxx,Id2-yyyyyyyy,Id3-zzzzzz"}.
So I want the Terraform code to parse the value as value = "{"Id1-xxxxxxxx,Id2-yyyyyyyy,Id3-zzzzzz"}" instead of value = "{Id1-xxxxxxxx,Id2-yyyyyyyy,Id3-zzzzzz}"

Things I have tried:

1. Doesn't works:

set {
    name  = "ObjectIds"
    value = "{\"${join(",", local.rbac_config.group_oid_list)}\"}"
}

Failue/Error : TF Plan parses the value as

+ value = "{\"Id1-xxxxxxxx,Id2-yyyyyyyy,Id3-zzzzzz\"}"

2. Doesn't works:

set {
    name  = "ObjectIds"
    value = format("\"%s\"", join(",", local.rbac_config.group_oid_list))
}

Failue/Error : TF Plan parses the value as

+ value = "{\"Id1-xxxxxxxx,Id2-yyyyyyyy,Id3-zzzzzz\"}"
Was this page helpful?
0 / 5 - 0 ratings