Terraform — Creating 20 Azure Virtual Machines with For_Each and a Module

Rafael Medeiros
5 min readJan 10, 2022

--

In a previous post I was talking about how to create virtual machines in Azure using a module that contained all the necessary things to spin up a simple virtual machine. I have repeated the module block to create 02 machines, but as I have mentioned there, repeating the same block of code multiple times is not a best practice.

Today I’m going to talk about the For_each meta argument and re-use the module I’ve created in that previous post to show you how to re-use the module and use just one module block to create as many resources as you wish.

Here is the code if you want to play around with it:

This code will create 02 resource groups, 02 VNETs with 01 subnet each, 20 virtual machines equally distributed between the 02 resource groups.

What is For_each meta argument and How it Works?

In short, the for_each is like a for loop that is well-known in many programming languages, you will be using this to create multiple versions of the same resource, by passing the variables as a map or a set of strings. It can be used with modules and with every resource type because it’s already embedded in the Terraform language.

Here is an example of how the resources will be created if we have a map variable called virtual_machines with 03 values in it:

In the next section, I will show you how to reference each resource created in a block that contains the for_each argument.

The good thing when using map variables is that you can have multiple values, that’s why we are using size, location, resource_group and subnet_id.

For simplicity sake, some values were hidden in the previous image, but you can check all of them in the “locals” block in the code.

In the image above, if you retrieve the first value of virtual machine, you will have the following:

key = vm1value = size, location, resource_group, subnet_id

each of these values are key-pair values, like:

location = “eastus”

I will show you how to reference them in the code in the next sections.

Referring to Instances in For_each

When you have a block that uses for_each argument, you may have many resources created by a single resource block. So how do you refer them in case you need to pass the recently created resource to be an input to another resource?

Multiple instances are prefixed with module.<NAME>[<KEY>] ,so for example azurerm_virtual_machine.vm refers to the block of resources, while

azurerm_virtual_machine.vm["vm1"], azurerm_virtual_machine.vm["vm2"] refers to each individual instance that was created.

The following example shows how to refer to an instance during an output:

Worth noting that I’m using a module to retrieve a value from, and this module should have an output configured on it, like this:

The [*] is used by Terraform to understand that you can have more than one instance in that module, and you are not specifying exactly from where you are getting the value, you will be specifying this when you are creating an output for instance, where you refer to the object by using the [“vm1”] like the previous example.

Referring to Values in For_each

These are the values that we will be using for the vms:

For simplicity sake, I just reduced them to 03. During each iteration, it will get the values like the following:

You have to use the “each” reserved word for Terraform to understand that you are using values from each line of the virtual_machine variable.

This is the same process for the rest of the iterations, each value will be taken from each row of the virtual machine map variable.

Testing the Code

Now that we understood the process, it’s time to put our code to proof and see how it goes.

66 resources to be created, including the network interface cards and the random_strings.

After running our code, it successfully created 10 virtual machines in one resource group and more 10 in the other:

The outputs are working correctly:

It took less than 5 minutes to have 20 virtual machines deployed!

And our code still just having one resource block.

How good is this? With just one block of a module, you were able to deploy all the 20 virtual machines, and you can increase this number as long as you update the values of the map variable.

Don’t forget that your subscription might have a limit to create resources, if you do, then you have to increase the quotas for each resource:

Wrap Up

In today’s post you have learned how to work with modules and for_each in Terraform, the benefits of using it and how fast it is to deploy our resources.

Now look at your Terraform code and try to implement for_each on it. Another use case for this could be NSG rules, Key vault Secrets and so on, everything that have to repeat the same block multiple times can be implemented using for_each.

That’s it for today guys, if you have any questions, feel free to ask them in the comments. Happy Studying!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Rafael Medeiros
Rafael Medeiros

Written by Rafael Medeiros

DevOps Engineer | CNCF Kubestronaut | 3x Azure | Cloud | Security | Devops | Another IT Professional willing to help the community

Responses (1)

Write a response