diff --git a/README.md b/README.md
index 55463138..0aed0639 100644
--- a/README.md
+++ b/README.md
@@ -162,7 +162,7 @@ You need the following permissions to run this module.
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.9.0 |
-| [ibm](#requirement\_ibm) | >= 1.78.4, < 2.0.0 |
+| [ibm](#requirement\_ibm) | >= 1.87.3, < 2.0.0 |
| [time](#requirement\_time) | >= 0.9.1, < 1.0.0 |
### Modules
diff --git a/security_group.tf b/security_group.tf
index 190948a4..21426bc5 100644
--- a/security_group.tf
+++ b/security_group.tf
@@ -64,138 +64,61 @@ locals {
}
}
-resource "ibm_is_security_group_rule" "security_group_rules" {
- for_each = local.security_group_rules
- group = ibm_is_security_group.security_group[each.value.sg_name].id
- direction = each.value.direction
- remote = each.value.source
- local = each.value.local
- ip_version = each.value.ip_version
-
-
- ##############################################################################
- # Dynamically create ICMP Block
- ##############################################################################
-
- dynamic "icmp" {
-
- # Runs a for each loop, if the rule block contains icmp, it looks through the block
- # Otherwise the list will be empty
-
- for_each = (
- # Only allow creation of icmp rules if all of the keys are not null.
- # This allows the use of the optional variable in landing zone patterns
- # to convert to a single typed list by adding `null` as the value.
- each.value.icmp == null
- ? []
- : length([
- for value in ["type", "code"] :
- true if lookup(each.value["icmp"], value, null) == null
- ]) == 2
- ? [] # if all values null empty array
- : [each.value]
+locals {
+ # True when tcp block has at least one non-null port value
+ sg_rule_has_tcp = {
+ for k, v in local.security_group_rules : k => (
+ v.tcp != null &&
+ length([for x in ["port_min", "port_max"] : true if lookup(v["tcp"], x, null) != null]) > 0
)
- # Conditionally add content if sg has icmp
- content {
- type = lookup(
- each.value["icmp"],
- "type",
- null
- )
- code = lookup(
- each.value["icmp"],
- "code",
- null
- )
- }
}
- ##############################################################################
-
- ##############################################################################
- # Dynamically create TCP Block
- ##############################################################################
-
- dynamic "tcp" {
-
- # Runs a for each loop, if the rule block contains tcp, it looks through the block
- # Otherwise the list will be empty
-
- for_each = (
- # Only allow creation of tcp rules if all of the keys are not null.
- # This allows the use of the optional variable in landing zone patterns
- # to convert to a single typed list by adding `null` as the value.
- # the default behavior will be to set `null` `port_min` values to 1 if null
- # and `port_max` to 65535 if null
- each.value.tcp == null
- ? []
- : length([
- for value in ["port_min", "port_max"] :
- true if lookup(each.value["tcp"], value, null) == null
- ]) == 2
- ? [] # if all values null empty array
- : [each.value]
+ # True when udp block has at least one non-null port value
+ sg_rule_has_udp = {
+ for k, v in local.security_group_rules : k => (
+ v.udp != null &&
+ length([for x in ["port_min", "port_max"] : true if lookup(v["udp"], x, null) != null]) > 0
)
-
- # Conditionally adds content if sg has tcp
- content {
- port_min = lookup(
- each.value["tcp"],
- "port_min",
- null
- )
-
- port_max = lookup(
- each.value["tcp"],
- "port_max",
- null
- )
- }
}
- ##############################################################################
-
- ##############################################################################
- # Dynamically create UDP Block
- ##############################################################################
-
- dynamic "udp" {
-
- # Runs a for each loop, if the rule block contains udp, it looks through the block
- # Otherwise the list will be empty
-
- for_each = (
- # Only allow creation of udp rules if all of the keys are not null.
- # This allows the use of the optional variable in landing zone patterns
- # to convert to a single typed list by adding `null` as the value.
- # the default behavior will be to set `null` `port_min` values to 1 if null
- # and `port_max` to 65535 if null
- each.value.udp == null
- ? []
- : length([
- for value in ["port_min", "port_max"] :
- true if lookup(each.value["udp"], value, null) == null
- ]) == 2
- ? [] # if all values null empty array
- : [each.value]
+ # True when icmp block has at least one non-null type/code value
+ sg_rule_has_icmp = {
+ for k, v in local.security_group_rules : k => (
+ v.icmp != null &&
+ length([for x in ["type", "code"] : true if lookup(v["icmp"], x, null) != null]) > 0
)
-
- # Conditionally adds content if sg has udp
- content {
- port_min = lookup(
- each.value["udp"],
- "port_min",
- null
- )
- port_max = lookup(
- each.value["udp"],
- "port_max",
- null
- )
- }
}
+}
+
+resource "ibm_is_security_group_rule" "security_group_rules" {
+ for_each = local.security_group_rules
+ group = ibm_is_security_group.security_group[each.value.sg_name].id
+ direction = each.value.direction
+ remote = each.value.source
+ local = each.value.local
+ ip_version = each.value.ip_version
- ##############################################################################
+ protocol = (
+ local.sg_rule_has_tcp[each.key] ? "tcp" :
+ local.sg_rule_has_udp[each.key] ? "udp" :
+ local.sg_rule_has_icmp[each.key] ? "icmp" :
+ null
+ )
+
+ port_min = (
+ local.sg_rule_has_tcp[each.key] ? lookup(each.value["tcp"], "port_min", null) :
+ local.sg_rule_has_udp[each.key] ? lookup(each.value["udp"], "port_min", null) :
+ null
+ )
+
+ port_max = (
+ local.sg_rule_has_tcp[each.key] ? lookup(each.value["tcp"], "port_max", null) :
+ local.sg_rule_has_udp[each.key] ? lookup(each.value["udp"], "port_max", null) :
+ null
+ )
+
+ type = local.sg_rule_has_icmp[each.key] ? lookup(each.value["icmp"], "type", null) : null
+ code = local.sg_rule_has_icmp[each.key] ? lookup(each.value["icmp"], "code", null) : null
}
diff --git a/version.tf b/version.tf
index ed675b17..30c01227 100644
--- a/version.tf
+++ b/version.tf
@@ -4,7 +4,7 @@ terraform {
# Use "greater than or equal to" range in modules
ibm = {
source = "IBM-Cloud/ibm"
- version = ">= 1.78.4, < 2.0.0"
+ version = ">= 1.87.3, < 2.0.0"
}
time = {
source = "hashicorp/time"