Terraform nested double for-loop

Preface

Terraform’s HCL language does not provide us with a double for loop out of the box. However this is still possible albeit in a more complicated way using the power of math! 

Tutorial

1 Create two list variables

For better understanding we will use list_1 and list_2 in this example. list_1 containing colors and list_2 containing shapes. 

Create your variables.tf

variable "list_1" {
  type    = "list"
  default = ["Red", "Blue", "Yellow", "Red"]
}

variable "list_2" {
  type    = "list"
  default = ["Square", "Triangle", "Circle", "Rectangle"]
}

2 Create your resource

This will be the resource where you want use your nested loop. We will be applying two tags onto a VPC – List1 and List2. I realize this creates an unreasonable amount of VPC but we are only looking at the logic of what we are trying to accomplish. 

Since there are a list of 4 items in both list_1 and list_2 there will be 16 resources created with every item of list_1 mapping to every item in list_2

Create your main.tf

resource "aws_vpc" "aws_vpc_test" {
  count = "${length(var.list_1) * length(var.list_2)}"

  cidr_block = "10.${count.index}.0.0/16"

  tags = {
    List1 = "${var.list_1[count.index / length(var.list_2)]}"
    List2 = "${var.list_2[count.index % length(var.list_2)]}"
  }
}

If you do a terraform plan 16 different VPC resources will be planned for creation with each one having a unique mapping of list_1 and list_2.

Output:

  + aws_vpc.aws_vpc_test[0]
... cidr_block: "10.0.0.0/16" tags.%: "2" tags.List1: "Red" tags.List2: "Square" + aws_vpc.aws_vpc_test[1] ... cidr_block: "10.1.0.0/16" tags.%: "2" tags.List1: "Red" tags.List2: "Triangle" + aws_vpc.aws_vpc_test[2] ... cidr_block: "10.2.0.0/16" tags.%: "2" tags.List1: "Red" tags.List2: "Circle" + aws_vpc.aws_vpc_test[3] ... cidr_block: "10.3.0.0/16" tags.%: "2" tags.List1: "Red" tags.List2: "Rectangle" + aws_vpc.aws_vpc_test[4] ... cidr_block: "10.4.0.0/16" tags.%: "2" tags.List1: "Blue" tags.List2: "Square" + aws_vpc.aws_vpc_test[5] ... cidr_block: "10.5.0.0/16" tags.%: "2" tags.List1: "Blue" tags.List2: "Triangle" + aws_vpc.aws_vpc_test[6] ... cidr_block: "10.6.0.0/16" tags.%: "2" tags.List1: "Blue" tags.List2: "Circle" + aws_vpc.aws_vpc_test[7] ... cidr_block: "10.7.0.0/16" tags.%: "2" tags.List1: "Blue" tags.List2: "Rectangle" + aws_vpc.aws_vpc_test[8] ... cidr_block: "10.8.0.0/16" tags.%: "2" tags.List1: "Yellow" tags.List2: "Square" + aws_vpc.aws_vpc_test[9] ... cidr_block: "10.9.0.0/16" tags.%: "2" tags.List1: "Yellow" tags.List2: "Triangle" + aws_vpc.aws_vpc_test[10] ... cidr_block: "10.10.0.0/16" tags.%: "2" tags.List1: "Yellow" tags.List2: "Circle" + aws_vpc.aws_vpc_test[11] ... cidr_block: "10.11.0.0/16" tags.%: "2" tags.List1: "Yellow" tags.List2: "Rectangle" + aws_vpc.aws_vpc_test[12] ... cidr_block: "10.12.0.0/16" tags.%: "2" tags.List1: "Red" tags.List2: "Square" + aws_vpc.aws_vpc_test[13] ... cidr_block: "10.13.0.0/16" tags.%: "2" tags.List1: "Red" tags.List2: "Triangle" + aws_vpc.aws_vpc_test[14] ... cidr_block: "10.14.0.0/16" tags.%: "2" tags.List1: "Red" tags.List2: "Circle" + aws_vpc.aws_vpc_test[15] ... cidr_block: "10.15.0.0/16" tags.%: "2" tags.List1: "Red" tags.List2: "Rectangle" Plan: 16 to add, 0 to change, 0 to destroy.

4 comments
9 likes
Prev post: Becoming a Cloudiator, attaining all 5 AWS CertificationsNext post: Terraform AWS backend for remote state files with S3 and DynamoDB

Related posts

Comments

  • Chris

    December 6, 2019 at 2:56 am
    Reply

    Depending on your version of terraform (I use v0.12.x), this may need to use the 'floor' command to get it to work. List1 = var.list_1[floor(count.index […] Read MoreDepending on your version of terraform (I use v0.12.x), this may need to use the 'floor' command to get it to work. List1 = var.list_1[floor(count.index / length(var.list_2))] Read Less

  • Gajendra

    October 30, 2019 at 3:36 pm
    Reply

    Thanks for this article, it was really helpful.

  • Carin

    March 6, 2019 at 7:59 am
    Reply

    Hi there! Such a good article, thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *