Skip to content

Commit dd09227

Browse files
committed
feat: Add support for creating security group for ECS Managed Instances
1 parent f3ae9c7 commit dd09227

File tree

3 files changed

+164
-6
lines changed

3 files changed

+164
-6
lines changed

modules/cluster/main.tf

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ resource "aws_ecs_cluster_capacity_providers" "this" {
145145
################################################################################
146146

147147
locals {
148+
managed_instances_enabled = anytrue([for k, v in local.capacity_providers : v.managed_instances_provider != null])
149+
148150
# TODO - embed the `autoscaling_capacity_providers` into a shape acceptable for
149151
# `var.capacity_providers` so that it can be merged with the new `capacity_providers`
150152
# for backward compatibility. Remove `autoscaling_capacity_providers` in the next major version.
@@ -322,7 +324,7 @@ resource "aws_ecs_capacity_provider" "this" {
322324
for_each = instance_launch_template.value.network_configuration != null ? [instance_launch_template.value.network_configuration] : []
323325

324326
content {
325-
security_groups = network_configuration.value.security_groups
327+
security_groups = local.create_security_group ? flatten(concat(aws_security_group.this[*].id, network_configuration.value.security_groups)) : network_configuration.value.security_groups
326328
subnets = network_configuration.value.subnets
327329
}
328330
}
@@ -510,8 +512,8 @@ resource "aws_iam_role_policy_attachment" "task_exec" {
510512
############################################################################################
511513

512514
locals {
513-
needs_infrastructure_iam_role = anytrue([for k, v in local.capacity_providers : v.managed_instances_provider != null])
514-
create_infrastructure_iam_role = var.create && var.create_infrastructure_iam_role && local.needs_infrastructure_iam_role
515+
create_infrastructure_iam_role = var.create && var.create_infrastructure_iam_role && local.managed_instances_enabled
516+
515517
infrastructure_iam_role_name = coalesce(var.infrastructure_iam_role_name, "${var.name}-infra", "NotProvided")
516518
}
517519

@@ -560,7 +562,7 @@ resource "aws_iam_role_policy_attachment" "infrastructure_managed_instances" {
560562
################################################################################
561563

562564
locals {
563-
create_node_iam_instance_profile = var.create && var.create_node_iam_instance_profile
565+
create_node_iam_instance_profile = var.create && var.create_node_iam_instance_profile && local.managed_instances_enabled
564566

565567
node_iam_role_name = coalesce(var.node_iam_role_name, "${var.name}-node")
566568
}
@@ -739,3 +741,78 @@ resource "aws_iam_instance_profile" "this" {
739741
create_before_destroy = true
740742
}
741743
}
744+
745+
################################################################################
746+
# Security Group
747+
################################################################################
748+
749+
locals {
750+
create_security_group = var.create && var.create_security_group && local.managed_instances_enabled
751+
752+
security_group_name = coalesce(var.security_group_name, var.name, "NotProvided")
753+
}
754+
755+
resource "aws_security_group" "this" {
756+
count = local.create_security_group ? 1 : 0
757+
758+
region = var.region
759+
760+
name = var.security_group_use_name_prefix ? null : local.security_group_name
761+
name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null
762+
description = var.security_group_description
763+
vpc_id = var.vpc_id
764+
765+
tags = merge(
766+
var.tags,
767+
{ Name = local.security_group_name },
768+
var.security_group_tags
769+
)
770+
771+
lifecycle {
772+
create_before_destroy = true
773+
}
774+
}
775+
776+
resource "aws_vpc_security_group_ingress_rule" "this" {
777+
for_each = { for k, v in var.security_group_ingress_rules : k => v if var.security_group_ingress_rules != null && local.create_security_group }
778+
779+
region = var.region
780+
781+
cidr_ipv4 = each.value.cidr_ipv4
782+
cidr_ipv6 = each.value.cidr_ipv6
783+
description = each.value.description
784+
from_port = each.value.from_port
785+
ip_protocol = each.value.ip_protocol
786+
prefix_list_id = each.value.prefix_list_id
787+
referenced_security_group_id = each.value.referenced_security_group_id == "self" ? aws_security_group.this[0].id : each.value.referenced_security_group_id
788+
security_group_id = aws_security_group.this[0].id
789+
tags = merge(
790+
var.tags,
791+
var.security_group_tags,
792+
{ "Name" = coalesce(each.value.name, "${local.security_group_name}-${each.key}") },
793+
each.value.tags
794+
)
795+
to_port = try(coalesce(each.value.to_port, each.value.from_port), null)
796+
}
797+
798+
resource "aws_vpc_security_group_egress_rule" "this" {
799+
for_each = { for k, v in var.security_group_egress_rules : k => v if var.security_group_egress_rules != null && local.create_security_group }
800+
801+
region = var.region
802+
803+
cidr_ipv4 = each.value.cidr_ipv4
804+
cidr_ipv6 = each.value.cidr_ipv6
805+
description = each.value.description
806+
from_port = try(coalesce(each.value.from_port, each.value.to_port), null)
807+
ip_protocol = each.value.ip_protocol
808+
prefix_list_id = each.value.prefix_list_id
809+
referenced_security_group_id = each.value.referenced_security_group_id == "self" ? aws_security_group.this[0].id : each.value.referenced_security_group_id
810+
security_group_id = aws_security_group.this[0].id
811+
tags = merge(
812+
var.tags,
813+
var.security_group_tags,
814+
{ "Name" = coalesce(each.value.name, "${local.security_group_name}-${each.key}") },
815+
each.value.tags
816+
)
817+
to_port = each.value.to_port
818+
}

modules/cluster/variables.tf

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ variable "capacity_providers" {
214214
}))
215215
monitoring = optional(string)
216216
network_configuration = optional(object({
217-
security_groups = optional(list(string))
217+
security_groups = optional(list(string), [])
218218
subnets = list(string)
219219
}))
220220
storage_configuration = optional(object({
@@ -484,3 +484,84 @@ variable "node_iam_role_statements" {
484484
}))
485485
default = null
486486
}
487+
488+
################################################################################
489+
# Security Group
490+
################################################################################
491+
492+
variable "create_security_group" {
493+
description = "Determines if a security group is created"
494+
type = bool
495+
default = true
496+
nullable = false
497+
}
498+
499+
variable "vpc_id" {
500+
description = "The ID of the VPC where the security group will be created"
501+
type = string
502+
default = null
503+
}
504+
505+
variable "security_group_name" {
506+
description = "Name to use on security group created"
507+
type = string
508+
default = null
509+
}
510+
511+
variable "security_group_use_name_prefix" {
512+
description = "Determines whether the security group name (`security_group_name`) is used as a prefix"
513+
type = bool
514+
default = true
515+
nullable = false
516+
}
517+
518+
variable "security_group_description" {
519+
description = "Description of the security group created"
520+
type = string
521+
default = null
522+
}
523+
524+
variable "security_group_ingress_rules" {
525+
description = "Security group ingress rules to add to the security group created"
526+
type = map(object({
527+
name = optional(string)
528+
529+
cidr_ipv4 = optional(string)
530+
cidr_ipv6 = optional(string)
531+
description = optional(string)
532+
from_port = optional(string)
533+
ip_protocol = optional(string, "tcp")
534+
prefix_list_id = optional(string)
535+
referenced_security_group_id = optional(string)
536+
tags = optional(map(string), {})
537+
to_port = optional(string)
538+
}))
539+
default = {}
540+
nullable = false
541+
}
542+
543+
variable "security_group_egress_rules" {
544+
description = "Security group egress rules to add to the security group created"
545+
type = map(object({
546+
name = optional(string)
547+
548+
cidr_ipv4 = optional(string)
549+
cidr_ipv6 = optional(string)
550+
description = optional(string)
551+
from_port = optional(string)
552+
ip_protocol = optional(string, "tcp")
553+
prefix_list_id = optional(string)
554+
referenced_security_group_id = optional(string)
555+
tags = optional(map(string), {})
556+
to_port = optional(string)
557+
}))
558+
default = {}
559+
nullable = false
560+
}
561+
562+
variable "security_group_tags" {
563+
description = "A map of additional tags to add to the security group created"
564+
type = map(string)
565+
default = {}
566+
nullable = false
567+
}

variables.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ variable "capacity_providers" {
219219
}))
220220
monitoring = optional(string)
221221
network_configuration = optional(object({
222-
security_groups = optional(list(string))
222+
security_groups = optional(list(string), [])
223223
subnets = list(string)
224224
}))
225225
storage_configuration = optional(object({

0 commit comments

Comments
 (0)