Updating Helm Chart for dynamic IP addresses fails

39 Views Asked by At

I'm trying to build up a Helm chart for nginx with Terraform. I created an additional values.yaml file with the following content:

allowableIPs: "{{ .Values.allowableIPs }}"

The Terraform code to fill in the information is like, yes, should have thought of another name for the IP addresses:

variable "allowable_ips" {
  type    = list(string)
  default = []
}
resource "helm_release" "nginx" {
  name       = "nginx"
  chart      = "${path.module}/nginx"
  namespace        = "ns-rebotics"
  force_update     = false
  recreate_pods    = true
  create_namespace = true

  set {
    name  = "allowableIPs"
    value = jsonencode(var.allowable_ips)
  }
}

and the variable to be passed in, I just typed rather than created via code to limit my possibility for errors. It is in a locals.tf file:

ip_addresses = ["52.24.34.195/32","34.216.251.107/32","183.14.29.54/32","212.112.111.26/32","172.112.148.169/32","52.34.216.69/32","104.2.87.241/32","107.2.155.54/32","100.15.233.56/32"]

When I execute the TF, I get the following error:

Error: failed parsing key "allowableIPs" with value ["52.24.34.195/32","34.216.251.107/32","183.14.29.54/32","212.112.111.26/32","172.112.148.169/32","52.34.216.69/32","104.2.87.241/32","107.2.155.54/32","100.15.233.56/32"], key "107/32"" has no value (cannot end with ,)

with module.client_instance.module.kubecharts.helm_release.nginx, on REB3Modules/container/nginx/v1/nginx.tf line 63, in resource "helm_release" "nginx": 63: resource "helm_release" "nginx" {

2

There are 2 best solutions below

1
javierlga On BEST ANSWER

The answer provided by @helpinghand is correct, just a small fix for the template file (remove %):

# custom-values.yaml.tpl
allowableIPs:
%{ for ip in allowable_ips ~}
- "${ip}"
%{ endfor ~}

If you don't want to use the templatefile, you can use the following code to apply the required values.

locals {
  allowable_ips = format("{%s}", join(",", var.allowable_ips))
}

resource "helm_release" "nginx" {
  name             = "nginx"
  chart            = "${path.module}/nginx"
  namespace        = "ns-rebotics"
  force_update     = false
  recreate_pods    = true
  create_namespace = true

  set {
    name  = "allowableIPs"
    value = local.allowable_ips
  }
}

This will format the variable with required format by Helm, that can be set using the Helm CLI:

helm install foo --set bar={a,b,c}.
1
helpinghand On

For passing complex lists from Terraform to a Helm chart, an effective methods that has worked for me is to use the values block in the helm_release resource along with a YAML file.

To address the issue you are facing, I will suggest you create a file named custom-values.yaml.tpl in your Terraform module directory. This template will include placeholders for dynamic content that Terraform will replace, which in your case are the allowable IPs. So something like this:

# custom-values.yaml.tpl
allowableIPs:
  %{ for ip in allowable_ips ~%}
  - "${ip}"
  %{ endfor ~%}

Modify your Terraform helm_release resource to use the values block to set the dynamically generated values file. Use Terraform's templatefile function to fill in the template with the actual IPs from your local.ip_addresses or var.allowable_ips. (I see you specified both, but you can stick with ip_addresses in your local file). For this change, it will look like:

resource "helm_release" "nginx" {
  name             = "nginx"
  chart            = "${path.module}/nginx"
  namespace        = "ns-rebotics"
  force_update     = false
  recreate_pods    = true
  create_namespace = true

  values = [templatefile("${path.module}/custom-values.yaml.tpl", {
    allowable_ips = local.ip_addresses
  })]
}

This way templatefile will read your custom-values.yaml.tpl, fill it with the IPs from local.ip_addresses, and pass the rendered YAML as a value to the Helm chart.

Also make sure your locals block is accessible in the scope where you're defining your helm_release resource.

Give this a go and let me know if it helps.