CEamonn
CEamonn

Reputation: 925

Creating resources from locals.tf with variable inputs

I have a long list of ACL rules and am trying to generate an aws_network_acl by iterating over them. The rules are in a locals.tf file in my module to keep main.tf a bit tidier, and look like this

locals.tf

locals {
  webapp = [{
    "protocol"  = "tcp"
    "rule_no"   = 100
    "action"    = "allow"
    "from_port" = 22
    "to_port"   = 22
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 110
      "action"    = "allow"
      "from_port" = 60111
      "to_port"   = 60111
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 120
      "action"    = "allow"
      "from_port" = 3243
      "to_port"   = 3243
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 130
      "action"    = "allow"
      "from_port" = 6379
      "to_port"   = 6379
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 140
      "action"    = "allow"
      "from_port" = 50123
      "to_port"   = 50123
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 150
      "action"    = "allow"
      "from_port" = 50432
      "to_port"   = 50432
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 160
      "action"    = "allow"
      "from_port" = 3306
      "to_port"   = 3306
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 170
      "action"    = "allow"
      "from_port" = 50001
      "to_port"   = 50001
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 180
      "action"    = "allow"
      "from_port" = 50010
      "to_port"   = 50015
    },
    {
      "protocol"  = "tcp"
      "rule_no"   = 190
      "action"    = "allow"
      "from_port" = 50650
      "to_port"   = 50660
    }
  ]
}

(there are more but shortened for brevity.

In my module's main.tf I want to iterate over each, creating an ACL

resource "aws_network_acl" "webapp" {
  vpc_id = data.aws_vpc.posttrade-vpc.id

  for_each = {for idx, query in locals.posttrade: idx => query}
  egress = [
    protocol = each.value.protocol
    rule_no = each.value.rule_no
    action = "allow"
    from_port = each.value.from_port
    to_port = each.value.to_port
  ]
}

But get the error

Missing item separator: Expected a comma to mark the beginning of the next item.

Is it possible to do this from a locals file, or a variables map?

Upvotes: 0

Views: 647

Answers (1)

Juan Fontes
Juan Fontes

Reputation: 908

You are missing a dynamic block to create multiples egress. You just need to add the code:

resource "aws_network_acl" "webapp" {
  vpc_id = data.aws_vpc.posttrade-vpc.id
  dynamic "egress" {

    for_each = toset(local.webapp)

    content {
      protocol  = egress.value["protocol"]
      rule_no   = egress.value["rule_no"]
      action    = "allow"
      from_port = egress.value["from_port"]
      to_port   = egress.value["to_port"]
    }

  }
}

And it will result in:

Terraform will perform the following actions:

  # aws_network_acl.webapp will be created
  + resource "aws_network_acl" "webapp" {
      + arn        = (known after apply)
      + egress     = [
          + {
              + action          = "allow"
              + cidr_block      = ""
              + from_port       = 22
              + icmp_code       = null
              + icmp_type       = null
              + ipv6_cidr_block = ""
              + protocol        = "tcp"
              + rule_no         = 100
              + to_port         = 22
            },
          + {
              + action          = "allow"
              + cidr_block      = ""
              + from_port       = 3243
              + icmp_code       = null
              + icmp_type       = null
              + ipv6_cidr_block = ""
              + protocol        = "tcp"
              + rule_no         = 120
              + to_port         = 3243
            },
......

Upvotes: 1

Related Questions