DEV Community

Cover image for Day 8: Mastering Terraform Meta Arguments - The Power of Control and Iteration
Tran Huynh An Duy (Andy)
Tran Huynh An Duy (Andy)

Posted on

Day 8: Mastering Terraform Meta Arguments - The Power of Control and Iteration

Welcome back to the 30 Days of AWS Terraform challenge! We are diving into a crucial topic today: Meta Arguments. While standard resource arguments (like bucket or region) are provided by the specific provider (e.g., AWS), Meta Arguments are supplied by Terraform itself. They provide powerful ways to implement advanced logic, control deployment flow, and avoid writing external scripts.

Today, we focus on three essential meta arguments: depends_on, count, and for_each.

1. Controlling Sequence with depends_on

When you define multiple resources in a Terraform file, how does Terraform know the order in which to provision them? While Terraform often detects implicit dependencies (e.g., if Resource B uses an output from Resource A), sometimes you need to enforce a specific creation order,this is known as explicit dependency.
The depends_on meta argument establishes this explicit dependency. It ensures that Resource A is fully provisioned and healthy before Terraform proceeds to create Resource B.

Controlling Sequence with depends_on

Scenario Flow: Suppose you need a second resource (bucket_two) to only be created after the primary resource (bucket_one) is fully operational:

// Resource 1: Primary Bucket (Created First)
resource "aws_s3_bucket" "bucket_one" {
  // configuration details...
}

// Resource 2: Dependent Bucket (Waits for Resource 1)
resource "aws_s3_bucket" "bucket_two" {
  depends_on = [
    aws_s3_bucket.bucket_one
  ]
  // configuration details...
}

Enter fullscreen mode Exit fullscreen mode

As demonstrated in our hands-on session, Terraform executes the creation of bucket_one first. Only once its creation is complete does it proceed with bucket_two.

2. Iteration for Lists using count

If you need to create multiple, identical resources such as 10 S3 buckets or 5 EC2 instances, you don't need to write the resource block 10 or 5 times. Instead, you use the count meta argument.
count works well when iterating over a variable defined as a list. Lists are ordered collections accessed by a numerical index starting at zero.
We can set count dynamically using the length() function on a list variable. To reference each element during the iteration, we use count.index.

 Iteration for Lists using count

Code Example (Creating Multiple Buckets from a List):

variable "bucket_names" {
  type = list(string)
  default = ["my-unique-bucket-1", "my-unique-bucket-2"]
}

resource "aws_s3_bucket" "bucket_one" {
  // Sets count to 2, based on the list size [10]
  count = length(var.bucket_names)

  // Iterates through the list using the index (0, 1, 2...) [10]
  bucket = var.bucket_names[count.index]
}

Enter fullscreen mode Exit fullscreen mode

3. Iteration for Sets and Maps using for_each

While count is excellent for lists, it won't work effectively with sets or maps because they lack fixed indexes. For these scenarios, we use for_each, which acts like a specialized for loop.
for_each iterates through the elements of the set or map. When using for_each, we reference the elements using the special each object.

Sets: In a set of strings, there is no key/value distinction. Therefore, each.key and each.value both refer to the content of the element.

Maps: Maps are defined by distinct key-value pairs (like JSON syntax). When iterating a map, each.key accesses the map key (e.g., name), and each.value accesses the corresponding map value (e.g., Piyush).

Iteration for Sets and Maps

Code Example (Creating Buckets from a Set):

variable "bucket_name_set" {
  type = set(string)
  default = ["set-bucket-a", "set-bucket-b"]
}

resource "aws_s3_bucket" "bucket_two" {
  // Iterates through every element in the set [11]
  for_each = var.bucket_name_set

  // In a set, key and value are the same [13]
  bucket = each.value 
}
Enter fullscreen mode Exit fullscreen mode

Mastering these meta arguments allows you to write concise, reusable, and powerful Terraform configurations that efficiently manage dependency and repetition.


Ready to solidify your understanding? Make sure to complete the practical exercises and tasks available in the Day 8 GitHub repository from @piyushsachdeva

Top comments (0)