Jithin Kumar S
Jithin Kumar S

Reputation: 873

How do I get the value of a variable whose name is based on another variable?

inside variables.tf

locals {
  env_name = lower(terraform.workspace)
}

inside tfvars

hc-auth-demo-port= 8003

main.tf

port= ${var.hc-auth-"${local.env_name}"-port}"

Getting error:

This character is not used within the language.

Based on an earlier answer, I've tried (which fixes that error, but doesn't solve my actual problem):

port = "${var.hc-auth}-${local.env_name}-port"

It is saying hc.auth is not declared:

An input variable with the name "hc-auth" has not been declared. This variable can be declared with a variable "hc-auth" {} block.

I've declared hc-auth-default-port in the variables, so how do I append all the 3 words to build that variable name and get its value?

this is the error msg --> this means it is looking for a variable hc.auth but in my case I wanted hc-auth-default-port interpolation

How do I get the value of a variable whose name is based on another variable?

Upvotes: 6

Views: 4965

Answers (1)

Alain O'Dea
Alain O'Dea

Reputation: 21686

Terraform does not support building variable names from variables, but there is a workaround: using maps.

Provide a map of ports in terraform.tfvars (notice the use of snake_case, not skewer-case, as snake_case is the preferred code style for Terraform code):

hc_auth_ports = {
  demo = 8003
}

Declare a map(int) variable hc_auth_ports in main.tf or variables.tf:

variable "hc_auth_ports" {
  type = map(int)
}

Update main.tf to look up the port for the environment in the hc_auth_ports:

port = var.hc_auth_ports[local.env_name]

Now, you should get the outcome you want:

  1. declare the ports for each environment in tfvars
  2. able to choose the port for the current environment in main.tf

Original Answer to original question

The original question was effectively:

Why do I get error "This character is not used within the language." when trying to append variables in a string?

Here is the port assignment with the errors corrected:

port = "${var.hc-auth}-${local.env_name}-port"

This kind of expression is called a String Template.

Here is the original (broken) expression:

port = ${var.hc-auth-"${local.env_name}"-port}"

Here is why it doesn't work:

  1. missing double quote (") to start the string before ${var.hc_auth (likely what triggered the error message since ${ is illegal outside a String Template)
  2. missing closing brace (}) to close the variable interpolation of var.hc_auth
  3. incorrect double quote (") before ${local.env_name}
  4. incorrect closing brace (}) after -port

An interpolation takes the following form:

${hcl_expression}

It must be inside a string.

A ${ ... } sequence is an interpolation, which evaluates the expression given between the markers, converts the result to a string if necessary, and then inserts it into the final string:

"Hello, ${var.name}!"

In the above example, the named object var.name is accessed and its value inserted into the string, producing a result like "Hello, Juan!".

From Interpolation - String Templates - Configuration Syntax

Upvotes: 6

Related Questions