In this post, we’ll review the basic Terraform building blocks from the previous post, Terraform HCL Intro 1: Resources, Variables, Outputs, and compare them to a “function”. This is a contrived analogy, but folks find it helpful. You’ll also learn about Terraform locals.

Terraform Review

Here’s a summary of the Terraform constructs we learned in the previous post in the context of a “function” definition.

  1. Variables: Input arguments to functions.
  2. Resources: Body definition. This includes resources declarations that tell Terraform what to create.
  3. Outputs: Return value of resources.

Here’s the example Terraform code:

variable "length" {
  type    = number
  default = 2
}

resource "random_pet" "this" {
  length = var.length
}

output "pet" {
  value = random_pet.this
}

It results in:

$ terraform apply -auto-approve
Outputs:

pet = {
  "id" = "yellow-unicorn"
  "length" = 2
  "separator" = "-"
}
$

Ruby Function Code Analogy

Theoretically, if the code was written in Ruby instead of Terraform, here’s what the analogous code could look like:

def terraform_apply(length)
  pet = resource("random_pet", "this", length: length)
  output("pet", pet)
end

def resource(type, name, attrs={})
  resource_mock(type, name, attrs)
end

def output(name, value)
  {name => value}
end

def resource_mock(type, name, attrs)
  {
    id: "yellow-unicorn", # mock
    length: attrs[:length],
    separator: "-",
  }
end

Let’s break down the Ruby code and map it to Terraform.

  • Variable: The “Terraform variable” is likened to the length argument in a Ruby method definition.
  • Resource: The body of the Ruby method definition itself is like the “Terraform resource” declaration. In this case, we’re faking it and calling resource_mock to “create” a resource and calling output to build the return value.
  • Output: The “Terraform output” is just the return value. It’s something like a Hash structure, IE: {value: "yellow-unicorn"}.

Remember, we’re just using an analogy to help understand Terraform better. The Ruby code does not create resources. We’re mocking the behavior. Running terraform apply in the terminal would be like invoking the Ruby method like so:

out = terraform_apply(2)
puts "Outputs:"
puts out

The code is available here: 2-function-analogy/1-fake-function. It does a little extra formatting. Running it results in:

$ ruby main.rb
Outputs:

"pet" = {
  "id" = "yellow-unicorn"
  "length" = 2
  "separator" = "-"
}

Analogizing Terraform components to a programming language like Ruby seem to help folks understand Terraform better.

Locals Introduction

If variables can be thought of as Ruby method arguments, then Terraform locals can be thought of as Ruby “local variables”. They’re only available within the function body. Here’s an example:

locals {
  length = 2
}

resource "random_pet" "this" {
  length = local.length
}

output "pet" {
  value = random_pet.this
}

Here’s the analogous Ruby code.

def terraform_apply
  length = 2 # local variable
  pet = resource("random_pet", "this", length: length)
  output("pet", pet)
end

See how the local variable is only available within the terraform_apply function body. Here’s the mimiced output again:

$ ruby main.rb
Outputs:

"pet" = {
  "id" = "yellow-unicorn"
  "length" = 2
  "separator" = "-"
}

Summary

We used a simple function analogy to help understand how Terraform works. We just put a regular programming language spin on it. The metaphor can help folks understand Terraform better. We also learned about locals in this post. In the next post, we’ll cover conditionals.

The source code for the examples is available at: terraform-hcl-tutorials/2-function-analogy

Want It to be Easier to Work with Terraform?

Check out Terraspace: The Terraform Framework.

The Terraform HCL Language Intro Tutorials