Skip to main content

Command Palette

Search for a command to run...

Day 8 of #30DaysOfTerraform — Terraform Meta-Arguments: Writing Dynamic Infrastructure

Updated
4 min read
Day 8 of #30DaysOfTerraform — Terraform Meta-Arguments: Writing Dynamic Infrastructure

#30daysofawsterraform

Day 8 was one of those days where you suddenly see Terraform not just as a way to describe infrastructure, but as a tool that can generate it — based on patterns and inputs instead of copy-paste blocks.

Up until now, each AWS resource we created lived inside its own block. Want two S3 buckets? You wrote two blocks. Need three EC2 instances? That meant three resource definitions. That works at first, but as soon as you start thinking about scale, you see its limitations. On Day 8, I learned how Terraform’s meta-arguments — especially count, for_each, and depends_on — change that game entirely.

What Meta-Arguments Really Do

Meta-arguments are special arguments built into Terraform itself — not part of a provider like AWS. They let you control how many resources are created and in what order, without repeating block definitions.

How Terraform uses meta-arguments to dynamically create and order infrastructure.

Before Day 8, I might write:

resource "aws_s3_bucket" "bucket1" {
bucket = "my-app-bucket-1"
tags = var.tags
}
resource "aws_s3_bucket" "bucket2" {
bucket = "my-app-bucket-2"
tags = var.tags
}

That’s simple and clear — until you need ten buckets. It’s then that repetition gets ugly, error-prone, and hard to maintain.

Meta-arguments give you a better pattern.

Leveraging count for Repetition

The count meta-argument lets you turn one resource block into many:

resource "aws_s3_bucket" "buckets" {
count = length(var.bucket_names)
bucket = var.bucket_names[count.index]
tags = var.tags
}

Here’s what’s nice about this:

  • One block generates multiple resources

  • count.index gives each instance its place

  • You can control names through variables

This makes the infrastructure elastic without duplication.

When for_each Makes More Sense

for_each is similar to count, but more stable when your list of values doesn’t map cleanly to numerical indexes.

resource "aws_s3_bucket" "buckets" {
for_each = toset(var.bucket_names)
bucket = each.value
tags = var.tags
}

This pattern is especially useful when:

  • You need stable resource identity over time

  • The order may change but you don’t want Terraform to recreate everything

  • You derive the list from maps or sets

That predictability matters in production.

Controlling Dependencies with depends_on

Terraform usually figures out dependencies automatically — based on references in the code. But there are real scenarios where the order matters even when there’s no direct reference.

For example:

  • An S3 bucket must exist before a policy attache

  • A VPC must be fully created before subnets

  • Custom IAM roles need to be in place before resources depend on them

In these cases, depends_on gives you explicit control:

resource "aws_s3_bucket" "example" {
bucket = "my-tf-bucket"
tags = var.tags
depends_on = [
aws_vpc.main
    ]
}

This forces Terraform to create the VPC before the bucket — even if otherwise they don’t depend on each other.

What This Changes in Your Terraform Workflow

By the end of Day 8’s exercise, a few clear shifts happened in my thinking:

  • I no longer write the same resource block 5–10 times accidentally

  • I treat Terraform like a mini programming language for infrastructure

  • Dependencies become safer to manage, not accidents waiting to happen

  • I see patterns in infrastructure that can be abstracted and repeated consistently

This is where Terraform starts feeling smart, not just convenient.

A Real-World Example (Beyond S3)

Imagine you’re provisioning multiple security groups, or spinning up clusters with a variable number of instances. With count or for_each, you can scale your HCL just like you scale resources:

  • Create n subnets dynamically

  • Generate multiple IAM users from a list

  • Provision network ACLs for each AZ

  • Build tags or naming conventions that adapt by environment or workspace

These patterns are the difference between a one-off script and infrastructure that grows with requirement changes.

Takeaway

Day 8 wasn’t just a lesson on Terraform syntax — it was about thinking differently:

  1. count and for_each replace repetition with pattern-based infrastructure

  2. depends_on gives you safety when implicit linking isn’t obvious

  3. Terraform starts to feel like a declarative automation language, not just a config tool

Once you stop copying code and start writing patterns with meta-arguments, your infrastructure becomes cleaner, safer, and closer to real engineering.