Skip to content

Commit 7550e95

Browse files
committed
fix: Move all EFA logic to the nodegroup itself
1 parent 30bf0cc commit 7550e95

File tree

13 files changed

+543
-44
lines changed

13 files changed

+543
-44
lines changed

README.md

Lines changed: 4 additions & 5 deletions
Large diffs are not rendered by default.

modules/eks-managed-node-group/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,16 @@ module "eks_managed_node_group" {
8989
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
9090
| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource |
9191
| [aws_placement_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/placement_group) | resource |
92+
| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
93+
| [aws_vpc_security_group_egress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource |
94+
| [aws_vpc_security_group_ingress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
9295
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
9396
| [aws_ec2_instance_type.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_instance_type) | data source |
9497
| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
9598
| [aws_iam_policy_document.role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
9699
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
97100
| [aws_ssm_parameter.ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source |
101+
| [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source |
98102

99103
## Inputs
100104

@@ -122,6 +126,7 @@ module "eks_managed_node_group" {
122126
| <a name="input_create_iam_role_policy"></a> [create\_iam\_role\_policy](#input\_create\_iam\_role\_policy) | Determines whether an IAM role policy is created or not | `bool` | `true` | no |
123127
| <a name="input_create_launch_template"></a> [create\_launch\_template](#input\_create\_launch\_template) | Determines whether to create a launch template or not. If set to `false`, EKS will use its own default launch template | `bool` | `true` | no |
124128
| <a name="input_create_placement_group"></a> [create\_placement\_group](#input\_create\_placement\_group) | Determines whether a placement group is created & used by the node group | `bool` | `false` | no |
129+
| <a name="input_create_security_group"></a> [create\_security\_group](#input\_create\_security\_group) | Determines if a security group is created | `bool` | `true` | no |
125130
| <a name="input_credit_specification"></a> [credit\_specification](#input\_credit\_specification) | Customize the credit specification of the instance | <pre>object({<br/> cpu_credits = optional(string)<br/> })</pre> | `null` | no |
126131
| <a name="input_desired_size"></a> [desired\_size](#input\_desired\_size) | Desired number of instances/nodes | `number` | `1` | no |
127132
| <a name="input_disable_api_termination"></a> [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 instance termination protection | `bool` | `null` | no |
@@ -172,6 +177,12 @@ module "eks_managed_node_group" {
172177
| <a name="input_private_dns_name_options"></a> [private\_dns\_name\_options](#input\_private\_dns\_name\_options) | The options for the instance hostname. The default values are inherited from the subnet | <pre>object({<br/> enable_resource_name_dns_aaaa_record = optional(bool)<br/> enable_resource_name_dns_a_record = optional(bool)<br/> hostname_type = optional(string)<br/> })</pre> | `null` | no |
173178
| <a name="input_ram_disk_id"></a> [ram\_disk\_id](#input\_ram\_disk\_id) | The ID of the ram disk | `string` | `null` | no |
174179
| <a name="input_remote_access"></a> [remote\_access](#input\_remote\_access) | Configuration block with remote access settings. Only valid when `use_custom_launch_template` = `false` | <pre>object({<br/> ec2_ssh_key = optional(string)<br/> source_security_group_ids = optional(list(string))<br/> })</pre> | `null` | no |
180+
| <a name="input_security_group_description"></a> [security\_group\_description](#input\_security\_group\_description) | Description of the security group created | `string` | `null` | no |
181+
| <a name="input_security_group_egress_rules"></a> [security\_group\_egress\_rules](#input\_security\_group\_egress\_rules) | Security group egress rules to add to the security group created | <pre>map(object({<br/> name = optional(string)<br/><br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(string)<br/> ip_protocol = optional(string, "tcp")<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> self = optional(bool, false)<br/> tags = optional(map(string), {})<br/> to_port = optional(string)<br/> }))</pre> | `{}` | no |
182+
| <a name="input_security_group_ingress_rules"></a> [security\_group\_ingress\_rules](#input\_security\_group\_ingress\_rules) | Security group ingress rules to add to the security group created | <pre>map(object({<br/> name = optional(string)<br/><br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(string)<br/> ip_protocol = optional(string, "tcp")<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> self = optional(bool, false)<br/> tags = optional(map(string), {})<br/> to_port = optional(string)<br/> }))</pre> | `{}` | no |
183+
| <a name="input_security_group_name"></a> [security\_group\_name](#input\_security\_group\_name) | Name to use on security group created | `string` | `null` | no |
184+
| <a name="input_security_group_tags"></a> [security\_group\_tags](#input\_security\_group\_tags) | A map of additional tags to add to the security group created | `map(string)` | `{}` | no |
185+
| <a name="input_security_group_use_name_prefix"></a> [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`security_group_name`) is used as a prefix | `bool` | `true` | no |
175186
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | Identifiers of EC2 Subnets to associate with the EKS Node Group. These subnets must have the following resource tag: `kubernetes.io/cluster/CLUSTER_NAME` | `list(string)` | `null` | no |
176187
| <a name="input_tag_specifications"></a> [tag\_specifications](#input\_tag\_specifications) | The tags to apply to the resources during launch | `list(string)` | <pre>[<br/> "instance",<br/> "volume",<br/> "network-interface"<br/>]</pre> | no |
177188
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
@@ -203,4 +214,6 @@ module "eks_managed_node_group" {
203214
| <a name="output_node_group_resources"></a> [node\_group\_resources](#output\_node\_group\_resources) | List of objects containing information about underlying resources |
204215
| <a name="output_node_group_status"></a> [node\_group\_status](#output\_node\_group\_status) | Status of the EKS Node Group |
205216
| <a name="output_node_group_taints"></a> [node\_group\_taints](#output\_node\_group\_taints) | List of objects containing information about taints applied to the node group |
217+
| <a name="output_security_group_arn"></a> [security\_group\_arn](#output\_security\_group\_arn) | Amazon Resource Name (ARN) of the security group |
218+
| <a name="output_security_group_id"></a> [security\_group\_id](#output\_security\_group\_id) | ID of the security group |
206219
<!-- END_TF_DOCS -->

modules/eks-managed-node-group/main.tf

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ locals {
7272

7373
locals {
7474
launch_template_name = coalesce(var.launch_template_name, "${var.name}-eks-node-group")
75-
security_group_ids = compact(concat([var.cluster_primary_security_group_id], var.vpc_security_group_ids))
75+
security_group_ids = compact(concat([var.cluster_primary_security_group_id], var.vpc_security_group_ids, aws_security_group.this[*].id))
7676
}
7777

7878
resource "aws_launch_template" "this" {
@@ -656,3 +656,102 @@ resource "aws_placement_group" "this" {
656656

657657
tags = var.tags
658658
}
659+
660+
################################################################################
661+
# Security Group
662+
################################################################################
663+
664+
locals {
665+
create_security_group = var.create && var.create_security_group && length(merge(local.security_group_ingress_rules, local.security_group_egress_rules)) > 0
666+
security_group_name = coalesce(var.security_group_name, "${var.cluster_name}-${var.name}")
667+
668+
security_group_ingress_rules = merge({ for k, v in
669+
{
670+
all_self_efa = {
671+
description = "Node to node EFA"
672+
protocol = "-1"
673+
from_port = 0
674+
self = true
675+
}
676+
} : k => v if var.enable_efa_support
677+
},
678+
var.security_group_ingress_rules
679+
)
680+
security_group_egress_rules = merge({ for k, v in
681+
{
682+
all_self_efa = {
683+
description = "Node to node EFA"
684+
protocol = "-1"
685+
to_port = 0
686+
self = true
687+
}
688+
} : k => v if var.enable_efa_support
689+
},
690+
var.security_group_egress_rules
691+
)
692+
}
693+
694+
data "aws_subnet" "this" {
695+
count = local.create_security_group ? 1 : 0
696+
697+
id = element(var.subnet_ids, 0)
698+
}
699+
700+
resource "aws_security_group" "this" {
701+
count = local.create_security_group ? 1 : 0
702+
703+
name = var.security_group_use_name_prefix ? null : local.security_group_name
704+
name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null
705+
description = var.security_group_description
706+
vpc_id = data.aws_subnet.this[0].vpc_id
707+
708+
tags = merge(
709+
var.tags,
710+
{ "Name" = local.security_group_name },
711+
var.security_group_tags
712+
)
713+
714+
lifecycle {
715+
create_before_destroy = true
716+
}
717+
}
718+
719+
resource "aws_vpc_security_group_ingress_rule" "this" {
720+
for_each = { for k, v in local.security_group_ingress_rules : k => v if length(local.security_group_ingress_rules) > 0 && local.create_security_group }
721+
722+
cidr_ipv4 = each.value.cidr_ipv4
723+
cidr_ipv6 = each.value.cidr_ipv6
724+
description = each.value.description
725+
from_port = each.value.from_port
726+
ip_protocol = each.value.ip_protocol
727+
prefix_list_id = each.value.prefix_list_id
728+
referenced_security_group_id = each.value.self ? aws_security_group.this[0].id : each.value.referenced_security_group_id
729+
security_group_id = aws_security_group.this[0].id
730+
tags = merge(
731+
var.tags,
732+
var.security_group_tags,
733+
{ "Name" = coalesce(each.value.name, "${local.security_group_name}-${each.key}") },
734+
each.value.tags
735+
)
736+
to_port = try(coalesce(each.value.to_port, each.value.from_port), null)
737+
}
738+
739+
resource "aws_vpc_security_group_egress_rule" "this" {
740+
for_each = { for k, v in local.security_group_egress_rules : k => v if length(local.security_group_egress_rules) && local.create_security_group }
741+
742+
cidr_ipv4 = each.value.cidr_ipv4
743+
cidr_ipv6 = each.value.cidr_ipv6
744+
description = each.value.description
745+
from_port = try(coalesce(each.value.from_port, each.value.to_port), null)
746+
ip_protocol = each.value.ip_protocol
747+
prefix_list_id = each.value.prefix_list_id
748+
referenced_security_group_id = each.value.self ? aws_security_group.this[0].id : each.value.referenced_security_group_id
749+
security_group_id = aws_security_group.this[0].id
750+
tags = merge(
751+
var.tags,
752+
var.security_group_tags,
753+
{ "Name" = coalesce(each.value.name, "${local.security_group_name}-${each.key}") },
754+
each.value.tags
755+
)
756+
to_port = each.value.to_port
757+
}

modules/eks-managed-node-group/outputs.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,17 @@ output "iam_role_unique_id" {
7979
description = "Stable and unique string identifying the IAM role"
8080
value = try(aws_iam_role.this[0].unique_id, null)
8181
}
82+
83+
################################################################################
84+
# Security Group
85+
################################################################################
86+
87+
output "security_group_arn" {
88+
description = "Amazon Resource Name (ARN) of the security group"
89+
value = try(aws_security_group.this[0].arn, null)
90+
}
91+
92+
output "security_group_id" {
93+
description = "ID of the security group"
94+
value = try(aws_security_group.this[0].id, null)
95+
}

modules/eks-managed-node-group/variables.tf

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,3 +666,75 @@ variable "iam_role_policy_statements" {
666666
}))
667667
default = null
668668
}
669+
670+
################################################################################
671+
# Security Group
672+
################################################################################
673+
674+
variable "create_security_group" {
675+
description = "Determines if a security group is created"
676+
type = bool
677+
default = true
678+
}
679+
680+
variable "security_group_name" {
681+
description = "Name to use on security group created"
682+
type = string
683+
default = null
684+
}
685+
686+
variable "security_group_use_name_prefix" {
687+
description = "Determines whether the security group name (`security_group_name`) is used as a prefix"
688+
type = bool
689+
default = true
690+
}
691+
692+
variable "security_group_description" {
693+
description = "Description of the security group created"
694+
type = string
695+
default = null
696+
}
697+
698+
variable "security_group_ingress_rules" {
699+
description = "Security group ingress rules to add to the security group created"
700+
type = map(object({
701+
name = optional(string)
702+
703+
cidr_ipv4 = optional(string)
704+
cidr_ipv6 = optional(string)
705+
description = optional(string)
706+
from_port = optional(string)
707+
ip_protocol = optional(string, "tcp")
708+
prefix_list_id = optional(string)
709+
referenced_security_group_id = optional(string)
710+
self = optional(bool, false)
711+
tags = optional(map(string), {})
712+
to_port = optional(string)
713+
}))
714+
default = {}
715+
}
716+
717+
variable "security_group_egress_rules" {
718+
description = "Security group egress rules to add to the security group created"
719+
type = map(object({
720+
name = optional(string)
721+
722+
cidr_ipv4 = optional(string)
723+
cidr_ipv6 = optional(string)
724+
description = optional(string)
725+
from_port = optional(string)
726+
ip_protocol = optional(string, "tcp")
727+
prefix_list_id = optional(string)
728+
referenced_security_group_id = optional(string)
729+
self = optional(bool, false)
730+
tags = optional(map(string), {})
731+
to_port = optional(string)
732+
}))
733+
default = {}
734+
}
735+
736+
variable "security_group_tags" {
737+
description = "A map of additional tags to add to the security group created"
738+
type = map(string)
739+
default = {}
740+
}

0 commit comments

Comments
 (0)