

Create Multiple Resources at Once With Terraform for_each
source link: https://xebia.com/blog/create-multiple-resources-at-once-with-terraform-for_each/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Create Multiple Resources at Once With Terraform for_each
16 Jun, 2022
Creating dynamic infrastructures with Terraform used to be a challenge. Start using the for_each-meta-argument to safely and predictably create your infrastructure while limiting code duplication.
This post gives you a real-world example of how to effectively use the for_each meta-argument of Terraform 0.12.
As an example, I will take the GCP storage bucket
module I talked about in my previous post about the object type. The module will be refactored so I can create multiple buckets by providing it with all of the bucket settings at once. We will see how using the for_each
meta-argument will make it easier to add, and remove buckets with Terraform.
The previous approach using count
Previously you would use the count
meta-argument to create multiple resources with one definition. If you did, you’ll also know the problems of this workaround as it doesn’t allow you to override the variables for each resource that easily, and it can give unwanted results if you change the count value and thus removing a resource from the list. In the example below, I will show you how you may have used this meta-argument:
resource "google_storage_bucket" "count" {
count = 4
name = format("bucket_%s", count.index)
location = "europe-west4"
storage_class = "REGIONAL"
bucket_policy_only = true
}
When you use count
as in the example above, you are limited in the variables passed to the resource definition. As a solution, you might have used a lookup variable like this:
locals {
bucket_settings = [
{ name = "bucket_1", location = "europe-west4", bucket_policy_only = false },
{ name = "secrets", location = "europe-west1", bucket_policy_only = true },
{ name = "documents", location = "europe-west1", bucket_policy_only = true },
{ name = "public", location = "europe-west4", bucket_policy_only = false },
]
}
resource "google_storage_bucket" "list" {
count = 4
name = local.bucket_settings[count.index].name
location = local.bucket_settings[count.index].location
storage_class = "REGIONAL"
bucket_policy_only = local.bucket_settings[count.index].bucket_policy_only
}
While this does give you more flexibility, it still gives you some problems when you want to remove or change the order of our resources. Terraform will create the resources, each with their own state key, which is using the count index number:
google_storage_bucket.list[0]
google_storage_bucket.list[1]
google_storage_bucket.list[2]
google_storage_bucket.list[3]
When removing a bucket, which is not the last one in the list, all buckets after that will shift 1 position. This results in Terraform wanting to delete them and recreate them with a new state key.
The Terraform for_each
Meta-argument
As of Terraform 0.12.6, we can use the for_each
function in the creation of resources. I’ve updated the previous example with this new for_each
function.
locals {
bucket_settings = {
"bucket_1" = { location = "europe-west4", bucket_policy_only = false },
"secrets" = { location = "europe-west1", bucket_policy_only = true },
"documents" = { location = "europe-west1", bucket_policy_only = true },
"public" = { location = "europe-west4", bucket_policy_only = false }
}
}
resource "google_storage_bucket" "map" {
for_each = local.bucket_settings
name = each.key
location = each.value.location
storage_class = "REGIONAL"
bucket_policy_only = each.value.bucket_policy_only
}
I have changed the local variable from a list into a map and replaced the list-lookup with each.value.<attribute>
. for_each can work either with a set of string or a map value. In my case, I’ve chosen a map, so I can pass separate settings for each bucket while using the keys for generating my bucket names. If you run this code, you will see Terraform will use the map keys as an index for the state keys of your resources:
google_storage_bucket.map["bucket_1"]
google_storage_bucket.map["documents"]
google_storage_bucket.map["public"]
google_storage_bucket.map["secrets"]
This will allow you to add or remove buckets to your map without worrying that Terraform will touch the other resources created.
Conclusion
You now know how to utilize this awesome for_each functionality that has been added in Terraform 0.12. If you want to see this fully in action, you can check out the GCP bucket module I’ve created. In this module, I’ve combined the use of the terraform object type with the for_each meta-argument having a flexible module as a result.
</div
Recommend
-
156
Now that Google has added multi-user support, the ability to set reminders, and other key functionality to the Google Home, there's not much to complain ab... by Corbin Davenport in Google, Google Home, Google Home Max, Google Home Mini, News
-
42
Get more information for a single or multiple repositories with a single command. Inspiration Simultaneously working with...
-
20
Edit Multiple Files at once in Neovim2020-10-28Nvim247 words 2 mins read 140 times readWhen I was in a folder and tried to edit multiple files using gl...
-
13
Terraform HCL Intro 4: Loops with Count and For Each Posted by Tung Nguyen on Oct 4, 2020 In this post, we’ll cover Terraform looping constructs. Terraform is declarativ...
-
10
Update or create multiple languages at once using eZ Platform PHP API It is possible to create or update content in multiple languages at once. There is one...
-
8
Today, we’ll cover a cool Terraspace feature. It allows you to deploy all of your infrastructure in a single command. terraspace all up Terraspace...
-
16
11 Apr 2020 Updated: 14 Apr 2020 essays ...
-
6
How to add multiple labels in legend, one for each curve advertisements I have written a code to generate a graph for 3 different vector sets....
-
2
Conditions with for_each in Terraform Conditions in Terraform are well-known and can provide in combination with the for_each argument a lot of flexibility. In today’s blog post I walk you thr...
-
11
include <bits/stdc++.h>using namespace std;int number; int l1,r1,l2,r2;int main(){ cin >> number; for(int i = 0; i < number; i++){ cin >> l1 >> r1 >> l2 >> r2; //basically, check if...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK