JPNagarajan
JPNagarajan

Reputation: 938

How to iterate through list of maps in terraform while creating locals?

I have a variable like below

subnets = [
{      
      app_name = "app1" 
      subnets = {
       "us-west-1a" = ["10.85.1.128/26", "10.85.1.192/26", "10.85.2.128/26", "10.85.2.192/26", "10.85.3.64/26", "10.85.3.128/26", "10.85.3.192/26", "10.85.4.0/26", "10.85.4.64/26", "10.85.4.128/26", "10.85.4.192/26", "10.85.5.0/26", "10.85.5.64/26", "10.85.5.128/26", "10.85.6.64/26", "10.85.6.128/26", "10.85.6.192/26"]
       "us-west-1b" = ["10.85.1.128/26", "10.85.1.192/26", "10.85.2.128/26", "10.85.2.192/26", "10.85.3.64/26", "10.85.3.128/26", "10.85.3.192/26", "10.85.4.0/26", "10.85.4.64/26", "10.85.4.128/26", "10.85.4.192/26", "10.85.5.0/26", "10.85.5.64/26", "10.85.5.128/26", "10.85.6.64/26", "10.85.6.128/26", "10.85.6.192/26"]
       "us-west-1c" = ["10.85.1.128/26", "10.85.1.192/26", "10.85.2.128/26", "10.85.2.192/26", "10.85.3.64/26", "10.85.3.128/26", "10.85.3.192/26", "10.85.4.0/26", "10.85.4.64/26", "10.85.4.128/26", "10.85.4.192/26", "10.85.5.0/26", "10.85.5.64/26", "10.85.5.128/26", "10.85.6.64/26", "10.85.6.128/26", "10.85.6.192/26"]
      }
},

     {
      app_name = "app2"
      subnets = {
       "us-west-1a" = ["10.85.1.128/26", "10.85.1.192/26", "10.85.2.128/26", "10.85.2.192/26", "10.85.3.64/26", "10.85.3.128/26", "10.85.3.192/26", "10.85.4.0/26", "10.85.4.64/26", "10.85.4.128/26", "10.85.4.192/26", "10.85.5.0/26", "10.85.5.64/26", "10.85.5.128/26", "10.85.6.64/26", "10.85.6.128/26", "10.85.6.192/26"]
       "us-west-1b" = ["10.86.1.128/26", "10.86.1.192/26", "10.86.2.128/26", "10.86.2.192/26", "10.86.3.64/26", "10.86.3.128/26", "10.86.3.192/26", "10.86.4.0/26", "10.86.4.64/26", "10.86.4.128/26", "10.86.4.192/26", "10.86.5.0/26", "10.86.5.64/26", "10.86.5.128/26", "10.86.6.64/26", "10.86.6.128/26", "10.86.6.192/26"]
      }
    }
  ]

I want to create a local which should give value as below

{app_name = app1
 cidr_block = "10.85.1.128/26"
 az = us-west-1a}
{app_name = app1
 cidr_block = "10.85.1.192/26"
 az = us-west-1a}
.............
{app_name = app2
 cidr_block = "10.85.1.128/26"
 az = us-west-1a}
{app_name = app2
     cidr_block = "10.86.1.128/26"
     az = us-west-1b}

I tried like below.But i'm not able to split the list and do 1 more iteration

locals {
int_subnets = toset(flatten([
for app in var.subnets: [
 for az,cidr in app.subnets : {
 app_name = app.app_name
 cidr_block = cidr
 az = az
 }
 ]]))

resource "aws_subnet" "example" {
  for_each = {
    for s in local.int_subnets : "${s.app_name} ${s.cidr_block}" => s
  }

  vpc_id            = var.vpc_id
  cidr_block        = each.value.cidr_block
  availability_zone = each.value.az

  tags = {
    Name = "${each.value.app_name}-Int-${split("-", each.value.az)[2]}"
  }
}
     }

Getting below error

on main.tf line 49, in resource "aws_subnet" "example":
│   49:     for s in local.int_subnets : "${s.app_name} ${s.cidr_block}" => s
│     ├────────────────
│     │ s.cidr_block is tuple with 17 elements
│ 
│ Cannot include the given value in a string template: string required.

Please let me know is it possible to do 1 more iteration and split the cidr block list into string or do we have any other better approch for the same

Upvotes: 0

Views: 869

Answers (1)

Ervin Szilagyi
Ervin Szilagyi

Reputation: 16805

I believe you may want to have something like this:

locals {
  int_subnets = toset(flatten([
    for app in var.subnets : [
      for az in keys(app.subnets) : [
        for subnet in flatten(app.subnets[az]) : [
          { "app_name" : app.app_name,
            "az" : az,
            "cidr_block " : subnet
          }
        ]
      ]
    ]
  ]))
}

This will produce an output in this format:

int_subnet = ([
  {
    "app_name" = "app1"
    "az" = "us-west-1a"
    "cidr_block " = "10.85.1.128/26"
  },
  {
    "app_name" = "app1"
    "az" = "us-west-1a"
    "cidr_block " = "10.85.1.192/26"
  },
...
  {
    "app_name" = "app2"
    "az" = "us-west-1a"
    "cidr_block " = "10.85.1.128/26"
  },
  {
    "app_name" = "app2"
    "az" = "us-west-1a"
    "cidr_block " = "10.85.1.192/26"
  },
...

Upvotes: 2

Related Questions