Hi I’d love to get some help with creating security groups rules dynamically. I’ve simplified most of the logic so you can reproduce as well.
I have 3 files:
- main.tf
resource "aws_security_group_rule" "bp_service_sg_rule" {
for_each = { for index, rules in local.security_group_rules : index => rules }
type = "ingress"
from_port = each.value.open_port
to_port = each.value.open_port
protocol = "tcp"
security_group_id = "sg-0e5e36abc940a1a2a"
cidr_blocks = [each.value.to_group]
}
- variables.tf
locals {
security_groups_file = yamldecode(file("${path.module}/security_groups.yml"))
security_group_rules = flatten([
for service_name, rules in local.security_groups_file.groups : [
for rule in rules : {
service_name = service_name
open_port = rule.open_port
to_group = rule.to_group
}
]
])
}
- security_groups.yml
groups:
test:
- open_port: 22
to_group: 4.4.4.4/32
The simplified logic is:
I go over security_groups.yml file with a loop to add the rules I want for the specific security_group. Example:
test: <===== The name of the security group
- open_port: 22 <===== The port number that I want to open
to_group: 4.4.4.4/32 <===== The ip address I want to open it to.
If I want to add another rule to the list, like this:
test:
- open_port: 22 <====== The new
to_group: 3.3.3.3/32 <====== rule
- open_port: 22
to_group: 4.4.4.4/32
Instead of adding the rule, Terraform destroys it and recreates it, like this:
# aws_security_group_rule.bp_service_sg_rule["0"] must be replaced
-/+ resource "aws_security_group_rule" "bp_service_sg_rule" {
~ cidr_blocks = [ # forces replacement
- "4.4.4.4/32",
+ "3.3.3.3/32",
]
from_port = 22
~ id = "sgrule-3857769040" -> (known after apply)
- ipv6_cidr_blocks = [] -> null
- prefix_list_ids = [] -> null
protocol = "tcp"
security_group_id = "sg-0e5e36abc940a1a2a"
self = false
+ source_security_group_id = (known after apply)
to_port = 22
type = "ingress"
}
# aws_security_group_rule.bp_service_sg_rule["1"] will be created
+ resource "aws_security_group_rule" "bp_service_sg_rule" {
+ cidr_blocks = [
+ "4.4.4.4/32",
]
+ from_port = 22
+ id = (known after apply)
+ protocol = "tcp"
+ security_group_id = "sg-0e5e36abc940a1a2a"
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 22
+ type = "ingress"
}
The problem is: we keep a file with ALL security groups of our cluster, when we make one simple change to a specific security group, Terraform destroys ALL rules and recreates them and thats a NO GO since it shuts us down until it finishes.