Hey folks, i’ve been banging my head against the wall on this one, and not sure if it is possible.
We are spinning up EKS clusters, and would like to use managed node groups. However, the limitation of managed node groups is that you cannot provide the security group for each node group-- amazon creates one for you.
We are currently barred from using managed node groups because we need to control the ports on the node security groups, but then I thought of a hack I could try that might work (and it sort of does, just not to the extent I would like).
I have a null data source that waits for the node group to be created, then a data block that looks up the security group that amazon created by name, which allows us to provide it in an aws_security_group_rule
resource, therefore managing the SG.
Here is the request: I would like to be able to create security group rules for each rule defined within each node group configuration. Here is some example code that I have that is working:
node_groups = {
default = {
instance_type = "t3.medium"
disk_size = 20
}
node_group_2 = {
instance_type = "m4.large"
}
additional_nodegroup_sg_rules = {
k8s = {
node_group = "default"
description = "app database",
type = "ingress",
from_port = 5432
to_port = 5432
protocol = "tcp"
source_security_group_id = "sg-12345"
},
ssh = {
node_group = "node_group_2"
description = "SSH",
type = "ingress",
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.60.192.0/28"]
},
}
data "aws_security_group" "node_group_sg" {
for_each = var.node_groups
filter {
name = "tag:eks"
values = [aws_eks_node_group.node_group[each.key].node_group_name]
}
depends_on = [data.null_data_source.node_groups_sg]
}
resource "aws_security_group_rule" "managed_node_ssh_access" {
for_each = var.additional_nodegroup_sg_rules
security_group_id = data.aws_security_group.node_group_sg[lookup(each.value, "node_group", null)].id
description = lookup(each.value, "description", null)
type = lookup(each.value, "type", null)
from_port = lookup(each.value, "from_port", null)
to_port = lookup(each.value, "to_port", null)
protocol = lookup(each.value, "protocol", null)
cidr_blocks = lookup(each.value, "cidr_blocks", null)
source_security_group_id = lookup(each.value, "source_security_group_id", null)
}
The limitation here is that if the user has a single rule they wish to apply to ALL node groups, it has to be defined multiple times, once for each specific node group. I would like to be able to set the value of node_group
within additional_nodegroup_sg_rules
to "all"
and only have to define it once, but have it propagate down to all the node group sgs.
I have tried every manner I can come up with of manipulating the data to create values and a workflow that supports this, but I just don’t think it is possible.
I think the only way would be to somehow convert the data with a local so that:
additional_nodegroup_sg_rules = {
ssh = {
node_group = "all"
description = "SSH",
type = "ingress",
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.60.192.0/28"]
},
}
turns into a map that looks like:
global_nodegroup_sg_rules = {
ssh_default = {
node_group = "default"
description = "SSH",
type = "ingress",
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.60.192.0/28"]
},
ssh_node_group_2 = {
node_group = "node_group_2"
description = "SSH",
type = "ingress",
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.60.192.0/28"]
},
}
and then have an additional sg rule resource block that runs against local.global_nodegroup_sg_rules
Any ideas?
Thanks in advance!