Terraform Resources Building Blocks of Infrastructure

Resources are the most important concept in Terraform. Every virtual machine, every database, every network subnet — all of these are resources in Terraform. This topic explains how to write resource blocks, understand their arguments, reference their attributes, and manage their behavior.

What Is a Resource

A resource represents a single infrastructure object. It could be a physical server, a virtual machine, a DNS record, a storage bucket, or any other piece of infrastructure that a cloud provider can create.

Analogy: Lego Bricks

Think of your entire infrastructure as a Lego model. Each individual Lego brick is a resource. A web server is one brick. The database it connects to is another brick. The network they share is a third brick. Terraform snaps those bricks together exactly as you describe in your code.

The Resource Block Syntax

resource "RESOURCE_TYPE" "LOCAL_NAME" {
  argument1 = value1
  argument2 = value2
}
  • RESOURCE_TYPE: Determined by the provider. For AWS it might be aws_instance, aws_s3_bucket, or aws_vpc.
  • LOCAL_NAME: A name you choose. It exists only inside Terraform and is never sent to the cloud provider. Use descriptive names like web_server, app_database, or main_network.

A Real Example: AWS EC2 Instance

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"

  tags = {
    Name        = "My Web Server"
    Environment = "Production"
  }
}

Diagram: Resource Block Anatomy

resource  "aws_instance"   "web_server"  {
   ^           ^                ^
Block       Resource          Your
Type        Type             Local Name
(always     (from the        (you choose)
"resource") provider docs)

  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
      ^                ^
  Required         Required
  Argument         Argument

  tags = { Name = "My Web Server" }
      ^
  Optional Argument (key-value map)
}

Required vs Optional Arguments

Each resource type has its own set of arguments. Some arguments are required — Terraform will refuse to create the resource without them. Other arguments are optional — if you omit them, the provider uses its default value.

You find the full list of arguments for any resource in the provider documentation on registry.terraform.io. For example, searching for aws_instance shows every argument, whether it is required, and what it does.

Referencing Resource Attributes

After Terraform creates a resource, it stores the resource's attributes in the state file. You reference those attributes in other resources using dot notation.

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
}

resource "aws_eip" "web_ip" {
  instance = aws_instance.web_server.id
                    ^            ^    ^
              resource type   name   attribute
}

The format is: RESOURCE_TYPE.LOCAL_NAME.ATTRIBUTE

This reference creates an implicit dependency — Terraform automatically creates the EC2 instance before trying to attach the Elastic IP, because the EIP needs the instance ID.

Common Resource Types Across Providers

ProviderResource TypeWhat It Creates
AWSaws_instanceVirtual machine (EC2)
AWSaws_s3_bucketObject storage bucket
AWSaws_vpcVirtual Private Cloud (network)
Azureazurerm_virtual_machineVirtual machine
Azureazurerm_resource_groupLogical container for Azure resources
GCPgoogle_compute_instanceVirtual machine
GitHubgithub_repositoryA new GitHub repository

Nested Blocks Inside Resources

Some resources contain nested configuration blocks. These are not separate resources — they are sub-configurations that belong to the parent resource.

resource "aws_instance" "app_server" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.small"

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  network_interface {
    network_interface_id = aws_network_interface.main.id
    device_index         = 0
  }
}

The root_block_device and network_interface blocks configure aspects of the EC2 instance itself. They are not standalone resources — they live inside the aws_instance resource block.

Key Points

  • A resource block defines one infrastructure object — a server, bucket, database, or network element.
  • The resource type comes from the provider; the local name is yours to choose.
  • Reference another resource's attribute with the pattern resource_type.local_name.attribute.
  • Attribute references create implicit dependencies that control the order Terraform creates resources.
  • Read provider documentation on the Terraform Registry to find all available arguments for any resource type.

Leave a Comment