Terraform Tutorial — HCL Syntax Practice Exercises
Practice writing HCL to reinforce your understanding of blocks, types, interpolation, and for expressions.
Exercise 1: Block Structure
Task: Write a resource block for an aws_instance with the following arguments: AMI ID ami-0c55b159cbfafe1f0, instance type t3.micro, and tags with Name = "web-server" and Environment = "dev".
Answer
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "web-server"
Environment = "dev"
}
}
Exercise 2: Variable Declaration
Task: Declare three variables: region (string, default “us-east-1”), instance_count (number, default 2), and enable_monitoring (boolean, default true). Add descriptions to each.
Answer
variable "region" {
type = string
default = "us-east-1"
description = "AWS region where resources will be created"
}
variable "instance_count" {
type = number
default = 2
description = "Number of EC2 instances to create"
}
variable "enable_monitoring" {
type = bool
default = true
description = "Whether to enable detailed monitoring on instances"
}
Exercise 3: String Interpolation
Task: Given variables project = "myapp" and environment = "staging", write an S3 bucket name that resolves to "myapp-staging-assets-2024". Use string interpolation.
Answer
resource "aws_s3_bucket" "assets" {
bucket = "${var.project}-${var.environment}-assets-2024"
}
Result: "myapp-staging-assets-2024"
Exercise 4: Map and Lookup
Task: Create a locals block with a map called instance_types that maps environment names to instance types: dev → t3.micro, staging → t3.small, prod → t3.large. Then use lookup() to get the instance type for the current environment, with a default of t3.micro.
Answer
locals {
instance_types = {
dev = "t3.micro"
staging = "t3.small"
prod = "t3.large"
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = lookup(local.instance_types, var.environment, "t3.micro")
}
Exercise 5: For Expression
Task: Given a list of server names ["web", "api", "worker"], write a for expression that produces the list ["web.example.com", "api.example.com", "worker.example.com"]. Then write another for expression that filters the original list to only include names shorter than 4 characters.
Answer
variable "server_names" {
default = ["web", "api", "worker"]
}
locals {
# Produce FQDNs
fqdns = [for name in var.server_names : "${name}.example.com"]
# Result: ["web.example.com", "api.example.com", "worker.example.com"]
# Filter to short names
short_names = [for name in var.server_names : name if length(name) < 4]
# Result: ["web", "api"]
}
Chapter Summary
In this chapter, you learned:
- HCL uses blocks as the fundamental building unit — resource, variable, output, provider, terraform, locals, data, module
- Arguments are key-value pairs inside blocks, and expressions compute values using references, operators, and functions
- String interpolation with
${}embeds dynamic values; heredocs handle multi-line strings - Primitive types are string, number, and bool; collection types are list, map, set, and object
- For expressions transform and filter collections
terraform fmtenforces consistent formatting;terraform validatecatches errors early
Next up: Providers — connecting Terraform to cloud platforms.