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

tfe_variable: list(string) not supported

Open ktham opened this issue 4 years ago • 9 comments

It seems like tfe_variable does not support values where the type is list(string)

  on tfe_workspace_vars.tf line 24, in resource "tfe_variable" "subnet_ids":
  24:   value        = [for subnet in aws_subnet.public : subnet.id]
    |----------------
    | aws_subnet.public is object with 3 attributes

Inappropriate value for attribute "value": string required.

Here's the code

resource "tfe_variable" "subnet_ids" {
  key          = "subnet_ids"
  value        = [for subnet in aws_subnet.public : subnet.id]
  category     = "terraform"
  workspace_id = tfe_workspace.frontend_prd.id
  hcl          = true
  description  = "a useful description"
}

How do I go about doing this?

ktham avatar Jun 25 '20 07:06 ktham

Providers fields can't handle multiple types, so it'll always have to be a string. You'll need to provide HCL—wrapping that array in jsonencode should work. If you had to feed in a map that you wanted to generate programmatically that might be a little painful. Could be a good justification for an hclencode function in Terraform.

bendrucker avatar Jun 25 '20 18:06 bendrucker

Right, I can see that it needs to be a string. I was wondering what other folks are doing, whether they are just manually hand-coding the HCL strings? Luckily HCL lists have the same syntax has JSON lists. Definitely, it would be great to have hclencode

ktham avatar Jun 25 '20 18:06 ktham

Either that, or the TF Cloud API, should support JSON strings

ktham avatar Jun 25 '20 18:06 ktham

Yes, other than the trick of using jsonencode on lists the only option is to specify full strings. Not too bad for an object but for a map you'd be stuck doing what amounts to code generation. The deeper the structure the more impractical this would get.

bendrucker avatar Jun 25 '20 18:06 bendrucker

We've had good mileage with the following hack, which translates "...": to "..." = (HCL).

 hcl = replace(jsonencode(local.test), "/(\".*?\"):/", "$1 = ")

osterman avatar Sep 28 '20 18:09 osterman

Ugh, I just ran into this (value must be a string). Fortunately, @osterman's hack seems to work.

I'd like to see the provider supporting all the valid types allowed for a variable without needing a hack.

robinbowes avatar Oct 05 '20 11:10 robinbowes

Being able to interpret HCL lists or maps (or other complex types) as strings would be a useful feature for cases like this.

matsest avatar Oct 09 '20 12:10 matsest

Hello,

We now starting to move to terrafom Cloud and this seems to be a blocker for us. How are you guys managing TF Cloud variables ?

Changing variables through the TF Cloud UI does not work for us I guess. We need to be able to version control variables and what changes/commit are done there.

Managing the variables via the UI is not a good idea right ? I mean you do not have big control who changed what and when etc.

kereza avatar Jan 08 '21 15:01 kereza

Hi guys, This is work for me: on terraform with terraform cloud provider

//.tfvars
private_subnets  = ["10.10.20.0/24", "10.10.21.0/24"]

//.tf
variable "private_subnets" {
  type = list(string)
}

resource "tfe_variable" "private_subnets" {
  key          = "private_subnets"
  value        = jsonencode(var.private_subnets)
  hcl          = true
  category     = "terraform"
  workspace_id = tfe_workspace.network-base.id
  description  = "Private Subnets"
}

on terraform with aws provider

//.tf
variable "private_subnets" {
  type = list(string)
}
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "${local.fullname}-vpc"

  cidr = var.cidr

  azs                          = var.azs
  private_subnets              = var.private_subnets
  public_subnets               = var.public_subnets
  database_subnets             = var.database_subnets
  create_database_subnet_group = var.create_database_subnet_group

  enable_nat_gateway   = false
  enable_dns_hostnames = true
  enable_dns_support   = true
}

So, list of string is work fine, but map of string is not. But I got a treat in this https://github.com/hashicorp/terraform-provider-tfe/issues/40#issuecomment-545556521

I tested, and now, I totally change from the old way to Terraform Cloud

mvn-bachhuynh-dn avatar Jul 02 '21 10:07 mvn-bachhuynh-dn

In the absence of an hclencode function, I think the provider could do a much better job of doing some of the encoding work on your behalf here. I've created

list(string) just happens to work because the json encoding is identical to the hcl encoding in that case. For hcl types that are simple/known, you can use template strings to reformulate hcl as an hcl string:

value = <<EOT
{
  %{ for k in keys(local.my-map-of-strings) ~}
  ${k} = "${local.my-map-of-strings[k]}"
  %{ endfor ~}
}
EOT

We'll investigate this as a feature request to encode arbitrary hcl expressions on your behalf, so I opened https://github.com/hashicorp/terraform-provider-tfe/issues/727

brandonc avatar Dec 20 '22 18:12 brandonc