terraform-provider-helm
terraform-provider-helm copied to clipboard
Add functionality to set a list
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
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?
I'm using Jenkins -> https://github.com/helm/charts/tree/master/stable/jenkins
@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\"}"
any update on working with list of maps
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)
]
}
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.
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.
+1
+1
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
}
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.