DEV Community

Shi Han
Shi Han

Posted on

tfvar - A tool to help you write Terraform's variable definitions

Whenever I want to start working on an existing Terraform project or using a Terraform module, the first thing that I find myself doing often is looking for the input variables. If the project is small enough, the input variables are usually being declared in the main.tf file. For a well organized Terraform configurations we can find a variables.tf file. However, the locations or where to put the input variable declarations is just a convention and is not enforced syntactically. It is our job as the user of the configurations/modules to track down all variables and make sure that they have the values assigned properly before running terraform plan or terraform apply. It is possible that some variables are hiding somewhere unexpectedly, or we just missed one during the assignment and only realize it when we encounter the following message during the terraform plan phase:

var.bucket_name
  Enter a value:

tfvar is created to solve the problems mentioned above. It is a CLI tool that extracts all variables declared in your Terraform configuration and output them in the format of .tfvars file so that you can use it as a template to write the variable definitions.

In this article, I would like to show you how this tool works.

Simple Demo

Let's say we have the following variable declared in our Terraform configuration

variable bucket_name {
  type    = string
  default = "mybucket"
}

variable instance_name {
  type = string
}

running tfvar . in the root directory of the Terraform configuration will give us the following in the standard output (stdout):

$ tfvar .
bucket_name   = "mybucket"
instance_name = null

Notice that the default value are automatically assigned in the generated definitions. If we want to ignore the default values, there is a --ignore-default flag that we can use. As shown below the with the --ignore-default flag, we get null instead:

$ tfvar . --ignore-default
bucket_name   = null
instance_name = null

A more common usage of tfvar might be to redirect the stdout to a file e.g. inputs.tfvars then change the value null in the file to a desired value.

$ tfvar . --ignore-default > inputs.tfvars

Terraform also allows input variables to be assigned via environment variables. For this, tfvar also provides the -e flag to generate a template in the environment variables format.

$ tfvar . --ignore-default -e
export TF_VAR_bucket_name=''
export TF_VAR_instance_name=''

If we already have some variables defined in terraform.tfvars[.json], *.auto.tfvars[.json], or environment variables (TF_VAR_ followed by the name of a declared variable), (see section "Assigning Values to Root Module Variables" in Terraform's documentation) and want to include there defined values in the generated one, we can use the --auto-assign flag:

$ export TF_VAR_bucket_name="mybucket"
$ export TF_VAR_instance_name="myinstance"
$ tfvar . --auto-assign
bucket_name   = "mybucket"
instance_name = "myinstance"

Finally for completeness sake, we also provide --var and --var-file flags to allow individual variables to be set, just like the -var and -var-file that we have in the terraform (plan|apply) commands. However, I honestly could not think of any use case that I would need this in my workflow 😆.

All --auto-assign, --var, and --var-file flags can be used together, and when they are, they follow the variable definition precedence set by Terraform.

How to get it?

The source codes of tfvar is publicly available on GitHub. In the repository below you will find the installation instructions.

GitHub logo shihanng / tfvar

Terraform's variable definitions template generator.

tfvar

GitHub release (latest by date) Coverage Status Go Report Card Package Documentation GitHub license

tfvar is a Terraform's variable definitions template generator.

For Terraform configuration that has input variables declared, e.g.,

variable "image_id" {
  type = string
}
variable "availability_zone_names" {
  type    = list(string)
  default = ["us-west-1a"]
}
variable "docker_ports" {
  type = list(object({
    internal = number
    external = number
    protocol = string
  }))
  default = [
    {
      internal = 8300
      external = 8300
      protocol = "tcp"
    }
  ]
}
  • tfvar will search for all input variables and generate template that helps user populates those variables easily
    $ tfvar
    availability_zone_names = ["us-west-1a"]
    docker_ports            = [{ external = 8300, internal = 8300, protocol = "tcp" }]
    image_id                = null
    
  • Note that default values are assigned to the definitions by default as shown above. Use the --ignore-default options to ignore the default values
    $ tfvar

tfvar is a tool to solve a trivial problem that would only cost me a few minutes. However, I decided to spend hours to build it hoping that it will save a few extra minutes off from my fellow Terraformers. Some of the codes/ideas are borrowed from Terraform itself which I enjoy exploring a lot. Please give it a try and I would love hear your feedback (via issues/PRs in project repository or comments in this post). If you like it, give the repository a ⭐ which will help other people discover it.

Thanks for reading ❤️.

Top comments (0)