Resources, arguments and references

Terraform · Essentials · 10 min

Resources are the core of every configuration; references create the dependency graph automatically.

A resource block declares one infrastructure object:

resource "<TYPE>" "<NAME>" { ...arguments... }

The type (aws_instance, google_storage_bucket) comes from a provider; the name is your local label. Together they form the address aws_instance.web, unique in a module.

Inside, arguments set the object's configuration: strings, numbers, booleans, lists, maps, and nested blocks (like ingress { ... }). Each resource type's arguments and exported attributes are documented on its provider's registry page; that page will be your main reference.

References use the form <TYPE>.<NAME>.<ATTRIBUTE>: aws_vpc.main.id. An attribute may be known after apply (an ID the cloud assigns), shown as (known after apply) in plans. Referencing another resource creates an implicit dependency: Terraform creates the VPC before the subnet that uses its ID, and destroys in reverse.

HCL basics: # comments, strings in double quotes with ${...} interpolation, heredocs (<<-EOT) for multi-line text. All .tf files in a directory form one configuration, so splitting into main.tf, network.tf, variables.tf and outputs.tf is purely organisational.

terraform fmt formats files to the canonical style and terraform validate checks syntax and types; run both before every commit.

Example

resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  tags                 = { Name = "main" }
}

resource "aws_subnet" "app" {
  vpc_id            = aws_vpc.main.id        # reference: implicit dependency
  cidr_block        = "10.0.1.0/24"
  availability_zone = "eu-west-1a"
  tags              = { Name = "app-${aws_vpc.main.tags.Name}" }
}
# terraform plan
#   + resource "aws_subnet" "app" {
#       + id     = (known after apply)
#       + vpc_id = (known after apply)

Remember

  • resource "type" "name" gives the address type.name
  • References like aws_vpc.main.id create implicit dependencies
  • All .tf files in a directory are one configuration; use fmt and validate

Watch out for

  • Renaming a resource's local name and being surprised the plan destroys and recreates it (use a moved block).

Check yourself

  1. Why does Terraform create aws_vpc.main before aws_subnet.app here?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.hashicorp.com/terraform/language/resources