Terraform meta arguments are resource arguments that can be used with any resource types to alter the default behavior of the resource. For instance a resource that is created once with normal arguments can be created 3 times with similar metadata by adding a meta argument count to the resource.
Today was chill, nice music and wonderful topic on the challenge, welcome to my series in #30DaysOfAwsTerraform, today, I learned about these Terraform meta arguments.
- count - Create multiple resource instances based on a number
resource "aws_s3_bucket" "example" {
count = 3
bucket = "my-bucket-${count.index}"
}
This creates N identical resources with unique names, in this case N is 3.
However, count has a key limitation:
👉 Terraform identifies resources by their index, not their value.
This results in address like:
aws_s3_bucket.example[0]
aws_s3_bucket.example[1]
aws_s3_bucket.example[2]
If you delete bucket ...example-[1] and reduce count from 3 to 2.
- Terraform thinks [1] should still exist, it recreates it
- Then deletes the last one, which is an unintended replacement.
This makes count fragile for production unless used carefully.
- for_each - Create multiple resources with maps/sets
resource "aws_s3_bucket" "example" {
for_each = toset(["bucket1", "bucket2", "bucket3"])
bucket = each.value
}
For each solves the count problem because resources are indexed by keys, not by numeric positions.
So deleting "bucket2" does not affect "bucket1" or "bucket3"
This is best for complex configurations, stable resource identities and large infrastructure.
- depends_on - Explicit resource dependencies
resource "aws_s3_bucket" "dependent" {
bucket = "my-bucket"
depends_on = [aws_s3_bucket.primary]
}
This is useful for explicit resource ordering and extremely useful for ensuring resources are created in specific order.
- lifecycle - Control resource creation and destruction behavior
resource "aws_s3_bucket" "example" {
bucket = "my-bucket"
lifecycle {
prevent_destroy = true # Prevent accidental deletion
create_before_destroy = true # Create new before destroying old
ignore_changes = [tags] # Ignore changes to tags
}
}
This meta argument is added to resources to protect them from deleted and any mishap that may affect it's existence. It can be used to control zero-downtime updates, ignore external changes to specific attributes and protect crititcal resources from deletion.
- provider - Use alternate provider configurations
resource "aws_s3_bucket" "example" {
provider = aws.west # Use alternate provider
bucket = "my-bucket"
}
This can be useful for multi-region deployments and multi-provider setups. Resources can be configured using one terraform project and infrastructure would be provisioned based on the provider(credentials) used.
I also learned how to use the splat operator, it necessarily doesn't add any improvements in value but it makes it fun to write and interest to look at.
## This is fine
output "s3_bucket_arns_count" {
description = "ARNs of S3 buckets created with count"
value = [for bucket in aws_s3_bucket.task_count_buckets: bucket.arn]
}
## But we could use the seplat operator
output "s3_bucket_arns_count" {
description = "ARNs of S3 buckets created with count"
value = aws_s3_bucket.task_count_buckets[*].arn
}
Tomorrow I'll be diving deep into Lifecyle meta argument to understand how to manage lifecyle better.
Hey you can follow along with the challenge, Learn with amazing people from CloudOps Community on discord.
Top comments (0)