Terraform: Interpolation for nested local or multiple variables

Created on 13 Jul 2018  ยท  9Comments  ยท  Source: hashicorp/terraform

Hi,

I am trying to interpolate on the basis of two variables. It can be helpful Either we can merge two variables into one or can use interpolation in local (nested local).
Terraform Version 0.11.7
Terraform Code

`variable "var1" {default = "value1"}
variable "var2" {default = "value2"}

locals {
var3 = "${var.var1}_${var.var2}"
}

locals {
value1_value2 = "local1"
value2_value3 = "local2"
value3_value4 = "local3"
}

output "val_output" {
value = "${local.${local.var3}}"
}`

Basically, I want to interpolate it on the basis of two variable "var1 and "var2". Whenever I changed the value of these two variables, the output should be changed accordingly.

output "val_output" { value = "${local.${local.var3}}" }
This is syntatically wrong, But I want it's equivalent solution.
variable "var3" {default ="${var1}_${var2}"} anything equivalent to this, also works for me

config question

Most helpful comment

Export your pairs as a map into the remote state:

output "vpc_ids" {
  value = {
    "test_val1" = "vpc-asdf"
    "test_val2" = "vpc-ghjk"
    "prod_val3" = "vpc-qwer"
  }
}

Reference this using index syntax:

    vpc = "${data.terraform_remote_state.state.vpc_ids["${var.var1}_${var.var2}"]}"

All 9 comments

Hi @farman022,

Terraform does not allow this sort of dynamic construction of names, because it needs to be able to analyze the configuration statically (that is, without evaluating any expressions) in order to determine which order the expressions must be resolved in.

Terraform supports a map data structure that can be used to achieve the effect you were looking for here:

variable "var1" {
  default = "value1"
}
variable "var2" {
  default = "value2"
}

locals {
  var3 = "${var.var1}_${var.var2}"
  values = {
    "value1_value2" = "local1"
    "value2_value3" = "local2"
    "value3_value4" = "local3"
  }
}

output "val_output" {
  value = "${local.values[local.var3]}"
}

By using a real data structure here, Terraform can still see that the val_output output depends on local.values and resolve these in the correct order, dealing with the _index_ operator [local.var3] as a separate step during expression evaluation.

Hi @apparentlymart,
Thanks for your quick reply. It will solve this.

But what my actual problem is, I want to interpolate from state file.
I have multiple entries of vpcs in my state file. And I want to choose different vpc on the basis of variables.
e.g I have 3 entries in the state file.
test_val1 = vpc-asdf test_val2 = vpc-ghjk prod_val3 = vpc-qwer
Code is as below
`
data "terraform_remote_state" "state" {
backend = "s3"

config {
bucket = "bucket-name"
key = "test/folder/terraform.tfstate"
region = "us-east-1"
}
}

//Using below vpc in some resource
vpc = "${data.terraform_remote_state.state.${var.var1}_${var.var2}.vpc}"`

If I will pass var1=test and var2=val1 then I want "vpc-asdf" as vpc id.

We can't pass variables in ${data.terraform_remote_state.state.${var.var1}_${var.var2}.vpc}"
Any equivalent solution also works for me.

Thanks in advance.

Export your pairs as a map into the remote state:

output "vpc_ids" {
  value = {
    "test_val1" = "vpc-asdf"
    "test_val2" = "vpc-ghjk"
    "prod_val3" = "vpc-qwer"
  }
}

Reference this using index syntax:

    vpc = "${data.terraform_remote_state.state.vpc_ids["${var.var1}_${var.var2}"]}"

Hi @apparentlymart,
Thanks a lot for help. Have one more doubt
I had something else in my state file. I wanted to call as below
vpc = "${data.terraform_remote_state.state."${var.var1}_${var.var2}".vpc_id}"
I want this kind of interpolation. Like It will work fine if I write their values of these variables.
vpc = "${data.terraform_remote_state.state.test_val1.vpc_id}"
But I want to pass test and val1 using some variables. I had so many other values, like I am going to pass different domains and different regions to pass as variable (test and val1 are sample).

Any Idea on how to achieve that.

Using maps is the intended way to solve these use-cases. It will never be possible to generate variable references themselves with interpolation, because that would require a very different sort of language interpreter than Terraform currently has.

Any problem you could solve by dynamically generating an attribute name can always, in general, be solved by using a map and dynamically generating the map key.

Can you please help me on how to use maps in this. I don't want to change anything in the state file.
vpc = "${data.terraform_remote_state.state."${var.var1}_${var.var2}".vpc_id}"
vpc = "${data.terraform_remote_state.state.test_val1.vpc_id}"

There is no way to achieve what you are trying to achieve without using a map output.

Hi @farman022!

It seems like we reached an empasse here, and I'm sorry I wasn't able to help you get exactly what you wanted here. As I mentioned in earlier comments, returning a map value as an output is the supported way to meet this sort of use-case, and dynamic references cannot be supported within the Terraform language model.

I'm going to close this out because this issue doesn't represent a work item to be completed, and we use GitHub issues for tracking bugs and enhancements rather than for questions.

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings