diff --git a/docs/syntax/compose_x/elbv2.rst b/docs/syntax/compose_x/elbv2.rst index eb998492..d3b3fec4 100644 --- a/docs/syntax/compose_x/elbv2.rst +++ b/docs/syntax/compose_x/elbv2.rst @@ -457,6 +457,22 @@ into a map/dict structure and compose-x will automatically convert it to the CFN `Target Group Attributes`_ +Settings +============ + +NoAllocateEips +---------------- + +By default, when using a public NLB, ECS Compose-X will create Elastic IP (EIPs) allocations. +Given this is no longer a requirement on NLBs, this boolean allows to disable this behaviour and let AWS assign +IP addresses to your NLB. + +RetainEips +------------ + +If set to true, when provisioning the EIPs, the DeletionPolicy will be set to ``Retain`` allowing you to preserve these +IP addresses should you want to re-use them later. + Examples ======== diff --git a/ecs_composex/elbv2/elbv2_stack/elbv2.py b/ecs_composex/elbv2/elbv2_stack/elbv2.py index 7b5cf294..cb6f719f 100644 --- a/ecs_composex/elbv2/elbv2_stack/elbv2.py +++ b/ecs_composex/elbv2/elbv2_stack/elbv2.py @@ -70,6 +70,8 @@ def __init__( self.listeners: list[ComposeListener] = [] self.target_groups: list[MergedTargetGroup] = [] super().__init__(name, definition, module, settings) + self.no_allocate_eips: bool = keyisset("NoAllocateEips", self.settings) + self.retain_eips: bool = keyisset("RetainEips", self.settings) self.validate_services() self.sort_props() self.module_name = MOD_KEY @@ -302,6 +304,7 @@ def set_eips(self, vpc_stack): EIP( f"{self.logical_name}Eip{public_subnet.title}", Domain="vpc", + DeletionPolicy="Retain" if self.retain_eips else "Delete", ) ) elif vpc_stack.vpc_resource.mappings: @@ -311,6 +314,7 @@ def set_eips(self, vpc_stack): EIP( f"{self.logical_name}Eip{public_az.title().split('-')[-1]}", Domain="vpc", + DeletionPolicy="Retain" if self.retain_eips else "Delete", ) ) @@ -334,7 +338,7 @@ def set_subnets(self, vpc_stack): "When Compose-X creates the VPC, the only subnets you can define to use are", [PUBLIC_SUBNETS.title, APP_SUBNETS.title], ) - if self.is_nlb() and self.lb_is_public: + if self.is_nlb() and self.lb_is_public and not self.no_allocate_eips: return Ref(AWS_NO_VALUE) if ( self.subnets_override @@ -354,7 +358,7 @@ def set_subnet_mappings(self, vpc_stack): """ if self.is_alb(): return Ref(AWS_NO_VALUE) - if not self.lb_eips and self.lb_is_public: + if not self.lb_eips and self.lb_is_public and not self.no_allocate_eips: self.set_eips(vpc_stack) mappings = [] subnets = self.define_override_subnets(PUBLIC_SUBNETS.title, vpc_stack) @@ -366,7 +370,7 @@ def set_subnet_mappings(self, vpc_stack): ) ) return mappings - elif not self.lb_is_public: + elif not self.lb_is_public or (self.lb_is_public and self.no_allocate_eips): self.cfn_resource.Subnets = self.set_subnets(vpc_stack) return Ref(AWS_NO_VALUE) @@ -503,4 +507,9 @@ def update_from_vpc(self, vpc_stack, settings=None): if self.is_alb(): self.cfn_resource.Subnets = self.set_subnets(vpc_stack) elif self.is_nlb(): - self.cfn_resource.SubnetMappings = self.set_subnet_mappings(vpc_stack) + if self.no_allocate_eips: + self.cfn_resource.Subnets = self.set_subnets(vpc_stack) + else: + self.cfn_resource.SubnetMappings = self.set_subnet_mappings( + vpc_stack + ) diff --git a/ecs_composex/elbv2/x-elbv2.spec.json b/ecs_composex/elbv2/x-elbv2.spec.json index 597c7a6f..8f0b95f3 100644 --- a/ecs_composex/elbv2/x-elbv2.spec.json +++ b/ecs_composex/elbv2/x-elbv2.spec.json @@ -126,7 +126,16 @@ "type": "object", "properties": { "Subnets": { - "type": "string" + "type": "string", + "description": "Name of the Subnets as defined in x-vpc to use" + }, + "NoAllocateEips": { + "type": "boolean", + "description": "Disables creating new EIPs for Network Load Balancers (NLB)" + }, + "RetainEips": { + "type": "boolean", + "description": "Retains provisioned EIPs" } } },