NSX DFW Rules based on map file issue

Hi Discuss

Trying to pickup somebody else’s code which creates groups, services and firewall rules in NSX using the NSX provider plugin…

Example code below [minimized for readability].

Its failing on these lines which enumerate the multiple groups/services on a rule from map_policies:

destination_groups = [for x in rule.value[“destinations”] : try(var.nsxt_policy_grp_grp[x])]

which reads from (exert):

map_policies = {

James-Common = {

category = "Environment"

domain   = ""

rules = {

  James-Common-0001 = {

    display      = "James-Common-0001"

    *sources      = \["dogs"\]*

    *destinations = \["cats"\]*

    *services     = \["TCP8443"\]*

    action       = "ALLOW"

    scope        = \["LAB"\]

    disabled     = "false"

  }

My question really is how to reference the “x” in (I presume) the nsxt_policy_grp_grp or map_ipgrp/map_taggrp variables so the rule is added.

Fairly new to this, so thanks!

main.tf

resource “nsxt_policy_security_policy” “policies” {

for_each = var.map_policies

display_name = each.key

stateful = true

tcp_strict = true

category = each.value[“category”]

#scope = [for x in each.value[“scope”] : try(var.nsxt_policy_grp_grp)]

domain = each.value[“domain”]

# a nested for_each to loop through each rule within the policy, pulling in the details where needed from the remote state var maps

dynamic “rule” {

for_each = each.value\["rules"\]



content {

  display_name = rule.value\["display"\]

  #source_groups = \[for x in rule.value\["sources"\] : try(var.nsxt_policy_grp_grp\[x\])\]

  destination_groups = \[for x in rule.value\["destinations"\] : try(var.nsxt_policy_grp_grp\[x\])\]

  action             = rule.value\["action"\]

  #services = \[for x in rule.value\["services"\] : try(var.nsxt_policy_svc_svc\[x\])\]

  logged   = true

  disabled = rule.value\["disabled"\]

}

}

}

variables.tf

variable “map_services” {

type = map(any)

default = {

}

}

variable “map_taggrp” {

type = map(any)

default = {

}

}

variable “map_ipgrp” {

type = map(any)

default = {

}

}

variable “map_policies” {

type = map(any)

default = {

}

}

variable “nsxt_policy_grp_grp” {

type = map(any)

default = {

}

}

variable “nsxt_policy_svc_svc” {

type = map(any)

default = {

}

}

terraform.tfvars

map_services = {

“TCP8443” = { TCP = [“8443”, “80”, “443”] }

“SSH” = { TCP = [“22”], UDP = [“22”] }

}

## groups ##

nsxt_policy_grp_grp = {

AD_Servers = { grp_ips = [“10.1.2.1/32”, “10.1.2.2/32”], “domain” = “default” }

More_Servers = { grp_ips = [“10.2.3.1/32”, “10.2.3.2/32”, “10.2.3.3/32”], “domain” = “default” }

}

map_ipgrp = {

dogs = {

key         = "grp_ips"

description = "dogs group"

domain      = ""

IP          = \["10.1.1.1"\]

}

}

map_taggrp = {

cats = {

key         = "grp_tags"

description = "cats group"

domain      = ""

TAG         = \["crw", "ssp"\]

}

}

## DFW policies ##

map_policies = {

James-Common = {

category = "Environment"

domain   = ""

rules = {

  James-Common-0001 = {

    display      = "James-Common-0001"

    sources      = \["dogs"\]

    destinations = \["cats"\]

    services     = \["TCP8443"\]

    action       = "ALLOW"

    scope        = \["LAB"\]

    disabled     = "false"

  }

  James-Common-0002 = {

    display      = "James-Common-0002"

    sources      = \["cats"\]

    destinations = \["dogs"\]

    services     = \["TCP8443", "SSH"\]

    action       = "ALLOW"

    scope        = \["LAB"\]

    disabled     = "false"

  }

}

}

}

I get the following error(s):

PS D:\James> terraform plan
data.nsxt_policy_site.lmb: Reading…
data.nsxt_policy_site.lma: Reading…
data.nsxt_policy_site.lmb: Read complete after 0s [id=lmb]
data.nsxt_policy_site.lma: Read complete after 0s [id=lma]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:

  • create

Terraform planned the following actions, but then encountered a problem:

nsxt_policy_group.ipgrp[“dogs”] will be created

  • resource “nsxt_policy_group” “ipgrp” {

    • display_name = “dogs”

    • id = (known after apply)

    • nsx_id = (known after apply)

    • path = (known after apply)

    • revision = (known after apply)

      (1 unchanged attribute hidden)

    }

nsxt_policy_group.taggrp[“cats”] will be created

  • resource “nsxt_policy_group” “taggrp” {

    • display_name = “cats”

    • id = (known after apply)

    • nsx_id = (known after apply)

    • path = (known after apply)

    • revision = (known after apply)

      (1 unchanged attribute hidden)

    }

nsxt_policy_service.services[“dogs”] will be created

  • resource “nsxt_policy_service” “services” {
    • display_name = “dogs”
    • id = (known after apply)
    • nsx_id = (known after apply)
    • path = (known after apply)
    • revision = (known after apply)
      }

Plan: 3 to add, 0 to change, 0 to destroy.

│ Error: Incorrect attribute value type

│ on main.tf line 114, in resource “nsxt_policy_security_policy” “policies”:
│ 114: destination_groups = [for x in rule.value[“destinations”] : try(var.map_ipgrp)]
│ ├────────────────
│ │ var.map_ipgrp is map of object with 1 element

│ Inappropriate value for attribute “destination_groups”: element 0: string required, but have object.


│ Error: Error in function call

│ on main.tf line 114, in resource “nsxt_policy_security_policy” “policies”:
│ 114: destination_groups = [for x in rule.value[“destinations”] : try(var.map_ipgrp)]
│ ├────────────────
│ │ var.map_ipgrp is map of object with 1 element

│ Call to function “try” failed: no expression succeeded:
│ - Invalid index (at main.tf:114,84-87)
│ The given key does not identify an element in this collection value.

│ At least one expression must produce a successful result.

so as a sub question :- how would I go about combining the two maps map_ipgrp and map_taggrp, I suppose into nsxt_policy_grp_grp? They are both groups, one based on IP’s and one on tags.

ta.