Blocks and Arguments
A block has a type, optional labels, and a body of arguments and nested blocks.
Syntax
resource "TYPE" "NAME" {
key = "value"
}Every piece of Terraform configuration is a block. A block starts with a type, may have one or more string labels, and holds a body wrapped in braces.
Anatomy of a block
resource— the block type."aws_instance"— first label (the resource type)."web"— second label (your local name).ami = "..."— an argument inside the body.
Argument values
Values can be strings, numbers, booleans, lists [...], maps {...}, or references to other objects like aws_vpc.main.id.
Example
resource "aws_security_group" "web" {
name = "web-sg"
description = "Allow HTTP inbound"
# A nested block
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}When to use it
- A developer scans a provider's documentation to find which arguments are required vs optional for an aws_rds_instance block before writing the resource.
- A team audits their Terraform files and realizes a nested lifecycle block is controlling replace-on-change behavior across several critical resources.
- An operator uses a nested connection block inside a null_resource provisioner block to configure SSH access for remote-exec commands.
More examples
Block with required arguments
Shows a resource block with top-level arguments (name, vpc_id) and a nested ingress block with its own arguments.
resource "aws_security_group" "app" {
name = "app-sg"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}Nested lifecycle block
Demonstrates a lifecycle nested block that controls how Terraform handles updates and protects a resource from accidental deletion.
resource "aws_instance" "db" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.medium"
lifecycle {
prevent_destroy = true
ignore_changes = [ami]
create_before_destroy = true
}
}Multiple blocks of the same type
Shows that a block type (ingress) can appear multiple times within a parent block to define multiple rules.
resource "aws_security_group" "web" {
name = "web-sg"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
Discussion