Last Updated on May 11, 2024 by Arnav Sharma
In Terraform, both `count` and `for_each` are meta-arguments used to create multiple instances of a given resource or module. They enable the `create multiple` infrastructure objects without manually duplicating `terraform code`. They serve different use cases and have distinct behaviors. Here’s a breakdown to help you choose between them.
terraform count
Use case
When you `need to create` a fixed `number of resources` or when you want to create resources based on a `conditional` logic.
Syntax
resource "type" "name" {
count = 3
...
}
Key characteristics
- It takes a numeric `count value` which is an `integer`.
- Resources are indexed by a zero-based `index`. E.g., `type.name[0]`, `type.name[1]`, etc.
- Changing the order or removing elements can cause resources to be destroyed and recreated, as the indices will change.
Pros
- Simple to use for creating a fixed number of resources.
- Can be combined with `conditional` logic using Terraform’s dynamic block to decide whether to create a resource.
Cons
- Not suitable for `dynamic` sets where the order or the number of elements can change frequently.
- Resource indices might shift if elements are added or removed, leading to potential unintended resource replacements.
for_each in Terraform
Use case
When you want to create resources based on a `set of strings` or a `map or set` of values.
Syntax
resource "type" "name" {
for_each = toset(["value1", "value2"])
...
}
Key characteristics
- It takes a `data structure` like set or map of values.
- Resources are indexed by the values in the set/map, not by a numeric index. The `key and value` pair is important.
- Adding, removing, or reordering elements in the set/map does not cause a shift in resource identities.
Pros
- Suitable for `dynamic` sets or maps.
- Order-independent, meaning resources won’t be unintentionally recreated if the order of elements changes.
- Can use complex data structures (like maps) to create resources with more granularity.
Cons
- Slightly more complex `basic syntax`, especially when working with maps.
- Requires a unique `set of strings`. Duplicates will cause errors.
When to use which?
Use `count` when:
- You want a simple way to `deploy multiple` resources in AWS or Kubernetes.
- Your `terraform configuration` involves `conditional` creation of resources.
Use `for_each` when:
- You’re working with a `dynamic` set or map of values, maybe from a GitHub repo or AWS API.
- You want to avoid potential resource replacements due to order changes.
- You require more granularity and control over resource creation based on complex data structures.
Comparison Table:
Feature/Characteristic | count |
for_each |
---|---|---|
Use case | Fixed number of resources or conditional creation | Based on a set or map of values |
Syntax example | count = 3 |
for_each = toset(["value1", "value2"]) |
Input type | Numeric value | Set or map of values |
Indexing | Zero-based integer (e.g., type.name[0] ) |
Values in the set/map (e.g., type.name["value1"] ) |
Order sensitivity | Order-sensitive (index might shift) | Order-independent |
Pros | – Simple for fixed number – Conditional logic support |
– Suitable for dynamic sets/maps – Avoids unintentional resource recreation |
Cons | – Not suitable for dynamic sets – Potential resource replacements |
– More complex syntax – Requires unique values |
Let’s look at some examples of count
and for_each
using Azure resources in Terraform.
Using count
:
Example 1: Create multiple Azure virtual machines:
resource "azurerm_virtual_machine" "example" {
count = 3
name = "vm-${count.index}"
location = "East US"
resource_group_name = "example-resources"
vm_size = "Standard_F2"
# ... other configurations ...
tags = {
environment = "test"
}
}
In this example, three virtual machines named vm-0
, vm-1
, and vm-2
will be created.
Example 2: Conditionally create an Azure storage account:
resource "azurerm_storage_account" "example" {
count = var.create_storage ? 1 : 0
name = "storageaccount"
location = "East US"
resource_group_name = "example-resources"
account_tier = "Standard"
account_replication_type = "LRS"
# … other configurations …
}
Here, the storage account will be created only if var.create_storage
is set to true
.
Using for_each
:
Example 1: Create Azure virtual networks based on a map:
variable "vnet_configs" {
description = "Map of vnet configurations"
default = {
vnet1 = "10.0.1.0/24"
vnet2 = "10.0.2.0/24"
}
}
resource "azurerm_virtual_network" "example" {
for_each = var.vnet_configs
name = each.key
address_space = [each.value]
location = "East US"
resource_group_name = "example-resources"
# ... other configurations ...
}
This will create two virtual networks named vnet1
and vnet2
with the respective address spaces.
Example 2: Create Azure resource groups based on a set:
variable "resource_group_names" {
description = "Set of resource group names"
default = ["rg1", "rg2", "rg3"]
}
resource "azurerm_resource_group" "example" {
for_each = toset(var.resource_group_names)
name = each.key
location = "East US"
}
This will create three resource groups named rg1
, rg2
, and rg3
.
These examples demonstrate how you can utilize count
and for_each
with Azure resources in Terraform to simplify and streamline infrastructure code.
While both `count` and `for_each` can be used to create multiple instances of resources in Terraform, the choice between them depends on the specific use case and desired behavior. Understanding their characteristics and differences will help in making an informed decision.
FAQ – Terraform Count and For_Each
Q: What is the difference between count and for_each in Terraform?
A: The main difference between count and for_each in Terraform is the way they handle the creation and management of resources. Count is used when you want to create a fixed number of resources based on a given parameter, while for_each is used when you want to create resources based on a dynamic set of values.
Q: How do I use count in Terraform?
A: To use count in Terraform, you need to specify the count meta-argument in the resource block. This meta-argument takes an integer value that determines the number of resources to create. For example:
resource "aws_instance" "example" {
count = 2
# ...
}
Q: How do I use for_each in Terraform?
A: To use for_each in Terraform, you need to specify the for_each meta-argument in the resource block. This meta-argument takes a map or set of strings that defines the dynamic set of values. Each key-value pair in the map or set represents a unique resource to be created. For example:
resource "aws_instance" "example" {
for_each = {
instance1 = "us-west-2a",
instance2 = "us-west-2b",
}
# ...
}
Q: Can I use count and for_each together in Terraform?
A: No, you cannot use count and for_each together in Terraform. They are mutually exclusive, meaning you can only use one of them in a resource block.
Q: What are some use cases for using the count parameter in Terraform?
A: The count parameter in Terraform is commonly used when you want to create a specific number of identical resources, such as multiple EC2 instances or multiple subnets.
Q: What are some use cases for using the for_each meta-argument in Terraform?
A: The for_each meta-argument in Terraform is commonly used when you want to create resources based on a dynamic set of values, such as creating multiple EC2 instances with different configurations or managing IAM roles for a set of users.
Q: What is the recommended approach to use count or for_each in Terraform?
A: The recommended approach to use count or for_each in Terraform depends on your specific use case. If you have a fixed number of resources that you want to create, you can use count. If you have a dynamic set of values that you want to use as input for creating resources, you can use for_each.
Q: How does Terraform deploy resources created with count or for_each when I run terraform apply?
A: When you run terraform apply, Terraform will create the resources specified in the resource block using the count or for_each configuration. If a resource already exists and is no longer specified in the resource block, Terraform will remove that resource.
Q: Can I use conditional logic with count or for_each in Terraform?
A: Yes, you can use conditional logic with count or for_each in Terraform. You can use expressions and functions to conditionally create resources based on specific conditions. For example, you can use an if statement in the resource block to conditionally create a resource based on a certain condition.
Q: What is the version compatibility for count and for_each in Terraform?
A: The count and for_each meta-arguments are available in Terraform version 0.12 and above. If you are using an older version of Terraform, you may need to upgrade to use count or for_each.
Q: Can I nest count or for_each in Terraform code?
A: Yes, you can nest count or for_each in Terraform. This means you can use count or for_each within a resource block that is already using count or for_each. However, it is important to note that nesting can make your configuration more complex and harder to manage, so use it judiciously.
keywords: hashicorp terraform state each.value configure terraform code to use terraform configuration for multiple resources and deploy terraform plan using terraform modules via devops main.tf key and value of input variable dynamically