How to use loops in Terraform

Networking infrastructure is critical stuff for many organizations. The benefits of using cloud services have made many organizations transfer their workloads to the cloud. Efficiently managing the resources inside these cloud infrastructures requires advanced skills(tools) and good experience. There are many tools available today for automating cloud-based infrastructure. Terraform is one such tool that has recently gained enormous popularity in the DevOps world.

What Terraform is all about?

Terraform is an Open source tool developed and maintained by HashiCorp. It uses its own Hashicorp Configuration Language- HCL to provision multiple cloud service providers. Basically, Terraform will compare your current infrastructure configuration to the desired state and only modify those parts of the infrastructure that are required to reach the desired state. 

Terraform uses plugins, which it calls providers, corresponding to different cloud and enterprise service providers such as AWS, Azure, vSphere etc. A terraform project is contained inside its own directory that contains various project-related files. Terraform does not affect all resources of your cloud account; it only deals with the components that are managed through its plan. It uses state files(of JSON format) to store the current state of the infrastructure.

What makes Terraform stand out?

One of the interesting things that stands out Terraform from other tools is that it lets you tell what you want and it will resolve how to get that without the need to worry about all the base-level commands to get it done. Another less known fact (or you may already know it), is that plugins that bind with the cloud service provider’s APIs, are currently designed by the cloud service provider themself. This means AWS itself maintains its AWS provider for Terraform. This is a good thing as the provider will remain updated with the AWS API space.

What will we learn here?

In this tutorial, I will show you how to use loop constructs in Terraform. We will see several examples of using some loop constructs. Let us now continue with this post.

Let’s Get Started…

There are different types of loop constructs in terraform, each has its specific case of use:

1. count’ parameter: This creates multiple copies of a resource or module. A count argument will result in as many objects as the count value for that resource or module. The count argument takes a whole number.

There is also a count-type object that works with the count argument. Using this object we change the configuration per instance. It uses ‘index’ as the only attribute. The index number starts with zero. We will later see the uses of each case.

Example of using ‘count’ parameter:

The below example show the procedure of creating multiple Identical EC2 Instances:

resource "aws_instance" "web-ec2" {
  count         = 5
  ami           = “ami-xxxx”
  instance_type = “t2.micro”

Count parameter example with identical EC2 instance.

Sample Output:

Plan: 5 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
Enter a value:

The above code will create 5 identical EC2 instances. In case we need to create multiple EC2 instances with different naming, the above code will be modified as:

resource "aws_instance" "web-ec2" {
  count         = 5
  ami           = ami-xxxx
  instance_type = t2.micro
tags {
Name = “my-server-${count.index}”

The above configuration will result in five EC2 instances named: my-server-0 to my-server-4.

Count parameter example with non-identical EC2 instance.

2. ‘for’ expressions: The ‘for’ expression in Terraform loops over the items inside a list, map, an object etc. It has the following syntax:

[for <item or element> in <Name_of_List> : <OUTPUT>]

Here ‘Name_of_List’ is the name of the List to iterate over. ‘Item’ or ‘element’ is the name of the variable attached to every element in the above LIST.

Example of using ‘for’ expression: The below code will print the uppercase version of the items inside the list:

variable "demo" {
 description = "A list of items"
 type        = list(string)
 default     = ["one", "two", "three"]
output "upper_case" {
 value = [for name in var.demo : upper(name)]

3. ‘for_each’ expressions: Terraform introduced the ‘for_each’ expressions from version 0.12. Using this expression we can iterate items inside a list, set and map. We can use this expression for creating numerous replicas of a complete resource or replicas of an inline-block inside a resource. The basic format for ‘for_each’ expression is:

resource "<Name_of_the_Provider>_<Type_of_resource>" "<identifier>" {
 for_each = <COLLECTION(set or map)>  
[Code ...]

Here specify the provider in place of ‘Name_of_the_Provider’. ‘Type_of_resource’ specifies the type of resource to yield.

Example of using ‘for_each’ expression: The below example demonstrate how to create IAM users using the ‘for_each’ expression: 

resource "aws_iam_user" "iam-accounts" {
  for_each = toset( ["tecofers", "HowToForge", "Demo"] )
  name     = each.key

The ‘toset’ function is used for conversion to sets. ‘each.key’ is a map key relative to an instance. Similarly ‘each.value’ is a map value relative to an instance. The above code will create three IAM users mentioned inside the list.

Note: The count and for_each constructs both cannot be present simultaneously. 

Wrapping Up

In this guide, we have seen about different loop constructs in Terraform and how they can be used. In the upcoming post we will try to explore Terraform modules, so stay tuned with HowToForge.


Share this page:

Suggested articles

0 Comment(s)

Add comment