DEV Community

drewmullen
drewmullen

Posted on • Edited on

Terraform: use a variable's value to define another variable

I was looking for a way to set a default terraform variable value from another variable but also have a way to override. Terraform does not allow this natively:

variable nickname {
  default = var.fullname
}

variable fullname {
  default = "richard"
}

output name {
  value = var.nickname
}

$ terraform apply

Error: Variables not allowed

  on var-to-var.tf line 2, in variable "nickname":
   2:   default = var.fullname

Variables may not be used here.
Enter fullscreen mode Exit fullscreen mode

But I was able to get this working, see below!

Disclaimer: This does not technically default the value from one variable to another. However, it provides the desired output; at least the one I was looking for.

variable fullname {
  default = "richard"
}

variable nickname {
  default = ""
}

output name {
  value = var.nickname != "" ? var.nickname : var.fullname
}
Enter fullscreen mode Exit fullscreen mode
$ terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
name = richard
Enter fullscreen mode Exit fullscreen mode
$ terraform apply -var nickname=drew
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
name = drew
Enter fullscreen mode Exit fullscreen mode

Top comments (7)

Collapse
 
david_j_eddy profile image
David J Eddy

The reason this works is due to Terraform variable values (and providers) do not support interpolation. The TF engine is not yet running when the values are assigned.

outputs on the other hand are evaluated near the end of a TF life cycle. Thus the engine is running and interpolation is supported.

Another way to to this is use a null object and apply the value = "${var.nickname != "" ? var.nickname : var.fullname}" logic to it.

Side note; might want to check out upgrading the TF 0.12.x when you get a chance. The resource/var/output sytax changes a bit.

Collapse
 
colinbjohnson profile image
Colin Johnson

This is brilliant -> thank you!!!

Collapse
 
augustgerro profile image
Alexey B.

I like it! realy useful while HCL does not not support interpolation in this way

Collapse
 
spodalov profile image
Sergey Podalov

Thanks, but this works only for outputs.

Collapse
 
drewmullen profile image
drewmullen

worked for for me with an ssm parameter value:

resource "aws_ssm_parameter" "foo" {
  name  = "foo"
  type  = "String"
  value = var.nickname != "" ? var.nickname : var.fullname
}

Enter fullscreen mode Exit fullscreen mode
$ tf apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_ssm_parameter.foo will be created
  + resource "aws_ssm_parameter" "foo" {
      + arn       = (known after apply)
      + data_type = (known after apply)
      + id        = (known after apply)
      + key_id    = (known after apply)
      + name      = "foo"
      + tier      = "Standard"
      + type      = "String"
      + value     = (sensitive value)
      + version   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_ssm_parameter.foo: Creating...
aws_ssm_parameter.foo: Creation complete after 4s [id=foo]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Enter fullscreen mode Exit fullscreen mode
Collapse
 
spodalov profile image
Sergey Podalov

It woks in a resource section and in a output section but it does not work if try to set an input variable this way.

Thread Thread
 
drewmullen profile image
drewmullen

correct. this is a work around for similar functionality