Search code examples
templatesansibleterraform

Terraform template file loop over list


Here is my code. It's supposed to generate an Ansible playbook file:

terraform.tfvars

cl_components = {
   cilium =  {
      enabled = "1",
      version = "1.13.4"
      repository = "https://helm.cilium.io"
   }
   traefik =  {
      enabled = "1",
      version = "24.0.0"
      repository = "https://traefik.github.io/charts"
   }
   cert-manger =  {
      enabled = "1",
      version = "1.14.1"
      repository = "https://charts.jetstack.io"
   }
}

main.tf

locals {

 component             = [
    for k,v in var.cl_components: k ]
  ver           = [
    for k,v in var.cl_components: v.version ]
  repo  = [
    for k,v in var.cl_components: v.repository ]
}

resource "local_file" "generate_playbook" {
  content =  templatefile("xox.tpl",
        {
        component  = local.component
        ver        = local.ver
        repo_url   = local.repo
        }
  )
  filename = "AAAA"
}

And here is the template file:

---
- block:
 %{ for name, ver in zipmap(component, ver)  ~}
  - name: ${name}
    helm:
      name: ${name}
      chart_ref: ${name}
      chart_version: ${ver}
      **chart_repo_url: ${nO idea how to add  the repo_url here...}**
%{ endfor ~}

++added vars.tf

variable "cl_components" {
  type = map(any)
  description = "List of cluster components to be installed"
}

The above code is working almost 100% but I still can't figure out how to add the 3rd variable "repo_url"


Solution

  • You need to refactor your templatefile function arguments to use the entire variable as a parameter value:

    content =  templatefile("xox.tpl", { components  = var.cl_components })
    

    Note that your locals can now be discarded if they are unused otherwise. Now you can iterate through the variable value in your unrendered template and access the nested values accordingly:

    ---
    - block:
    %{ for component, attrs in components  ~}
      - name: ${component}
        kubernetes.core.helm:
          name: ${component}
          chart_ref: ${component}
          chart_version: ${attrs.version}
          chart_repo_url: ${attrs.repository}
    %{ endfor ~}
    

    Note additionally the helm module is updated to its FQCN kubernetes.core.helm as per Ansible best practices.