Skip to content

HCL Fundamentals

Terraform uses HashiCorp Configuration Language (HCL) to define infrastructure as code. This section covers the foundational elements of HCL: blocks, attributes, dynamic blocks, and interpolation expressions, which are essential for structuring and parameterizing Terraform configurations. Understanding these concepts enables precise control over resource creation and dynamic value handling.


Blocks: The Building Blocks of HCL

Blocks are the primary structural elements in HCL. They define resources, providers, variables, and other components. Each block has a name, an opening brace {, and a closing brace }. Blocks can contain nested blocks and attributes.

Example: Resource Block

resource "aws_instance" "example" {
  ami           = "ami-12345678"
  instance_type = "t2.micro"
}
- resource is the block type.
- "aws_instance" is the resource provider.
- "example" is the resource name (optional but recommended).
- Attributes like ami and instance_type are defined within the block.

Blocks can also be nested. For example, the lifecycle block is nested inside a resource block:

resource "aws_instance" "example" {
  ami           = "ami-12345678"
  instance_type = "t2.micro"

  lifecycle {
    create_before_destroy = true
  }
}


Attributes: Key-Value Pairs for Configuration

Attributes are key-value pairs that define properties of a block. They are static and used to specify resource parameters, such as count or tags.

Example: Using Attributes

variable "env" {
  type    = string
  default = "dev"
}
- type and default are attributes of the variable block.
- Attributes are always written in lowercase and are not enclosed in quotes.

Attributes can also be used to reference variables or outputs:

output "instance_id" {
  value = aws_instance.example.id
}


Dynamic Blocks: Generating Multiple Resources

Dynamic blocks allow you to create multiple instances of a resource dynamically, such as multiple EC2 instances. They use the dynamic keyword and are enclosed in braces {}.

Example: Dynamic Block with Count

dynamic "aws_instance" {
  for_each = var.instances
  content {
    ami           = "ami-12345678"
    instance_type = "t2.micro"
  }
}
- for_each iterates over a collection (e.g., a list of instance names).
- The content block defines the attributes for each instance.

Dynamic blocks are ideal for scenarios where the number of resources is not known upfront.


Expressions: Interpolating Values Dynamically

Expressions in HCL allow you to dynamically evaluate values using interpolation syntax ${} or the newer interpolate() function. They are used to reference variables, outputs, or functions.

Example: Interpolation with Variables

resource "aws_instance" "example" {
  ami = var.default_ami
}
- var.default_ami references a variable defined elsewhere.

Example: Functions in Expressions

output "instance_count" {
  value = length(var.instances)
}
- length() is a built-in function that counts elements in a list.

Expressions are evaluated at apply time, enabling flexible and reusable configurations.


Key takeaways

  • Blocks structure Terraform configurations and define resources, providers, and variables.
  • Attributes are static key-value pairs that specify resource properties.
  • Dynamic blocks enable the creation of multiple resources based on input data.
  • Expressions use interpolation and functions to dynamically evaluate values during apply.
  • Combining these elements allows for modular, reusable, and scalable infrastructure code.