1
votes

I took reference from the below link and made someone modifications in the input cidr block

Nested For_each or count with dynamic for aws_security_group_rule in terraform

Port 22 should have CIDR as ["10.0.0.1/24"] Port 443 & 80 each should have CIDR as ["172.31.96.0/20","sg-09eadd831567d7dsb","172.31.160.0/20"]

ingress_ports_tcp = [[22], [443,80]]
ingress_cidr_tcp = [["172.31.32.0/20"],["172.31.96.0/20","sg-09eadd831567d7dsb","172.31.160.0/20"]]

Changes made: I added security group id as well in the ingress_cidr_tcp variable

 locals {
        my_rules = merge([
                for idx_port, ports in var.ingress_ports_tcp:
                       { for port in ports:
                            { for idx_cidr, cidrs in var.ingress_cidr_tcp[idx_port]:
                                    "${idx_port}-${port}-${idx_cidr}" => {
                                    "port" = port
                                    "cidrs" = length(regexall("[0-9].+\\..*",cidrs[idx_cidr])) > 0 ? cidrs[idx_cidr] : null
                                    "security_group_id" = length(regexall("sg-.*",cidrs[idx_cidr])) > 0 ? cidrs[idx_cidr] : null
                            }
                          }
                       }  
            ]...)
    }

I want the output like bellow

{
  "0-22-0" = {
    "cidrs" = [
      "172.31.32.0/20",
    ]
    "port" = 22
  }
  "1-443-0" = {
    "cidrs" = [
      "172.31.96.0/20",
    ]
    "port" = 443
  }
  "1-443-1" = {
    "security_group_id" = [
      "sg-09eadd831567d7dsb",
    ]
    "port" = 443
  }
  "1-443-2" = {
    "cidrs" = [
      "172.31.160.0/20",
    ]
    "port" = 443
  }
  "1-80-0" = {
    "cidrs" = [
      "172.31.96.0/20",
    ]
    "port" = 80
  }
  "1-80-1" = {
    "security_group_id" = [
      "sg-09eadd831567d7dsb",
    ]
    "port" = 80
  }
  "1-80-2" = {
    "cidrs" = [
      "172.31.160.0/20",
    ]
    "port" = 80
  }

Error :

Invalid 'for' expression\
Key expression is required when building an object.
1
It worked fine :) . But can you explain why it was not working in my code , what went wrong logic or syntax.Abhishek Solanki
After your for port in ports: you need something with the key, e.g. mykey => {your map}Marcin

1 Answers

3
votes

This is rather complex input data, so maybe it would be good idea to re-consider simplifying it. But anyway, you can achieve your outcome as follows. I split it first into my_rules_cidrs and my_rules_sgs, and then merge them into final my_rules:

variable "ingress_ports_tcp" {
    default = [[22], [443,80]]
}    

variable "ingress_cidr_tcp" {
    default = [["172.31.32.0/20"], 
               ["172.31.128.0/20", "sg-09eadd831567d7dsb", "172.31.160.0/20"]]
}

locals {

    my_rules_cidrs = merge(flatten([
    for idx_port, ports in var.ingress_ports_tcp:
        [ for port in ports:
            { for idx_cidr, cidr in var.ingress_cidr_tcp[idx_port]:
              "${idx_port}-${port}-${idx_cidr}" => {
                  "port" = port
                  "cidrs" = [cidr]
             } if length(regexall("[0-9].+\\..*",cidr)) > 0
          }
       ]  
    ])...)
    
    my_rules_sgs = merge(flatten([
    for idx_port, ports in var.ingress_ports_tcp:
        [ for port in ports:
            { for idx_cidr, cidr in var.ingress_cidr_tcp[idx_port]:
              "${idx_port}-${port}-${idx_cidr}" => {
                  "port" = port
                  "security_group_id" = [cidr]
             } if length(regexall("sg-.*",cidr)) > 0
          }
       ]  
    ])...)    
    
    my_rules = merge(local.my_rules_cidrs, local.my_rules_sgs)
}

Results in:

my_rules = {
  "0-22-0" = {
    "cidrs" = [
      "172.31.32.0/20",
    ]
    "port" = 22
  }
  "1-443-0" = {
    "cidrs" = [
      "172.31.128.0/20",
    ]
    "port" = 443
  }
  "1-443-1" = {
    "port" = 443
    "security_group_id" = [
      "sg-09eadd831567d7dsb",
    ]
  }
  "1-443-2" = {
    "cidrs" = [
      "172.31.160.0/20",
    ]
    "port" = 443
  }
  "1-80-0" = {
    "cidrs" = [
      "172.31.128.0/20",
    ]
    "port" = 80
  }
  "1-80-1" = {
    "port" = 80
    "security_group_id" = [
      "sg-09eadd831567d7dsb",
    ]
  }
  "1-80-2" = {
    "cidrs" = [
      "172.31.160.0/20",
    ]
    "port" = 80
  }
}