terraform-provider-helm icon indicating copy to clipboard operation
terraform-provider-helm copied to clipboard

Add functionality to set a list

Open aaronmell opened this issue 6 years ago • 39 comments

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

aaronmell avatar Jul 17 '18 19:07 aaronmell

This should work:

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

sebastien-prudhomme avatar Jul 25 '18 16:07 sebastien-prudhomme

@sebastien-prudhomme tried this, get the following error

key map "ran" has no value

aaronmell avatar Jul 31 '18 22:07 aaronmell

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

sebastien-prudhomme avatar Aug 01 '18 07:08 sebastien-prudhomme

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)}}"
  }
}

BrunoQuaresma avatar Aug 03 '18 20:08 BrunoQuaresma

@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 avatar Aug 04 '18 02:08 BrunoQuaresma

@BrunoQuaresma It works for simple list, not for map

sebastien-prudhomme avatar Aug 04 '18 07:08 sebastien-prudhomme

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

BrunoQuaresma avatar Aug 04 '18 12:08 BrunoQuaresma

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?

sebastien-prudhomme avatar Aug 05 '18 16:08 sebastien-prudhomme

I'm using Jenkins -> https://github.com/helm/charts/tree/master/stable/jenkins

BrunoQuaresma avatar Aug 05 '18 16:08 BrunoQuaresma

@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 avatar Aug 06 '18 18:08 sebastien-prudhomme

@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

BrunoQuaresma avatar Aug 06 '18 20:08 BrunoQuaresma

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.

sebastien-prudhomme avatar Aug 06 '18 20:08 sebastien-prudhomme

Thanks.

BrunoQuaresma avatar Aug 07 '18 03:08 BrunoQuaresma

+1 for adding this to the provider

acrewdson avatar Jan 29 '19 18:01 acrewdson

+1 for this. It would be very useful.

mogaal avatar Feb 15 '19 10:02 mogaal

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 avatar May 13 '19 15:05 joanayma

@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.

etwillbefine avatar May 13 '19 17:05 etwillbefine

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}).

joshuaspence avatar Nov 08 '19 22:11 joshuaspence

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}"
  }

abelal83 avatar Jan 27 '20 16:01 abelal83

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 }
            ]
          }
        }
      })
  ]
}

theothermike avatar Apr 17 '20 13:04 theothermike

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
  ]
}

tomaszgawlik avatar Jul 08 '20 09:07 tomaszgawlik

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\"}"

biswarup1290dass avatar Dec 22 '20 20:12 biswarup1290dass

any update on working with list of maps

venky999 avatar Jan 20 '21 20:01 venky999

it works like below as well

locals {
    helmChartValues1 = {
        someProperty1= {
            someArray1 = [
                "a", "b"
            ]
        }
        someOtherProperty1 = {
            a = "b"
        }
    }

    helmChartValues2 = {
        someProperty2= {
            someArray2 = [
                "x", "y"
            ]
        }
        someOtherProperty2 = {
            p = "r"
        }
    }
}

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

  values = [
      yamlencode(local.helmChartValues1),
      yamlencode(local.helmChartValues2)
  ]
}


venky999 avatar Jan 21 '21 10:01 venky999

I'd really like to set the set block take a list or map as it's value attribute and "do the right thing". I don't want to have to escape strings so that everything will work as if I'm working on the command line because Terraform has these types that Helm wants already. The values list in the helm_release resource, and the command literals as strings are working work arounds for now, but setting values individually with the set block should work with non-string types, or at least maps and lists.

Type1J avatar Feb 04 '21 04:02 Type1J

I see that this has been marked as "breaking change".

Terraform attempts to parse strings from the command line when the variable that the string defines is typed as map or list in the variable definition. If a type were added to the set block, then an undefined or auto type could preserve the current behavior, while map or list could accept either the parsed string (as it does now), or a Terraform typed value.

As a bonus, a type of string would auto-escape the { and } so that a string that begins and ends with { and } could be used.

All cases would work properly, while a type of auto would preserve current behavior.

Type1J avatar Feb 04 '21 17:02 Type1J

+1

omerfsen avatar Feb 19 '21 13:02 omerfsen

+1

Mark1626 avatar Mar 04 '21 11:03 Mark1626

any updates ? I would like to send a list of objects to the helm without doing the yamlencode ugly . Is it possible now after 3 years ? Something like this :

variable "example" {
   default = [ 
                {  
                 "name": string
                 "ips": list
                }
     ]
}

set { 
   name = example 
   values = var.example   

}

rafaelnpaiva avatar May 07 '21 15:05 rafaelnpaiva

I've done quite a bit of structure gymnastics to get the data that I need into the chart from Terraform. This really needs to be fixed. The yaml encoding that other comments have stated only works when the array values are not maps.

Type1J avatar May 17 '21 23:05 Type1J