It is indeed an array.
This is the terraform resource for L3 firewall rules.
resource "meraki_networks_appliance_firewall_l3_firewall_rules" "sb3_fw_l3" {
network_id = meraki_networks.sb3.id
rules = [{
comment = "Deny-RFC1918."
dest_cidr = "10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16"
dest_port = "any"
policy = "deny"
protocol = "any"
src_cidr = "any"
src_port = "any"
syslog_enabled = false
},
{
comment = "Allow-corp-outbound-to-internet."
dest_cidr = "any"
dest_port = "any"
policy = "allow"
protocol = "any"
src_cidr = var.subnet_prefix_corp
src_port = "any"
syslog_enabled = false
},
{
comment = "Allow-iot-outbound-to-internet."
dest_cidr = "any"
dest_port = "any"
policy = "allow"
protocol = "any"
src_cidr = var.subnet_prefix_iot
src_port = "any"
syslog_enabled = false
},
{
comment = "Allow-guest-outbound-to-internet."
dest_cidr = "any"
dest_port = "any"
policy = "allow"
protocol = "any"
src_cidr = var.subnet_prefix_guest
src_port = "any"
syslog_enabled = false
}
]
}
This is how it ends up in the Dashboard.

I deleted all rules above and pasted the same array into postman.
Postman body:
{
"rules": [
{
"policy": "deny",
"protocol": "any",
"srcCidr": "any",
"destCidr": "10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16",
"comment": "Deny-RFC1918.",
"srcPort": "any",
"destPort": "any",
"syslogEnabled": false
},
{
"policy": "allow",
"protocol": "any",
"srcCidr": "10.100.2.0/24",
"destCidr": "any",
"comment": "Allow-corp-outbound-to-internet.",
"srcPort": "any",
"destPort": "any",
"syslogEnabled": false
},
{
"policy": "allow",
"protocol": "any",
"srcCidr": "10.110.2.0/24",
"destCidr": "any",
"comment": "Allow-iot-outbound-to-internet.",
"srcPort": "any",
"destPort": "any",
"syslogEnabled": false
},
{
"policy": "allow",
"protocol": "any",
"srcCidr": "10.120.2.0/24",
"destCidr": "any",
"comment": "Allow-guest-outbound-to-internet.",
"srcPort": "any",
"destPort": "any",
"syslogEnabled": false
}
]
}
Postman response:
200 OK
"rules": [
{
"comment": "Deny-RFC1918.",
"policy": "deny",
"protocol": "any",
"srcPort": "Any",
"srcCidr": "Any",
"destPort": "Any",
"destCidr": "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16",
"syslogEnabled": false
},
{
"comment": "Allow-corp-outbound-to-internet.",
"policy": "allow",
"protocol": "any",
"srcPort": "Any",
"srcCidr": "10.100.2.0/24",
"destPort": "Any",
"destCidr": "Any",
"syslogEnabled": false
},
{
"comment": "Allow-iot-outbound-to-internet.",
"policy": "allow",
"protocol": "any",
"srcPort": "Any",
"srcCidr": "10.110.2.0/24",
"destPort": "Any",
"destCidr": "Any",
"syslogEnabled": false
},
{
"comment": "Allow-guest-outbound-to-internet.",
"policy": "allow",
"protocol": "any",
"srcPort": "Any",
"srcCidr": "10.120.2.0/24",
"destPort": "Any",
"destCidr": "Any",
"syslogEnabled": false
},
{
"comment": "Default rule",
"policy": "allow",
"protocol": "Any",
"srcPort": "Any",
"srcCidr": "Any",
"destPort": "Any",
"destCidr": "Any",
"syslogEnabled": false
}
]
}
Dashboard:

Everything is identical in the array. The only difference is how i populate the fields in terraform. I'm just pointing to some variables defined in variables.tf
Here they are:
variable "subnet_prefix_corp" {
type = string
default = "10.100.2.0/24"
}
variable "appliance_ip_corp" {
type = string
default = "10.100.2.1"
}
variable "subnet_prefix_iot" {
type = string
default = "10.110.2.0/24"
}
variable "appliance_ip_iot" {
type = string
default = "10.110.2.1"
}
variable "subnet_prefix_guest" {
type = string
default = "10.120.2.0/24"
}
variable "appliance_ip_guest" {
type = string
default = "10.120.2.1"
}
variable "subnet_prefix_mgmt" {
type = string
default = "10.130.2.0/24"
}
variable "appliance_ip_mgmt" {
type = string
default = "10.130.2.1"
}
It looks like Terraform is somehow re-ordering the array. But i'm not sure how or why 😕
MLL