Terraform Tutorial — HCL Syntax Practice Exercises

2 minute read

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 fmt enforces consistent formatting; terraform validate catches errors early

Next up: Providers — connecting Terraform to cloud platforms.


← terraform fmt & validate Providers →