hashicorp / terraform-provider-template

Terraform template provider
https://www.terraform.io/docs/providers/template/
Mozilla Public License 2.0
130 stars 89 forks source link

Passing List as Template Variables #40

Closed ghost closed 5 years ago

ghost commented 5 years ago

This issue was originally opened by @geek876 as hashicorp/terraform#9368. It was migrated here as a result of the provider split. The original body of the issue is below.


I want to render a template as below (effectively create an AWS Policy)

{
  "Version": "2012-10-17",
  "Statement": [
    {
       ...
       ...
      },
      "Action": "ec2:*",
      "Resource": "xxxx*"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "ec2:*",
      "Resource": "xxx/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [
            "x.x.x.x/24",
            ...
            ...
            "x.x.x.x/16"
          ]
        }
      }
    }
  ]
}

My Template file test.tpl is

{
  "Version": "2012-10-17",
  "Statement": [
    {
       ...
       ...
      },
      "Action": "ec2:*",
      "Resource": "xxxx*"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "ec2:*",
      "Resource": "xxx/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [${whitelist_ips}]
        }
      }
    }
  ]
}

How do I pass ${whitelist_ips} as list to template when I render it ?

I tried the usual way as below but it gives me template parse error

data "template_file" "x" {
  template = "${file("test.tpl")}"

  vars {
    whitelist_ips = [ "${split(",", var.allow_list}" ]
  }
}

My use case is that I don't want to hard-code the IPs within access policy and want to provide a way to pass it as a variable like

variable "allow_list" { default = "x.x.x.x/20,y.y.y/10" }
apparentlymart commented 5 years ago

Hi @geek876! Sorry for the long silence here.

template provider version v2.0.0 and later now support the Terraform 0.12 template syntax, which includes conditionals and iteration as described in the String Templates documentation.

However, for this particular use-case of generating JSON I would recommend using jsonencode instead. We also improved that function in Terraform 0.12 so it now supports all JSON value types, and using it (along with Terraform 0.12's for expressions and conditional operator) can allow dynamically generating JSON structures without needing to manually construct the JSON syntax. Using this function directly inside the Terraform configuration requires Terraform 0.12, but if you are using template provider 2.0.0 or later then you can use jsonencode inside your templates and get the new Terraform 0.12 behavior of it, because the template provider has the Terraform 0.12 language engine embedded inside it.

Between these two (along with the new Terraform 0.12 templatefile function) I think this meets the use-cases represented by this issue, so I'm going to close this out. Sorry this one sat here for so long without any comment. Thanks for suggesting this!