Reputation: 327
I am trying to create a multi-cloud solution for building out security rules for EC2/GCE instances. The idea is that I only want to use a single .tfvars
file which works for both platforms.
Everything works, however, because of a discrepancy between AWS & GCP (AWS requires you to provide a port value of -1
and GCP requires that you don't provide a port when defining an ICMP rule), my solution doesn't entirely work. Here's a snippet of my .tfvars
:
rules = [
{
protocol = "tcp"
port = 22
cidrs = ["10.0.0.0/8"]
},
{
protocol = "icmp"
port = -1
cidrs = ["10.0.0.0/8"]
}
]
These are passed into variables.tf
:
variable "rules" {
type = list(object({
protocol = string
port = number
cidrs = list(string)
}))
}
Which are then accessed using dynamic blocks. Here's the example for GCP:
resource "google_compute_firewall" "this" {
name = "rule"
network = "network"
project = "project"
target_tags = "targets"
dynamic "allow" {
for_each = var.rules
content{
protocol = allow.value["protocol"]
ports = [allow.value["port"]]
}
}
}
So essentially, I either need to tell the GCP module to ignore allow.value["port"]
when it equals -1
, or I need to not define the port for ICMP in my .tfvars
file, and tell AWS to add -1
as a port number when allow.value["protocol"]
is equal to icmp
.
Any suggestions on how to achieve either of these would be greatly appreciated!
Upvotes: 1
Views: 816
Reputation: 56859
Terraform 0.12, as well as introducing dynamic
blocks, introduced null
which will omit sending the attribute to the provider.
This works nicely when you have something conditional and the provider isn't happy with say an empty string to mean that it's being omitted (a common trick pre 0.12).
So for you you could do this:
resource "google_compute_firewall" "this" {
name = "rule"
network = "network"
project = "project"
target_tags = "targets"
dynamic "allow" {
for_each = var.rules
content{
protocol = allow.value["protocol"]
ports = allow.value["port"] == -1 ? null : [allow.value["port"]]
}
}
}
Now if you set port
to -1
then it will omit the ports
attribute from the allow
block but otherwise it sets it to the value of the rules.port
.
Upvotes: 3