From 1fca1e5b92ba760a33652f39c2345f6aa1eaa9f7 Mon Sep 17 00:00:00 2001 From: MohanprasadKumar ST <67147891+stm29@users.noreply.github.com> Date: Thu, 15 Aug 2024 23:38:48 +0530 Subject: [PATCH] fix(elasticloadbalancingv2-targets): add AlbListenerTarget for NLBs, deprecate AlbTarget due to ALB listener race conditions (#17208) (#30396) ### Issue # (if applicable) Closes #17208 . ### Description of changes - This PR replaces `AlbTarget` with `AlbListenerTarget`, allowing us to automatically add a dependency between the provided ALB listener and the associated NLB target group. Without such a dependency stacks may fail to deploy if the listener is not created when the target group attempts to be created. - Also, As described - https://github.com/aws/aws-cdk/issues/17208#issuecomment-1681475590 , it will handle graceful deletion of resources. ### Description of how you validated changes - Added UnitTests - Ran integrationTests as below, ``` $ yarn integ aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js --update-on-failed ``` ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...efaultTestDeployAssert4E6713E1.assets.json | 19 + ...aultTestDeployAssert4E6713E1.template.json | 36 + .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 281 +++++ .../nlb-alb-listner-stack.assets.json | 19 + .../nlb-alb-listner-stack.template.json | 564 ++++++++++ .../tree.json | 984 ++++++++++++++++++ .../test/integ.alb-listner-target.ts | 36 + .../lib/alb-target.ts | 53 +- .../test/alb-target.test.ts | 31 + .../aws-elasticloadbalancingv2/README.md | 2 +- .../lib/alb/application-listener.ts | 6 + 13 files changed, 2038 insertions(+), 6 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/nlb-alb-listner-stack.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/nlb-alb-listner-stack.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json new file mode 100644 index 0000000000000..2af610f0d4a39 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "IntegDefaultTestDeployAssert4E6713E1.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/integ.json new file mode 100644 index 0000000000000..2c45ac2312a61 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "Integ/DefaultTest": { + "stacks": [ + "nlb-alb-listner-stack" + ], + "assertionStack": "Integ/DefaultTest/DeployAssert", + "assertionStackName": "IntegDefaultTestDeployAssert4E6713E1" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/manifest.json new file mode 100644 index 0000000000000..396335d45801d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/manifest.json @@ -0,0 +1,281 @@ +{ + "version": "36.0.0", + "artifacts": { + "nlb-alb-listner-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "nlb-alb-listner-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "nlb-alb-listner-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "nlb-alb-listner-stack.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/24394092400f6a02c210490a7acaf10236a1fa2c0101836651065d233e2d2c44.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "nlb-alb-listner-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "nlb-alb-listner-stack.assets" + ], + "metadata": { + "/nlb-alb-listner-stack/VPC/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCB9E5F0B4" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1SubnetB4246D30" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableFEE4B781" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableAssociation0B0896DC" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1DefaultRoute91CEF279" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1EIP6AD938E8" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1NATGatewayE0556630" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2Subnet74179F39" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTable6F1A15F1" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTableAssociation5A808732" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2DefaultRouteB7481BBA" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2EIP4947BC00" + } + ], + "/nlb-alb-listner-stack/VPC/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2NATGateway3C070193" + } + ], + "/nlb-alb-listner-stack/VPC/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ], + "/nlb-alb-listner-stack/VPC/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableBE8A6027" + } + ], + "/nlb-alb-listner-stack/VPC/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableAssociation347902D1" + } + ], + "/nlb-alb-listner-stack/VPC/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1DefaultRouteAE1D6490" + } + ], + "/nlb-alb-listner-stack/VPC/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "/nlb-alb-listner-stack/VPC/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTable0A19E10E" + } + ], + "/nlb-alb-listner-stack/VPC/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTableAssociation0C73D413" + } + ], + "/nlb-alb-listner-stack/VPC/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2DefaultRouteF4F5CFD2" + } + ], + "/nlb-alb-listner-stack/VPC/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCIGWB7E252D3" + } + ], + "/nlb-alb-listner-stack/VPC/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCVPCGW99B986DC" + } + ], + "/nlb-alb-listner-stack/ALB/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ALBAEE750D2" + } + ], + "/nlb-alb-listner-stack/ALB/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ALBSecurityGroup8B8624F8" + } + ], + "/nlb-alb-listner-stack/ALB/ALBListener/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ALBALBListenerDB80B4FD" + } + ], + "/nlb-alb-listner-stack/NLB/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "NLB55158F82" + } + ], + "/nlb-alb-listner-stack/NLB/Listener/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "NLBListener96C8170F" + } + ], + "/nlb-alb-listner-stack/NLB/Listener/TargetsGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "NLBListenerTargetsGroupB42DD77B" + } + ], + "/nlb-alb-listner-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/nlb-alb-listner-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "nlb-alb-listner-stack" + }, + "IntegDefaultTestDeployAssert4E6713E1.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IntegDefaultTestDeployAssert4E6713E1.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IntegDefaultTestDeployAssert4E6713E1": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IntegDefaultTestDeployAssert4E6713E1.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "IntegDefaultTestDeployAssert4E6713E1.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "IntegDefaultTestDeployAssert4E6713E1.assets" + ], + "metadata": { + "/Integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/Integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "Integ/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/nlb-alb-listner-stack.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/nlb-alb-listner-stack.assets.json new file mode 100644 index 0000000000000..ea7fdc5da45ba --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/nlb-alb-listner-stack.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "24394092400f6a02c210490a7acaf10236a1fa2c0101836651065d233e2d2c44": { + "source": { + "path": "nlb-alb-listner-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "24394092400f6a02c210490a7acaf10236a1fa2c0101836651065d233e2d2c44.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/nlb-alb-listner-stack.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/nlb-alb-listner-stack.template.json new file mode 100644 index 0000000000000..f68b564ec2c22 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/nlb-alb-listner-stack.template.json @@ -0,0 +1,564 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1RouteTableAssociation0B0896DC" + ] + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.64.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet2EIP4947BC00": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet2DefaultRouteB7481BBA", + "VPCPublicSubnet2RouteTableAssociation5A808732" + ] + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.192.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + }, + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "nlb-alb-listner-stack/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "ALBAEE750D2": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internal", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "ALBSecurityGroup8B8624F8", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "Type": "application" + } + }, + "ALBSecurityGroup8B8624F8": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Automatically created Security Group for ELB nlbalblistnerstackALBE6EE71F4", + "SecurityGroupEgress": [ + { + "CidrIp": "255.255.255.255/32", + "Description": "Disallow all traffic", + "FromPort": 252, + "IpProtocol": "icmp", + "ToPort": 86 + } + ], + "SecurityGroupIngress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow from anyone on port 80", + "FromPort": 80, + "IpProtocol": "tcp", + "ToPort": 80 + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "ALBALBListenerDB80B4FD": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "FixedResponseConfig": { + "StatusCode": "200" + }, + "Type": "fixed-response" + } + ], + "LoadBalancerArn": { + "Ref": "ALBAEE750D2" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "NLB55158F82": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internal", + "Subnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "Type": "network" + } + }, + "NLBListener96C8170F": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "NLBListenerTargetsGroupB42DD77B" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "NLB55158F82" + }, + "Port": 80, + "Protocol": "TCP" + } + }, + "NLBListenerTargetsGroupB42DD77B": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 80, + "Protocol": "TCP", + "TargetType": "alb", + "Targets": [ + { + "Id": { + "Ref": "ALBAEE750D2" + }, + "Port": 80 + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + }, + "DependsOn": [ + "ALBALBListenerDB80B4FD" + ] + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/tree.json new file mode 100644 index 0000000000000..e35c5c7661743 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.js.snapshot/tree.json @@ -0,0 +1,984 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "nlb-alb-listner-stack": { + "id": "nlb-alb-listner-stack", + "path": "nlb-alb-listner-stack", + "children": { + "VPC": { + "id": "VPC", + "path": "nlb-alb-listner-stack/VPC", + "children": { + "Resource": { + "id": "Resource", + "path": "nlb-alb-listner-stack/VPC/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.64.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "nlb-alb-listner-stack/VPC/PublicSubnet2/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.192.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "nlb-alb-listner-stack/VPC/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + }, + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "IGW": { + "id": "IGW", + "path": "nlb-alb-listner-stack/VPC/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "nlb-alb-listner-stack/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "nlb-alb-listner-stack/VPC/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "internetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.Vpc", + "version": "0.0.0" + } + }, + "ALB": { + "id": "ALB", + "path": "nlb-alb-listner-stack/ALB", + "children": { + "Resource": { + "id": "Resource", + "path": "nlb-alb-listner-stack/ALB/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "aws:cdk:cloudformation:props": { + "loadBalancerAttributes": [ + { + "key": "deletion_protection.enabled", + "value": "false" + } + ], + "scheme": "internal", + "securityGroups": [ + { + "Fn::GetAtt": [ + "ALBSecurityGroup8B8624F8", + "GroupId" + ] + } + ], + "subnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "type": "application" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer", + "version": "0.0.0" + } + }, + "SecurityGroup": { + "id": "SecurityGroup", + "path": "nlb-alb-listner-stack/ALB/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "nlb-alb-listner-stack/ALB/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "Automatically created Security Group for ELB nlbalblistnerstackALBE6EE71F4", + "securityGroupEgress": [ + { + "cidrIp": "255.255.255.255/32", + "description": "Disallow all traffic", + "ipProtocol": "icmp", + "fromPort": 252, + "toPort": 86 + } + ], + "securityGroupIngress": [ + { + "cidrIp": "0.0.0.0/0", + "ipProtocol": "tcp", + "fromPort": 80, + "toPort": 80, + "description": "Allow from anyone on port 80" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "ALBListener": { + "id": "ALBListener", + "path": "nlb-alb-listner-stack/ALB/ALBListener", + "children": { + "Resource": { + "id": "Resource", + "path": "nlb-alb-listner-stack/ALB/ALBListener/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener", + "aws:cdk:cloudformation:props": { + "defaultActions": [ + { + "type": "fixed-response", + "fixedResponseConfig": { + "statusCode": "200" + } + } + ], + "loadBalancerArn": { + "Ref": "ALBAEE750D2" + }, + "port": 80, + "protocol": "HTTP" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnListener", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationListener", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer", + "version": "0.0.0" + } + }, + "NLB": { + "id": "NLB", + "path": "nlb-alb-listner-stack/NLB", + "children": { + "Resource": { + "id": "Resource", + "path": "nlb-alb-listner-stack/NLB/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "aws:cdk:cloudformation:props": { + "loadBalancerAttributes": [ + { + "key": "deletion_protection.enabled", + "value": "false" + } + ], + "scheme": "internal", + "subnets": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "type": "network" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer", + "version": "0.0.0" + } + }, + "Listener": { + "id": "Listener", + "path": "nlb-alb-listner-stack/NLB/Listener", + "children": { + "Resource": { + "id": "Resource", + "path": "nlb-alb-listner-stack/NLB/Listener/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener", + "aws:cdk:cloudformation:props": { + "defaultActions": [ + { + "type": "forward", + "targetGroupArn": { + "Ref": "NLBListenerTargetsGroupB42DD77B" + } + } + ], + "loadBalancerArn": { + "Ref": "NLB55158F82" + }, + "port": 80, + "protocol": "TCP" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnListener", + "version": "0.0.0" + } + }, + "TargetsGroup": { + "id": "TargetsGroup", + "path": "nlb-alb-listner-stack/NLB/Listener/TargetsGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "nlb-alb-listner-stack/NLB/Listener/TargetsGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "aws:cdk:cloudformation:props": { + "port": 80, + "protocol": "TCP", + "targets": [ + { + "id": { + "Ref": "ALBAEE750D2" + }, + "port": 80 + } + ], + "targetType": "alb", + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnTargetGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.NetworkTargetGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.NetworkListener", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.NetworkLoadBalancer", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "nlb-alb-listner-stack/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "nlb-alb-listner-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Integ": { + "id": "Integ", + "path": "Integ", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "Integ/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "Integ/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "Integ/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "Integ/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "Integ/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.ts new file mode 100644 index 0000000000000..8315ade0f3d1c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2-targets/test/integ.alb-listner-target.ts @@ -0,0 +1,36 @@ +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import * as cdk from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as targets from 'aws-cdk-lib/aws-elasticloadbalancingv2-targets'; + +// WHEN +const app = new cdk.App(); + +// GIVEN +class ALBListenerStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + const vpc = new ec2.Vpc(this, 'VPC', { restrictDefaultSecurityGroup: false }); + const alb = new elbv2.ApplicationLoadBalancer(this, 'ALB', { vpc }); + const albListener = alb.addListener('ALBListener', { + port: 80, + defaultAction: elbv2.ListenerAction.fixedResponse(200), + }); + const nlb = new elbv2.NetworkLoadBalancer(this, 'NLB', { vpc }); + const listener = nlb.addListener('Listener', { port: 80 }); + listener.addTargets('Targets', { + targets: [new targets.AlbListenerTarget(albListener)], + port: 80, + }); + } +} + +// EXPECT +const stack = new ALBListenerStack(app, 'nlb-alb-listner-stack'); +new IntegTest(app, 'Integ', { + testCases: [stack], +}); +app.synth(); diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2-targets/lib/alb-target.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2-targets/lib/alb-target.ts index ec658da181af6..ccb2aeb0c49aa 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2-targets/lib/alb-target.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2-targets/lib/alb-target.ts @@ -5,7 +5,8 @@ import * as elbv2 from '../../aws-elasticloadbalancingv2'; */ export class AlbArnTarget implements elbv2.INetworkLoadBalancerTarget { /** - * Create a new alb target + * Create a new alb target. + * Note that the ALB must have a listener on the provided target port. * * @param albArn The ARN of the application load balancer to load balance to * @param port The port on which the target is listening @@ -20,10 +21,13 @@ export class AlbArnTarget implements elbv2.INetworkLoadBalancerTarget { * load balancer. */ public attachToNetworkTargetGroup(targetGroup: elbv2.INetworkTargetGroup): elbv2.LoadBalancerTargetProps { - return this.attach(targetGroup); + return this._attach(targetGroup); } - private attach(_targetGroup: elbv2.ITargetGroup): elbv2.LoadBalancerTargetProps { + /** + * @internal + */ + protected _attach(_targetGroup: elbv2.ITargetGroup): elbv2.LoadBalancerTargetProps { return { targetType: elbv2.TargetType.ALB, targetJson: { id: this.albArn, port: this.port }, @@ -32,8 +36,13 @@ export class AlbArnTarget implements elbv2.INetworkLoadBalancerTarget { } /** - * A single Application Load Balancer as the target for load balancing. - */ + * A single Application Load Balancer as the target for load balancing. + * @deprecated Use `AlbListenerTarget` instead or + * `AlbArnTarget` for an imported load balancer. This target does not automatically + * add a dependency between the ALB listener and resulting NLB target group, + * without which may cause stack deployments to fail if the NLB target group is provisioned + * before the listener has been fully created. + */ export class AlbTarget extends AlbArnTarget { /** * @param alb The application load balancer to load balance to @@ -43,3 +52,37 @@ export class AlbTarget extends AlbArnTarget { super(alb.loadBalancerArn, port); } } + +/** + * A single Application Load Balancer's listener as the target for load balancing. + */ +export class AlbListenerTarget extends AlbArnTarget { + /** + * Create a new ALB target. + * The associated target group will automatically have a dependency added + * against the ALB's listener. + * + * @param albListener The application load balancer listener to target. + */ + constructor(private albListener: elbv2.ApplicationListener) { + super(albListener.loadBalancer.loadBalancerArn, albListener.port); + } + + private attach(targetGroup: elbv2.ITargetGroup): elbv2.LoadBalancerTargetProps { + targetGroup.node.addDependency(this.albListener); + return super._attach(targetGroup); + } + + /** + * Register this ALB target with a load balancer. + * + * Don't call this, it is called automatically when you add the target to a + * load balancer. + * + * This adds dependency on albListener because creation of ALB listener and NLB can vary during runtime. + * More Details on - https://github.com/aws/aws-cdk/issues/17208 + */ + public attachToNetworkTargetGroup(targetGroup: elbv2.INetworkTargetGroup): elbv2.LoadBalancerTargetProps { + return this.attach(targetGroup); + } +} diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2-targets/test/alb-target.test.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2-targets/test/alb-target.test.ts index c48812bcadc94..322a4e6f507b0 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2-targets/test/alb-target.test.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2-targets/test/alb-target.test.ts @@ -37,6 +37,37 @@ test('Can create target groups with alb target', () => { }); }); +test('AlbListener target creates a dependency on the NLB target group and ALB listener', () => { + // GIVEN + const stack = new Stack(); + const vpc = new ec2.Vpc(stack, 'Stack'); + const alb = new elbv2.ApplicationLoadBalancer(stack, 'ALB', { vpc }); + const albListener = alb.addListener('ALBListener', { + port: 80, + defaultAction: elbv2.ListenerAction.fixedResponse(200), + }); + const nlb = new elbv2.NetworkLoadBalancer(stack, 'NLB', { vpc }); + const listener = nlb.addListener('Listener', { port: 80 }); + + // WHEN + listener.addTargets('Targets', { + targets: [new targets.AlbListenerTarget(albListener)], + port: 80, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancingV2::TargetGroup', { + Port: 80, + Protocol: 'TCP', + Targets: [{ Id: { Ref: 'ALBAEE750D2' }, Port: 80 }], + TargetType: 'alb', + VpcId: { Ref: 'Stack8A423254' }, + }); + Template.fromStack(stack).hasResource('AWS::ElasticLoadBalancingV2::TargetGroup', { + DependsOn: ['ALBALBListenerDB80B4FD'], + }); +}); + test('Can create target groups with alb arn target', () => { // GIVEN const stack = new Stack(); diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md index 3fbbce053d021..a3052f5f18430 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/README.md @@ -553,7 +553,7 @@ const nlb = new elbv2.NetworkLoadBalancer(this, 'Nlb', { const listener = nlb.addListener('listener', { port: 80 }); listener.addTargets('Targets', { - targets: [new targets.AlbTarget(svc.loadBalancer, 80)], + targets: [new targets.AlbListenerTarget(svc.listener)], port: 80, }); diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener.ts index c4c75ea0c8fda..07cfb949f3b83 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/alb/application-listener.ts @@ -233,6 +233,11 @@ export class ApplicationListener extends BaseListener implements IApplicationLis */ public readonly loadBalancer: IApplicationLoadBalancer; + /** + * The port of the listener. + */ + public readonly port: number; + /** * ARNs of certificates added to this listener */ @@ -266,6 +271,7 @@ export class ApplicationListener extends BaseListener implements IApplicationLis this.loadBalancer = props.loadBalancer; this.protocol = protocol; + this.port = port; this.certificateArns = []; // Attach certificates