From 00e8a7b877a732b4236227f6462bf3914ce7a214 Mon Sep 17 00:00:00 2001
From: Hirotaka Tagawa / wafuwafu13 <jaruwafu@gmail.com>
Date: Wed, 13 Mar 2024 01:40:58 +0000
Subject: [PATCH 1/4] feat(ecs-patterns): support `securityGroups` in
 `NetworkLoadBalancedFargateService` (#29431)

### Issue # (if applicable)

Closes #29430

(related to https://github.com/aws/aws-cdk/pull/29186#issuecomment-1959231406)

### Reason for this change


We can't specify `securityGroups` in `NetworkLoadBalancedFargateService` now.

### Description of changes


- Add `securityGroups` property to `NetworkLoadBalancedFargateServiceProps`.
- Add unit test
- Add integ test

### Description of how you validated changes


- Pass unit test
- Pass integ test

### 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*
---
 .../aws-ecs-integ-lb-fargate.assets.json      |   19 +
 .../aws-ecs-integ-lb-fargate.template.json    |  750 ++++++++++
 .../fargate/integ.nlb-sg.js.snapshot/cdk.out  |    1 +
 .../integ.nlb-sg.js.snapshot/integ.json       |   12 +
 ...efaultTestDeployAssert3391A20B.assets.json |   19 +
 ...aultTestDeployAssert3391A20B.template.json |   36 +
 .../integ.nlb-sg.js.snapshot/manifest.json    |  323 ++++
 .../integ.nlb-sg.js.snapshot/tree.json        | 1304 +++++++++++++++++
 .../test/fargate/integ.nlb-sg.ts              |   40 +
 .../aws-cdk-lib/aws-ecs-patterns/README.md    |   17 +-
 .../network-load-balanced-fargate-service.ts  |    9 +-
 .../load-balanced-fargate-service.test.ts     |   44 +
 12 files changed, 2572 insertions(+), 2 deletions(-)
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/aws-ecs-integ-lb-fargate.assets.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/aws-ecs-integ-lb-fargate.template.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/cdk.out
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/integ.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/l3FargateTestDefaultTestDeployAssert3391A20B.assets.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/l3FargateTestDefaultTestDeployAssert3391A20B.template.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/manifest.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/tree.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.ts

diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/aws-ecs-integ-lb-fargate.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/aws-ecs-integ-lb-fargate.assets.json
new file mode 100644
index 0000000000000..17197614dcd47
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/aws-ecs-integ-lb-fargate.assets.json
@@ -0,0 +1,19 @@
+{
+  "version": "36.0.0",
+  "files": {
+    "01677902a566d4c905bae44eaf146aefbe867b471036ab56d5abe5f9622c0ccd": {
+      "source": {
+        "path": "aws-ecs-integ-lb-fargate.template.json",
+        "packaging": "file"
+      },
+      "destinations": {
+        "current_account-current_region": {
+          "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+          "objectKey": "01677902a566d4c905bae44eaf146aefbe867b471036ab56d5abe5f9622c0ccd.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-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/aws-ecs-integ-lb-fargate.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/aws-ecs-integ-lb-fargate.template.json
new file mode 100644
index 0000000000000..69b2823074894
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/aws-ecs-integ-lb-fargate.template.json
@@ -0,0 +1,750 @@
+{
+ "Resources": {
+  "Vpc8378EB38": {
+   "Type": "AWS::EC2::VPC",
+   "Properties": {
+    "CidrBlock": "10.0.0.0/16",
+    "EnableDnsHostnames": true,
+    "EnableDnsSupport": true,
+    "InstanceTenancy": "default",
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc"
+     }
+    ]
+   }
+  },
+  "VpcPublicSubnet1Subnet5C2D37C4": {
+   "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": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "VpcPublicSubnet1RouteTable6C95E38E": {
+   "Type": "AWS::EC2::RouteTable",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "VpcPublicSubnet1RouteTableAssociation97140677": {
+   "Type": "AWS::EC2::SubnetRouteTableAssociation",
+   "Properties": {
+    "RouteTableId": {
+     "Ref": "VpcPublicSubnet1RouteTable6C95E38E"
+    },
+    "SubnetId": {
+     "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+    }
+   }
+  },
+  "VpcPublicSubnet1DefaultRoute3DA9E72A": {
+   "Type": "AWS::EC2::Route",
+   "Properties": {
+    "DestinationCidrBlock": "0.0.0.0/0",
+    "GatewayId": {
+     "Ref": "VpcIGWD7BA715C"
+    },
+    "RouteTableId": {
+     "Ref": "VpcPublicSubnet1RouteTable6C95E38E"
+    }
+   },
+   "DependsOn": [
+    "VpcVPCGWBF912B6E"
+   ]
+  },
+  "VpcPublicSubnet1EIPD7E02669": {
+   "Type": "AWS::EC2::EIP",
+   "Properties": {
+    "Domain": "vpc",
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1"
+     }
+    ]
+   }
+  },
+  "VpcPublicSubnet1NATGateway4D7517AA": {
+   "Type": "AWS::EC2::NatGateway",
+   "Properties": {
+    "AllocationId": {
+     "Fn::GetAtt": [
+      "VpcPublicSubnet1EIPD7E02669",
+      "AllocationId"
+     ]
+    },
+    "SubnetId": {
+     "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+    },
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1"
+     }
+    ]
+   },
+   "DependsOn": [
+    "VpcPublicSubnet1DefaultRoute3DA9E72A",
+    "VpcPublicSubnet1RouteTableAssociation97140677"
+   ]
+  },
+  "VpcPublicSubnet2Subnet691E08A3": {
+   "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": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2"
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "VpcPublicSubnet2RouteTable94F7E489": {
+   "Type": "AWS::EC2::RouteTable",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2"
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "VpcPublicSubnet2RouteTableAssociationDD5762D8": {
+   "Type": "AWS::EC2::SubnetRouteTableAssociation",
+   "Properties": {
+    "RouteTableId": {
+     "Ref": "VpcPublicSubnet2RouteTable94F7E489"
+    },
+    "SubnetId": {
+     "Ref": "VpcPublicSubnet2Subnet691E08A3"
+    }
+   }
+  },
+  "VpcPublicSubnet2DefaultRoute97F91067": {
+   "Type": "AWS::EC2::Route",
+   "Properties": {
+    "DestinationCidrBlock": "0.0.0.0/0",
+    "GatewayId": {
+     "Ref": "VpcIGWD7BA715C"
+    },
+    "RouteTableId": {
+     "Ref": "VpcPublicSubnet2RouteTable94F7E489"
+    }
+   },
+   "DependsOn": [
+    "VpcVPCGWBF912B6E"
+   ]
+  },
+  "VpcPublicSubnet2EIP3C605A87": {
+   "Type": "AWS::EC2::EIP",
+   "Properties": {
+    "Domain": "vpc",
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2"
+     }
+    ]
+   }
+  },
+  "VpcPublicSubnet2NATGateway9182C01D": {
+   "Type": "AWS::EC2::NatGateway",
+   "Properties": {
+    "AllocationId": {
+     "Fn::GetAtt": [
+      "VpcPublicSubnet2EIP3C605A87",
+      "AllocationId"
+     ]
+    },
+    "SubnetId": {
+     "Ref": "VpcPublicSubnet2Subnet691E08A3"
+    },
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2"
+     }
+    ]
+   },
+   "DependsOn": [
+    "VpcPublicSubnet2DefaultRoute97F91067",
+    "VpcPublicSubnet2RouteTableAssociationDD5762D8"
+   ]
+  },
+  "VpcPrivateSubnet1Subnet536B997A": {
+   "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": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "VpcPrivateSubnet1RouteTableB2C5B500": {
+   "Type": "AWS::EC2::RouteTable",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "VpcPrivateSubnet1RouteTableAssociation70C59FA6": {
+   "Type": "AWS::EC2::SubnetRouteTableAssociation",
+   "Properties": {
+    "RouteTableId": {
+     "Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
+    },
+    "SubnetId": {
+     "Ref": "VpcPrivateSubnet1Subnet536B997A"
+    }
+   }
+  },
+  "VpcPrivateSubnet1DefaultRouteBE02A9ED": {
+   "Type": "AWS::EC2::Route",
+   "Properties": {
+    "DestinationCidrBlock": "0.0.0.0/0",
+    "NatGatewayId": {
+     "Ref": "VpcPublicSubnet1NATGateway4D7517AA"
+    },
+    "RouteTableId": {
+     "Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
+    }
+   }
+  },
+  "VpcPrivateSubnet2Subnet3788AAA1": {
+   "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": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2"
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "VpcPrivateSubnet2RouteTableA678073B": {
+   "Type": "AWS::EC2::RouteTable",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2"
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "VpcPrivateSubnet2RouteTableAssociationA89CAD56": {
+   "Type": "AWS::EC2::SubnetRouteTableAssociation",
+   "Properties": {
+    "RouteTableId": {
+     "Ref": "VpcPrivateSubnet2RouteTableA678073B"
+    },
+    "SubnetId": {
+     "Ref": "VpcPrivateSubnet2Subnet3788AAA1"
+    }
+   }
+  },
+  "VpcPrivateSubnet2DefaultRoute060D2087": {
+   "Type": "AWS::EC2::Route",
+   "Properties": {
+    "DestinationCidrBlock": "0.0.0.0/0",
+    "NatGatewayId": {
+     "Ref": "VpcPublicSubnet2NATGateway9182C01D"
+    },
+    "RouteTableId": {
+     "Ref": "VpcPrivateSubnet2RouteTableA678073B"
+    }
+   }
+  },
+  "VpcIGWD7BA715C": {
+   "Type": "AWS::EC2::InternetGateway",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-ecs-integ-lb-fargate/Vpc"
+     }
+    ]
+   }
+  },
+  "VpcVPCGWBF912B6E": {
+   "Type": "AWS::EC2::VPCGatewayAttachment",
+   "Properties": {
+    "InternetGatewayId": {
+     "Ref": "VpcIGWD7BA715C"
+    },
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "FargateCluster7CCD5F93": {
+   "Type": "AWS::ECS::Cluster"
+  },
+  "SecurityGroupNlbFA132873": {
+   "Type": "AWS::EC2::SecurityGroup",
+   "Properties": {
+    "GroupDescription": "aws-ecs-integ-lb-fargate/SecurityGroupNlb",
+    "SecurityGroupEgress": [
+     {
+      "CidrIp": "0.0.0.0/0",
+      "Description": "Allow all outbound traffic by default",
+      "IpProtocol": "-1"
+     }
+    ],
+    "SecurityGroupIngress": [
+     {
+      "CidrIp": "0.0.0.0/0",
+      "Description": "from 0.0.0.0/0:32768-65535",
+      "FromPort": 32768,
+      "IpProtocol": "tcp",
+      "ToPort": 65535
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "SecurityGroupServiceDE1E5E6A": {
+   "Type": "AWS::EC2::SecurityGroup",
+   "Properties": {
+    "GroupDescription": "aws-ecs-integ-lb-fargate/SecurityGroupService",
+    "SecurityGroupEgress": [
+     {
+      "CidrIp": "0.0.0.0/0",
+      "Description": "Allow all outbound traffic by default",
+      "IpProtocol": "-1"
+     }
+    ],
+    "SecurityGroupIngress": [
+     {
+      "Description": {
+       "Fn::Join": [
+        "",
+        [
+         "from ",
+         {
+          "Fn::GetAtt": [
+           "SecurityGroupNlbFA132873",
+           "GroupId"
+          ]
+         },
+         ":ALL PORTS"
+        ]
+       ]
+      },
+      "FromPort": 0,
+      "IpProtocol": "tcp",
+      "SourceSecurityGroupId": {
+       "Fn::GetAtt": [
+        "SecurityGroupNlbFA132873",
+        "GroupId"
+       ]
+      },
+      "ToPort": 65535
+     }
+    ],
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "NLBFargateServiceLB659EC17C": {
+   "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
+   "Properties": {
+    "LoadBalancerAttributes": [
+     {
+      "Key": "deletion_protection.enabled",
+      "Value": "false"
+     }
+    ],
+    "Scheme": "internet-facing",
+    "SecurityGroups": [
+     {
+      "Fn::GetAtt": [
+       "SecurityGroupNlbFA132873",
+       "GroupId"
+      ]
+     }
+    ],
+    "Subnets": [
+     {
+      "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+     },
+     {
+      "Ref": "VpcPublicSubnet2Subnet691E08A3"
+     }
+    ],
+    "Type": "network"
+   },
+   "DependsOn": [
+    "VpcPublicSubnet1DefaultRoute3DA9E72A",
+    "VpcPublicSubnet1RouteTableAssociation97140677",
+    "VpcPublicSubnet2DefaultRoute97F91067",
+    "VpcPublicSubnet2RouteTableAssociationDD5762D8"
+   ]
+  },
+  "NLBFargateServiceLBPublicListenerB0DCA73C": {
+   "Type": "AWS::ElasticLoadBalancingV2::Listener",
+   "Properties": {
+    "DefaultActions": [
+     {
+      "TargetGroupArn": {
+       "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2"
+      },
+      "Type": "forward"
+     }
+    ],
+    "LoadBalancerArn": {
+     "Ref": "NLBFargateServiceLB659EC17C"
+    },
+    "Port": 80,
+    "Protocol": "TCP"
+   }
+  },
+  "NLBFargateServiceLBPublicListenerECSGroupC469CAA2": {
+   "Type": "AWS::ElasticLoadBalancingV2::TargetGroup",
+   "Properties": {
+    "Port": 80,
+    "Protocol": "TCP",
+    "TargetType": "ip",
+    "VpcId": {
+     "Ref": "Vpc8378EB38"
+    }
+   }
+  },
+  "NLBFargateServiceTaskDefTaskRole6C88F40B": {
+   "Type": "AWS::IAM::Role",
+   "Properties": {
+    "AssumeRolePolicyDocument": {
+     "Statement": [
+      {
+       "Action": "sts:AssumeRole",
+       "Effect": "Allow",
+       "Principal": {
+        "Service": "ecs-tasks.amazonaws.com"
+       }
+      }
+     ],
+     "Version": "2012-10-17"
+    }
+   }
+  },
+  "NLBFargateServiceTaskDefB836FA89": {
+   "Type": "AWS::ECS::TaskDefinition",
+   "Properties": {
+    "ContainerDefinitions": [
+     {
+      "Essential": true,
+      "Image": "amazon/amazon-ecs-sample",
+      "LogConfiguration": {
+       "LogDriver": "awslogs",
+       "Options": {
+        "awslogs-group": {
+         "Ref": "NLBFargateServiceTaskDefwebLogGroupC4A42FE2"
+        },
+        "awslogs-stream-prefix": "NLBFargateService",
+        "awslogs-region": {
+         "Ref": "AWS::Region"
+        }
+       }
+      },
+      "Name": "web",
+      "PortMappings": [
+       {
+        "ContainerPort": 80,
+        "Protocol": "tcp"
+       }
+      ]
+     }
+    ],
+    "Cpu": "512",
+    "ExecutionRoleArn": {
+     "Fn::GetAtt": [
+      "NLBFargateServiceTaskDefExecutionRoleF6D642D5",
+      "Arn"
+     ]
+    },
+    "Family": "awsecsinteglbfargateNLBFargateServiceTaskDef1265FF34",
+    "Memory": "1024",
+    "NetworkMode": "awsvpc",
+    "RequiresCompatibilities": [
+     "FARGATE"
+    ],
+    "TaskRoleArn": {
+     "Fn::GetAtt": [
+      "NLBFargateServiceTaskDefTaskRole6C88F40B",
+      "Arn"
+     ]
+    }
+   }
+  },
+  "NLBFargateServiceTaskDefwebLogGroupC4A42FE2": {
+   "Type": "AWS::Logs::LogGroup",
+   "UpdateReplacePolicy": "Retain",
+   "DeletionPolicy": "Retain"
+  },
+  "NLBFargateServiceTaskDefExecutionRoleF6D642D5": {
+   "Type": "AWS::IAM::Role",
+   "Properties": {
+    "AssumeRolePolicyDocument": {
+     "Statement": [
+      {
+       "Action": "sts:AssumeRole",
+       "Effect": "Allow",
+       "Principal": {
+        "Service": "ecs-tasks.amazonaws.com"
+       }
+      }
+     ],
+     "Version": "2012-10-17"
+    }
+   }
+  },
+  "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805": {
+   "Type": "AWS::IAM::Policy",
+   "Properties": {
+    "PolicyDocument": {
+     "Statement": [
+      {
+       "Action": [
+        "logs:CreateLogStream",
+        "logs:PutLogEvents"
+       ],
+       "Effect": "Allow",
+       "Resource": {
+        "Fn::GetAtt": [
+         "NLBFargateServiceTaskDefwebLogGroupC4A42FE2",
+         "Arn"
+        ]
+       }
+      }
+     ],
+     "Version": "2012-10-17"
+    },
+    "PolicyName": "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805",
+    "Roles": [
+     {
+      "Ref": "NLBFargateServiceTaskDefExecutionRoleF6D642D5"
+     }
+    ]
+   }
+  },
+  "NLBFargateServiceB92AC095": {
+   "Type": "AWS::ECS::Service",
+   "Properties": {
+    "Cluster": {
+     "Ref": "FargateCluster7CCD5F93"
+    },
+    "DeploymentConfiguration": {
+     "Alarms": {
+      "AlarmNames": [],
+      "Enable": false,
+      "Rollback": false
+     },
+     "MaximumPercent": 200,
+     "MinimumHealthyPercent": 50
+    },
+    "EnableECSManagedTags": false,
+    "HealthCheckGracePeriodSeconds": 60,
+    "LaunchType": "FARGATE",
+    "LoadBalancers": [
+     {
+      "ContainerName": "web",
+      "ContainerPort": 80,
+      "TargetGroupArn": {
+       "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2"
+      }
+     }
+    ],
+    "NetworkConfiguration": {
+     "AwsvpcConfiguration": {
+      "AssignPublicIp": "DISABLED",
+      "SecurityGroups": [
+       {
+        "Fn::GetAtt": [
+         "SecurityGroupServiceDE1E5E6A",
+         "GroupId"
+        ]
+       }
+      ],
+      "Subnets": [
+       {
+        "Ref": "VpcPrivateSubnet1Subnet536B997A"
+       },
+       {
+        "Ref": "VpcPrivateSubnet2Subnet3788AAA1"
+       }
+      ]
+     }
+    },
+    "TaskDefinition": {
+     "Ref": "NLBFargateServiceTaskDefB836FA89"
+    }
+   },
+   "DependsOn": [
+    "NLBFargateServiceLBPublicListenerECSGroupC469CAA2",
+    "NLBFargateServiceLBPublicListenerB0DCA73C",
+    "NLBFargateServiceTaskDefTaskRole6C88F40B"
+   ]
+  }
+ },
+ "Outputs": {
+  "NLBFargateServiceLoadBalancerDNSC2B2922F": {
+   "Value": {
+    "Fn::GetAtt": [
+     "NLBFargateServiceLB659EC17C",
+     "DNSName"
+    ]
+   }
+  }
+ },
+ "Parameters": {
+  "BootstrapVersion": {
+   "Type": "AWS::SSM::Parameter::Value<String>",
+   "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-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/cdk.out
new file mode 100644
index 0000000000000..1f0068d32659a
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.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-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/integ.json
new file mode 100644
index 0000000000000..6d95f61c34e55
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/integ.json
@@ -0,0 +1,12 @@
+{
+  "version": "36.0.0",
+  "testCases": {
+    "l3FargateTest/DefaultTest": {
+      "stacks": [
+        "aws-ecs-integ-lb-fargate"
+      ],
+      "assertionStack": "l3FargateTest/DefaultTest/DeployAssert",
+      "assertionStackName": "l3FargateTestDefaultTestDeployAssert3391A20B"
+    }
+  }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/l3FargateTestDefaultTestDeployAssert3391A20B.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/l3FargateTestDefaultTestDeployAssert3391A20B.assets.json
new file mode 100644
index 0000000000000..4e6f5d15656c9
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/l3FargateTestDefaultTestDeployAssert3391A20B.assets.json
@@ -0,0 +1,19 @@
+{
+  "version": "36.0.0",
+  "files": {
+    "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
+      "source": {
+        "path": "l3FargateTestDefaultTestDeployAssert3391A20B.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-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/l3FargateTestDefaultTestDeployAssert3391A20B.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/l3FargateTestDefaultTestDeployAssert3391A20B.template.json
new file mode 100644
index 0000000000000..ad9d0fb73d1dd
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/l3FargateTestDefaultTestDeployAssert3391A20B.template.json
@@ -0,0 +1,36 @@
+{
+ "Parameters": {
+  "BootstrapVersion": {
+   "Type": "AWS::SSM::Parameter::Value<String>",
+   "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-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/manifest.json
new file mode 100644
index 0000000000000..796449a3f0f70
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/manifest.json
@@ -0,0 +1,323 @@
+{
+  "version": "36.0.0",
+  "artifacts": {
+    "aws-ecs-integ-lb-fargate.assets": {
+      "type": "cdk:asset-manifest",
+      "properties": {
+        "file": "aws-ecs-integ-lb-fargate.assets.json",
+        "requiresBootstrapStackVersion": 6,
+        "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
+      }
+    },
+    "aws-ecs-integ-lb-fargate": {
+      "type": "aws:cloudformation:stack",
+      "environment": "aws://unknown-account/unknown-region",
+      "properties": {
+        "templateFile": "aws-ecs-integ-lb-fargate.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}/01677902a566d4c905bae44eaf146aefbe867b471036ab56d5abe5f9622c0ccd.json",
+        "requiresBootstrapStackVersion": 6,
+        "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
+        "additionalDependencies": [
+          "aws-ecs-integ-lb-fargate.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": [
+        "aws-ecs-integ-lb-fargate.assets"
+      ],
+      "metadata": {
+        "/aws-ecs-integ-lb-fargate/Vpc/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "Vpc8378EB38"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/Subnet": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet1Subnet5C2D37C4"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/RouteTable": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet1RouteTable6C95E38E"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/RouteTableAssociation": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet1RouteTableAssociation97140677"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/DefaultRoute": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet1DefaultRoute3DA9E72A"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/EIP": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet1EIPD7E02669"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/NATGateway": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet1NATGateway4D7517AA"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/Subnet": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet2Subnet691E08A3"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/RouteTable": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet2RouteTable94F7E489"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/RouteTableAssociation": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet2RouteTableAssociationDD5762D8"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/DefaultRoute": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet2DefaultRoute97F91067"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/EIP": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet2EIP3C605A87"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/NATGateway": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPublicSubnet2NATGateway9182C01D"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1/Subnet": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPrivateSubnet1Subnet536B997A"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1/RouteTable": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPrivateSubnet1RouteTableB2C5B500"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1/RouteTableAssociation": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPrivateSubnet1RouteTableAssociation70C59FA6"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1/DefaultRoute": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPrivateSubnet1DefaultRouteBE02A9ED"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2/Subnet": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPrivateSubnet2Subnet3788AAA1"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2/RouteTable": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPrivateSubnet2RouteTableA678073B"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2/RouteTableAssociation": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPrivateSubnet2RouteTableAssociationA89CAD56"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2/DefaultRoute": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcPrivateSubnet2DefaultRoute060D2087"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/IGW": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcIGWD7BA715C"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/Vpc/VPCGW": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "VpcVPCGWBF912B6E"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/FargateCluster/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "FargateCluster7CCD5F93"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/SecurityGroupNlb/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "SecurityGroupNlbFA132873"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/SecurityGroupService/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "SecurityGroupServiceDE1E5E6A"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/LB/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceLB659EC17C"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/LB/PublicListener/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceLBPublicListenerB0DCA73C"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/LB/PublicListener/ECSGroup/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/LoadBalancerDNS": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceLoadBalancerDNSC2B2922F"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/TaskRole/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceTaskDefTaskRole6C88F40B"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceTaskDefB836FA89"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/web/LogGroup/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceTaskDefwebLogGroupC4A42FE2"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/ExecutionRole/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceTaskDefExecutionRoleF6D642D5"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/ExecutionRole/DefaultPolicy/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/NLBFargateService/Service/Service": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "NLBFargateServiceB92AC095"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/BootstrapVersion": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "BootstrapVersion"
+          }
+        ],
+        "/aws-ecs-integ-lb-fargate/CheckBootstrapVersion": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "CheckBootstrapVersion"
+          }
+        ]
+      },
+      "displayName": "aws-ecs-integ-lb-fargate"
+    },
+    "l3FargateTestDefaultTestDeployAssert3391A20B.assets": {
+      "type": "cdk:asset-manifest",
+      "properties": {
+        "file": "l3FargateTestDefaultTestDeployAssert3391A20B.assets.json",
+        "requiresBootstrapStackVersion": 6,
+        "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
+      }
+    },
+    "l3FargateTestDefaultTestDeployAssert3391A20B": {
+      "type": "aws:cloudformation:stack",
+      "environment": "aws://unknown-account/unknown-region",
+      "properties": {
+        "templateFile": "l3FargateTestDefaultTestDeployAssert3391A20B.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": [
+          "l3FargateTestDefaultTestDeployAssert3391A20B.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": [
+        "l3FargateTestDefaultTestDeployAssert3391A20B.assets"
+      ],
+      "metadata": {
+        "/l3FargateTest/DefaultTest/DeployAssert/BootstrapVersion": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "BootstrapVersion"
+          }
+        ],
+        "/l3FargateTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "CheckBootstrapVersion"
+          }
+        ]
+      },
+      "displayName": "l3FargateTest/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-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/tree.json
new file mode 100644
index 0000000000000..8e06bfa34093f
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.js.snapshot/tree.json
@@ -0,0 +1,1304 @@
+{
+  "version": "tree-0.1",
+  "tree": {
+    "id": "App",
+    "path": "",
+    "children": {
+      "aws-ecs-integ-lb-fargate": {
+        "id": "aws-ecs-integ-lb-fargate",
+        "path": "aws-ecs-integ-lb-fargate",
+        "children": {
+          "Vpc": {
+            "id": "Vpc",
+            "path": "aws-ecs-integ-lb-fargate/Vpc",
+            "children": {
+              "Resource": {
+                "id": "Resource",
+                "path": "aws-ecs-integ-lb-fargate/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": "aws-ecs-integ-lb-fargate/Vpc"
+                      }
+                    ]
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.aws_ec2.CfnVPC",
+                  "version": "0.0.0"
+                }
+              },
+              "PublicSubnet1": {
+                "id": "PublicSubnet1",
+                "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1",
+                "children": {
+                  "Subnet": {
+                    "id": "Subnet",
+                    "path": "aws-ecs-integ-lb-fargate/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": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "Vpc8378EB38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "Acl": {
+                    "id": "Acl",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/Acl",
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.Resource",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "RouteTable": {
+                    "id": "RouteTable",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/RouteTable",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+                      "aws:cdk:cloudformation:props": {
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "Vpc8378EB38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "RouteTableAssociation": {
+                    "id": "RouteTableAssociation",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/RouteTableAssociation",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+                      "aws:cdk:cloudformation:props": {
+                        "routeTableId": {
+                          "Ref": "VpcPublicSubnet1RouteTable6C95E38E"
+                        },
+                        "subnetId": {
+                          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "DefaultRoute": {
+                    "id": "DefaultRoute",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/DefaultRoute",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+                      "aws:cdk:cloudformation:props": {
+                        "destinationCidrBlock": "0.0.0.0/0",
+                        "gatewayId": {
+                          "Ref": "VpcIGWD7BA715C"
+                        },
+                        "routeTableId": {
+                          "Ref": "VpcPublicSubnet1RouteTable6C95E38E"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "EIP": {
+                    "id": "EIP",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/EIP",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::EIP",
+                      "aws:cdk:cloudformation:props": {
+                        "domain": "vpc",
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1"
+                          }
+                        ]
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnEIP",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "NATGateway": {
+                    "id": "NATGateway",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1/NATGateway",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway",
+                      "aws:cdk:cloudformation:props": {
+                        "allocationId": {
+                          "Fn::GetAtt": [
+                            "VpcPublicSubnet1EIPD7E02669",
+                            "AllocationId"
+                          ]
+                        },
+                        "subnetId": {
+                          "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+                        },
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-ecs-integ-lb-fargate/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": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2",
+                "children": {
+                  "Subnet": {
+                    "id": "Subnet",
+                    "path": "aws-ecs-integ-lb-fargate/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": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "Vpc8378EB38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "Acl": {
+                    "id": "Acl",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/Acl",
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.Resource",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "RouteTable": {
+                    "id": "RouteTable",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/RouteTable",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+                      "aws:cdk:cloudformation:props": {
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "Vpc8378EB38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "RouteTableAssociation": {
+                    "id": "RouteTableAssociation",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/RouteTableAssociation",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+                      "aws:cdk:cloudformation:props": {
+                        "routeTableId": {
+                          "Ref": "VpcPublicSubnet2RouteTable94F7E489"
+                        },
+                        "subnetId": {
+                          "Ref": "VpcPublicSubnet2Subnet691E08A3"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "DefaultRoute": {
+                    "id": "DefaultRoute",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/DefaultRoute",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+                      "aws:cdk:cloudformation:props": {
+                        "destinationCidrBlock": "0.0.0.0/0",
+                        "gatewayId": {
+                          "Ref": "VpcIGWD7BA715C"
+                        },
+                        "routeTableId": {
+                          "Ref": "VpcPublicSubnet2RouteTable94F7E489"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnRoute",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "EIP": {
+                    "id": "EIP",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/EIP",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::EIP",
+                      "aws:cdk:cloudformation:props": {
+                        "domain": "vpc",
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2"
+                          }
+                        ]
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnEIP",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "NATGateway": {
+                    "id": "NATGateway",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2/NATGateway",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway",
+                      "aws:cdk:cloudformation:props": {
+                        "allocationId": {
+                          "Fn::GetAtt": [
+                            "VpcPublicSubnet2EIP3C605A87",
+                            "AllocationId"
+                          ]
+                        },
+                        "subnetId": {
+                          "Ref": "VpcPublicSubnet2Subnet691E08A3"
+                        },
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-ecs-integ-lb-fargate/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": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1",
+                "children": {
+                  "Subnet": {
+                    "id": "Subnet",
+                    "path": "aws-ecs-integ-lb-fargate/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": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "Vpc8378EB38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "Acl": {
+                    "id": "Acl",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1/Acl",
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.Resource",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "RouteTable": {
+                    "id": "RouteTable",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1/RouteTable",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+                      "aws:cdk:cloudformation:props": {
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "Vpc8378EB38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "RouteTableAssociation": {
+                    "id": "RouteTableAssociation",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1/RouteTableAssociation",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+                      "aws:cdk:cloudformation:props": {
+                        "routeTableId": {
+                          "Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
+                        },
+                        "subnetId": {
+                          "Ref": "VpcPrivateSubnet1Subnet536B997A"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "DefaultRoute": {
+                    "id": "DefaultRoute",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1/DefaultRoute",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+                      "aws:cdk:cloudformation:props": {
+                        "destinationCidrBlock": "0.0.0.0/0",
+                        "natGatewayId": {
+                          "Ref": "VpcPublicSubnet1NATGateway4D7517AA"
+                        },
+                        "routeTableId": {
+                          "Ref": "VpcPrivateSubnet1RouteTableB2C5B500"
+                        }
+                      }
+                    },
+                    "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": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2",
+                "children": {
+                  "Subnet": {
+                    "id": "Subnet",
+                    "path": "aws-ecs-integ-lb-fargate/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": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "Vpc8378EB38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "Acl": {
+                    "id": "Acl",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2/Acl",
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.Resource",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "RouteTable": {
+                    "id": "RouteTable",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2/RouteTable",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+                      "aws:cdk:cloudformation:props": {
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "Vpc8378EB38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "RouteTableAssociation": {
+                    "id": "RouteTableAssociation",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2/RouteTableAssociation",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+                      "aws:cdk:cloudformation:props": {
+                        "routeTableId": {
+                          "Ref": "VpcPrivateSubnet2RouteTableA678073B"
+                        },
+                        "subnetId": {
+                          "Ref": "VpcPrivateSubnet2Subnet3788AAA1"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "DefaultRoute": {
+                    "id": "DefaultRoute",
+                    "path": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2/DefaultRoute",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+                      "aws:cdk:cloudformation:props": {
+                        "destinationCidrBlock": "0.0.0.0/0",
+                        "natGatewayId": {
+                          "Ref": "VpcPublicSubnet2NATGateway9182C01D"
+                        },
+                        "routeTableId": {
+                          "Ref": "VpcPrivateSubnet2RouteTableA678073B"
+                        }
+                      }
+                    },
+                    "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": "aws-ecs-integ-lb-fargate/Vpc/IGW",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway",
+                  "aws:cdk:cloudformation:props": {
+                    "tags": [
+                      {
+                        "key": "Name",
+                        "value": "aws-ecs-integ-lb-fargate/Vpc"
+                      }
+                    ]
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway",
+                  "version": "0.0.0"
+                }
+              },
+              "VPCGW": {
+                "id": "VPCGW",
+                "path": "aws-ecs-integ-lb-fargate/Vpc/VPCGW",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment",
+                  "aws:cdk:cloudformation:props": {
+                    "internetGatewayId": {
+                      "Ref": "VpcIGWD7BA715C"
+                    },
+                    "vpcId": {
+                      "Ref": "Vpc8378EB38"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment",
+                  "version": "0.0.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "aws-cdk-lib.aws_ec2.Vpc",
+              "version": "0.0.0"
+            }
+          },
+          "FargateCluster": {
+            "id": "FargateCluster",
+            "path": "aws-ecs-integ-lb-fargate/FargateCluster",
+            "children": {
+              "Resource": {
+                "id": "Resource",
+                "path": "aws-ecs-integ-lb-fargate/FargateCluster/Resource",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::ECS::Cluster",
+                  "aws:cdk:cloudformation:props": {}
+                },
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.aws_ecs.CfnCluster",
+                  "version": "0.0.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "aws-cdk-lib.aws_ecs.Cluster",
+              "version": "0.0.0"
+            }
+          },
+          "SecurityGroupNlb": {
+            "id": "SecurityGroupNlb",
+            "path": "aws-ecs-integ-lb-fargate/SecurityGroupNlb",
+            "children": {
+              "Resource": {
+                "id": "Resource",
+                "path": "aws-ecs-integ-lb-fargate/SecurityGroupNlb/Resource",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup",
+                  "aws:cdk:cloudformation:props": {
+                    "groupDescription": "aws-ecs-integ-lb-fargate/SecurityGroupNlb",
+                    "securityGroupEgress": [
+                      {
+                        "cidrIp": "0.0.0.0/0",
+                        "description": "Allow all outbound traffic by default",
+                        "ipProtocol": "-1"
+                      }
+                    ],
+                    "securityGroupIngress": [
+                      {
+                        "cidrIp": "0.0.0.0/0",
+                        "ipProtocol": "tcp",
+                        "fromPort": 32768,
+                        "toPort": 65535,
+                        "description": "from 0.0.0.0/0:32768-65535"
+                      }
+                    ],
+                    "vpcId": {
+                      "Ref": "Vpc8378EB38"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup",
+                  "version": "0.0.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup",
+              "version": "0.0.0"
+            }
+          },
+          "SecurityGroupService": {
+            "id": "SecurityGroupService",
+            "path": "aws-ecs-integ-lb-fargate/SecurityGroupService",
+            "children": {
+              "Resource": {
+                "id": "Resource",
+                "path": "aws-ecs-integ-lb-fargate/SecurityGroupService/Resource",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup",
+                  "aws:cdk:cloudformation:props": {
+                    "groupDescription": "aws-ecs-integ-lb-fargate/SecurityGroupService",
+                    "securityGroupEgress": [
+                      {
+                        "cidrIp": "0.0.0.0/0",
+                        "description": "Allow all outbound traffic by default",
+                        "ipProtocol": "-1"
+                      }
+                    ],
+                    "securityGroupIngress": [
+                      {
+                        "sourceSecurityGroupId": {
+                          "Fn::GetAtt": [
+                            "SecurityGroupNlbFA132873",
+                            "GroupId"
+                          ]
+                        },
+                        "ipProtocol": "tcp",
+                        "fromPort": 0,
+                        "toPort": 65535,
+                        "description": {
+                          "Fn::Join": [
+                            "",
+                            [
+                              "from ",
+                              {
+                                "Fn::GetAtt": [
+                                  "SecurityGroupNlbFA132873",
+                                  "GroupId"
+                                ]
+                              },
+                              ":ALL PORTS"
+                            ]
+                          ]
+                        }
+                      }
+                    ],
+                    "vpcId": {
+                      "Ref": "Vpc8378EB38"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup",
+                  "version": "0.0.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup",
+              "version": "0.0.0"
+            }
+          },
+          "NLBFargateService": {
+            "id": "NLBFargateService",
+            "path": "aws-ecs-integ-lb-fargate/NLBFargateService",
+            "children": {
+              "LB": {
+                "id": "LB",
+                "path": "aws-ecs-integ-lb-fargate/NLBFargateService/LB",
+                "children": {
+                  "Resource": {
+                    "id": "Resource",
+                    "path": "aws-ecs-integ-lb-fargate/NLBFargateService/LB/Resource",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
+                      "aws:cdk:cloudformation:props": {
+                        "loadBalancerAttributes": [
+                          {
+                            "key": "deletion_protection.enabled",
+                            "value": "false"
+                          }
+                        ],
+                        "scheme": "internet-facing",
+                        "securityGroups": [
+                          {
+                            "Fn::GetAtt": [
+                              "SecurityGroupNlbFA132873",
+                              "GroupId"
+                            ]
+                          }
+                        ],
+                        "subnets": [
+                          {
+                            "Ref": "VpcPublicSubnet1Subnet5C2D37C4"
+                          },
+                          {
+                            "Ref": "VpcPublicSubnet2Subnet691E08A3"
+                          }
+                        ],
+                        "type": "network"
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "PublicListener": {
+                    "id": "PublicListener",
+                    "path": "aws-ecs-integ-lb-fargate/NLBFargateService/LB/PublicListener",
+                    "children": {
+                      "Resource": {
+                        "id": "Resource",
+                        "path": "aws-ecs-integ-lb-fargate/NLBFargateService/LB/PublicListener/Resource",
+                        "attributes": {
+                          "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener",
+                          "aws:cdk:cloudformation:props": {
+                            "defaultActions": [
+                              {
+                                "type": "forward",
+                                "targetGroupArn": {
+                                  "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2"
+                                }
+                              }
+                            ],
+                            "loadBalancerArn": {
+                              "Ref": "NLBFargateServiceLB659EC17C"
+                            },
+                            "port": 80,
+                            "protocol": "TCP"
+                          }
+                        },
+                        "constructInfo": {
+                          "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnListener",
+                          "version": "0.0.0"
+                        }
+                      },
+                      "ECSGroup": {
+                        "id": "ECSGroup",
+                        "path": "aws-ecs-integ-lb-fargate/NLBFargateService/LB/PublicListener/ECSGroup",
+                        "children": {
+                          "Resource": {
+                            "id": "Resource",
+                            "path": "aws-ecs-integ-lb-fargate/NLBFargateService/LB/PublicListener/ECSGroup/Resource",
+                            "attributes": {
+                              "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::TargetGroup",
+                              "aws:cdk:cloudformation:props": {
+                                "port": 80,
+                                "protocol": "TCP",
+                                "targetType": "ip",
+                                "vpcId": {
+                                  "Ref": "Vpc8378EB38"
+                                }
+                              }
+                            },
+                            "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"
+                }
+              },
+              "LoadBalancerDNS": {
+                "id": "LoadBalancerDNS",
+                "path": "aws-ecs-integ-lb-fargate/NLBFargateService/LoadBalancerDNS",
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.CfnOutput",
+                  "version": "0.0.0"
+                }
+              },
+              "TaskDef": {
+                "id": "TaskDef",
+                "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef",
+                "children": {
+                  "TaskRole": {
+                    "id": "TaskRole",
+                    "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/TaskRole",
+                    "children": {
+                      "ImportTaskRole": {
+                        "id": "ImportTaskRole",
+                        "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/TaskRole/ImportTaskRole",
+                        "constructInfo": {
+                          "fqn": "aws-cdk-lib.Resource",
+                          "version": "0.0.0"
+                        }
+                      },
+                      "Resource": {
+                        "id": "Resource",
+                        "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/TaskRole/Resource",
+                        "attributes": {
+                          "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+                          "aws:cdk:cloudformation:props": {
+                            "assumeRolePolicyDocument": {
+                              "Statement": [
+                                {
+                                  "Action": "sts:AssumeRole",
+                                  "Effect": "Allow",
+                                  "Principal": {
+                                    "Service": "ecs-tasks.amazonaws.com"
+                                  }
+                                }
+                              ],
+                              "Version": "2012-10-17"
+                            }
+                          }
+                        },
+                        "constructInfo": {
+                          "fqn": "aws-cdk-lib.aws_iam.CfnRole",
+                          "version": "0.0.0"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_iam.Role",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "Resource": {
+                    "id": "Resource",
+                    "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/Resource",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::ECS::TaskDefinition",
+                      "aws:cdk:cloudformation:props": {
+                        "containerDefinitions": [
+                          {
+                            "essential": true,
+                            "image": "amazon/amazon-ecs-sample",
+                            "name": "web",
+                            "portMappings": [
+                              {
+                                "containerPort": 80,
+                                "protocol": "tcp"
+                              }
+                            ],
+                            "logConfiguration": {
+                              "logDriver": "awslogs",
+                              "options": {
+                                "awslogs-group": {
+                                  "Ref": "NLBFargateServiceTaskDefwebLogGroupC4A42FE2"
+                                },
+                                "awslogs-stream-prefix": "NLBFargateService",
+                                "awslogs-region": {
+                                  "Ref": "AWS::Region"
+                                }
+                              }
+                            }
+                          }
+                        ],
+                        "cpu": "512",
+                        "executionRoleArn": {
+                          "Fn::GetAtt": [
+                            "NLBFargateServiceTaskDefExecutionRoleF6D642D5",
+                            "Arn"
+                          ]
+                        },
+                        "family": "awsecsinteglbfargateNLBFargateServiceTaskDef1265FF34",
+                        "memory": "1024",
+                        "networkMode": "awsvpc",
+                        "requiresCompatibilities": [
+                          "FARGATE"
+                        ],
+                        "taskRoleArn": {
+                          "Fn::GetAtt": [
+                            "NLBFargateServiceTaskDefTaskRole6C88F40B",
+                            "Arn"
+                          ]
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ecs.CfnTaskDefinition",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "web": {
+                    "id": "web",
+                    "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/web",
+                    "children": {
+                      "LogGroup": {
+                        "id": "LogGroup",
+                        "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/web/LogGroup",
+                        "children": {
+                          "Resource": {
+                            "id": "Resource",
+                            "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/web/LogGroup/Resource",
+                            "attributes": {
+                              "aws:cdk:cloudformation:type": "AWS::Logs::LogGroup",
+                              "aws:cdk:cloudformation:props": {}
+                            },
+                            "constructInfo": {
+                              "fqn": "aws-cdk-lib.aws_logs.CfnLogGroup",
+                              "version": "0.0.0"
+                            }
+                          }
+                        },
+                        "constructInfo": {
+                          "fqn": "aws-cdk-lib.aws_logs.LogGroup",
+                          "version": "0.0.0"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ecs.ContainerDefinition",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "ExecutionRole": {
+                    "id": "ExecutionRole",
+                    "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/ExecutionRole",
+                    "children": {
+                      "ImportExecutionRole": {
+                        "id": "ImportExecutionRole",
+                        "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/ExecutionRole/ImportExecutionRole",
+                        "constructInfo": {
+                          "fqn": "aws-cdk-lib.Resource",
+                          "version": "0.0.0"
+                        }
+                      },
+                      "Resource": {
+                        "id": "Resource",
+                        "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/ExecutionRole/Resource",
+                        "attributes": {
+                          "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+                          "aws:cdk:cloudformation:props": {
+                            "assumeRolePolicyDocument": {
+                              "Statement": [
+                                {
+                                  "Action": "sts:AssumeRole",
+                                  "Effect": "Allow",
+                                  "Principal": {
+                                    "Service": "ecs-tasks.amazonaws.com"
+                                  }
+                                }
+                              ],
+                              "Version": "2012-10-17"
+                            }
+                          }
+                        },
+                        "constructInfo": {
+                          "fqn": "aws-cdk-lib.aws_iam.CfnRole",
+                          "version": "0.0.0"
+                        }
+                      },
+                      "DefaultPolicy": {
+                        "id": "DefaultPolicy",
+                        "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/ExecutionRole/DefaultPolicy",
+                        "children": {
+                          "Resource": {
+                            "id": "Resource",
+                            "path": "aws-ecs-integ-lb-fargate/NLBFargateService/TaskDef/ExecutionRole/DefaultPolicy/Resource",
+                            "attributes": {
+                              "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+                              "aws:cdk:cloudformation:props": {
+                                "policyDocument": {
+                                  "Statement": [
+                                    {
+                                      "Action": [
+                                        "logs:CreateLogStream",
+                                        "logs:PutLogEvents"
+                                      ],
+                                      "Effect": "Allow",
+                                      "Resource": {
+                                        "Fn::GetAtt": [
+                                          "NLBFargateServiceTaskDefwebLogGroupC4A42FE2",
+                                          "Arn"
+                                        ]
+                                      }
+                                    }
+                                  ],
+                                  "Version": "2012-10-17"
+                                },
+                                "policyName": "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805",
+                                "roles": [
+                                  {
+                                    "Ref": "NLBFargateServiceTaskDefExecutionRoleF6D642D5"
+                                  }
+                                ]
+                              }
+                            },
+                            "constructInfo": {
+                              "fqn": "aws-cdk-lib.aws_iam.CfnPolicy",
+                              "version": "0.0.0"
+                            }
+                          }
+                        },
+                        "constructInfo": {
+                          "fqn": "aws-cdk-lib.aws_iam.Policy",
+                          "version": "0.0.0"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_iam.Role",
+                      "version": "0.0.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.aws_ecs.FargateTaskDefinition",
+                  "version": "0.0.0"
+                }
+              },
+              "Service": {
+                "id": "Service",
+                "path": "aws-ecs-integ-lb-fargate/NLBFargateService/Service",
+                "children": {
+                  "Service": {
+                    "id": "Service",
+                    "path": "aws-ecs-integ-lb-fargate/NLBFargateService/Service/Service",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::ECS::Service",
+                      "aws:cdk:cloudformation:props": {
+                        "cluster": {
+                          "Ref": "FargateCluster7CCD5F93"
+                        },
+                        "deploymentConfiguration": {
+                          "maximumPercent": 200,
+                          "minimumHealthyPercent": 50,
+                          "alarms": {
+                            "alarmNames": [],
+                            "enable": false,
+                            "rollback": false
+                          }
+                        },
+                        "enableEcsManagedTags": false,
+                        "healthCheckGracePeriodSeconds": 60,
+                        "launchType": "FARGATE",
+                        "loadBalancers": [
+                          {
+                            "targetGroupArn": {
+                              "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2"
+                            },
+                            "containerName": "web",
+                            "containerPort": 80
+                          }
+                        ],
+                        "networkConfiguration": {
+                          "awsvpcConfiguration": {
+                            "assignPublicIp": "DISABLED",
+                            "subnets": [
+                              {
+                                "Ref": "VpcPrivateSubnet1Subnet536B997A"
+                              },
+                              {
+                                "Ref": "VpcPrivateSubnet2Subnet3788AAA1"
+                              }
+                            ],
+                            "securityGroups": [
+                              {
+                                "Fn::GetAtt": [
+                                  "SecurityGroupServiceDE1E5E6A",
+                                  "GroupId"
+                                ]
+                              }
+                            ]
+                          }
+                        },
+                        "taskDefinition": {
+                          "Ref": "NLBFargateServiceTaskDefB836FA89"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.aws_ecs.CfnService",
+                      "version": "0.0.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "aws-cdk-lib.aws_ecs.FargateService",
+                  "version": "0.0.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "aws-cdk-lib.aws_ecs_patterns.NetworkLoadBalancedFargateService",
+              "version": "0.0.0"
+            }
+          },
+          "BootstrapVersion": {
+            "id": "BootstrapVersion",
+            "path": "aws-ecs-integ-lb-fargate/BootstrapVersion",
+            "constructInfo": {
+              "fqn": "aws-cdk-lib.CfnParameter",
+              "version": "0.0.0"
+            }
+          },
+          "CheckBootstrapVersion": {
+            "id": "CheckBootstrapVersion",
+            "path": "aws-ecs-integ-lb-fargate/CheckBootstrapVersion",
+            "constructInfo": {
+              "fqn": "aws-cdk-lib.CfnRule",
+              "version": "0.0.0"
+            }
+          }
+        },
+        "constructInfo": {
+          "fqn": "aws-cdk-lib.Stack",
+          "version": "0.0.0"
+        }
+      },
+      "l3FargateTest": {
+        "id": "l3FargateTest",
+        "path": "l3FargateTest",
+        "children": {
+          "DefaultTest": {
+            "id": "DefaultTest",
+            "path": "l3FargateTest/DefaultTest",
+            "children": {
+              "Default": {
+                "id": "Default",
+                "path": "l3FargateTest/DefaultTest/Default",
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "DeployAssert": {
+                "id": "DeployAssert",
+                "path": "l3FargateTest/DefaultTest/DeployAssert",
+                "children": {
+                  "BootstrapVersion": {
+                    "id": "BootstrapVersion",
+                    "path": "l3FargateTest/DefaultTest/DeployAssert/BootstrapVersion",
+                    "constructInfo": {
+                      "fqn": "aws-cdk-lib.CfnParameter",
+                      "version": "0.0.0"
+                    }
+                  },
+                  "CheckBootstrapVersion": {
+                    "id": "CheckBootstrapVersion",
+                    "path": "l3FargateTest/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-ecs-patterns/test/fargate/integ.nlb-sg.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.ts
new file mode 100644
index 0000000000000..a88af6f0e0ee9
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs-patterns/test/fargate/integ.nlb-sg.ts
@@ -0,0 +1,40 @@
+import * as ec2 from 'aws-cdk-lib/aws-ec2';
+import * as ecs from 'aws-cdk-lib/aws-ecs';
+import * as cdk from 'aws-cdk-lib';
+import * as integ from '@aws-cdk/integ-tests-alpha';
+import * as ecsPatterns from 'aws-cdk-lib/aws-ecs-patterns';
+
+const app = new cdk.App();
+const stack = new cdk.Stack(app, 'aws-ecs-integ-lb-fargate');
+
+// Create VPC and cluster
+const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2, restrictDefaultSecurityGroup: false });
+const cluster = new ecs.Cluster(stack, 'FargateCluster', { vpc });
+const securityGroupNlb = new ec2.SecurityGroup(stack, 'SecurityGroupNlb', {
+  vpc,
+  allowAllOutbound: true,
+});
+securityGroupNlb.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcpRange(32768, 65535));
+const securityGroupService = new ec2.SecurityGroup(stack, 'SecurityGroupService', {
+  vpc,
+  allowAllOutbound: true,
+});
+securityGroupService.addIngressRule(ec2.Peer.securityGroupId(securityGroupNlb.securityGroupId), ec2.Port.allTcp());
+
+// Create NLB service with security group
+const networkLoadBalancedFargateService = new ecsPatterns.NetworkLoadBalancedFargateService(stack, 'NLBFargateService', {
+  cluster,
+  memoryLimitMiB: 1024,
+  cpu: 512,
+  taskImageOptions: {
+    image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
+  },
+  securityGroups: [securityGroupService],
+});
+networkLoadBalancedFargateService.loadBalancer.connections.addSecurityGroup(securityGroupNlb);
+
+new integ.IntegTest(app, 'l3FargateTest', {
+  testCases: [stack],
+});
+
+app.synth();
diff --git a/packages/aws-cdk-lib/aws-ecs-patterns/README.md b/packages/aws-cdk-lib/aws-ecs-patterns/README.md
index 6dda31ecccfaf..f927f78127524 100644
--- a/packages/aws-cdk-lib/aws-ecs-patterns/README.md
+++ b/packages/aws-cdk-lib/aws-ecs-patterns/README.md
@@ -1072,4 +1072,19 @@ const networkLoadBalancedFargateService = new ecsPatterns.NetworkLoadBalancedFar
     image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
   },
 });
-```
\ No newline at end of file
+```
+
+### Set securityGroups for NetworkLoadBalancedFargateService
+
+```ts
+declare const vpc: ec2.Vpc;
+declare const securityGroup: ec2.SecurityGroup;
+const queueProcessingFargateService = new ecsPatterns.NetworkLoadBalancedFargateService(this, 'Service', {
+  vpc,
+  memoryLimitMiB: 512,
+  taskImageOptions: {
+    image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
+  },
+  securityGroups: [securityGroup],
+});
+```
diff --git a/packages/aws-cdk-lib/aws-ecs-patterns/lib/fargate/network-load-balanced-fargate-service.ts b/packages/aws-cdk-lib/aws-ecs-patterns/lib/fargate/network-load-balanced-fargate-service.ts
index 993a17a92aed2..cf5b0389914c8 100644
--- a/packages/aws-cdk-lib/aws-ecs-patterns/lib/fargate/network-load-balanced-fargate-service.ts
+++ b/packages/aws-cdk-lib/aws-ecs-patterns/lib/fargate/network-load-balanced-fargate-service.ts
@@ -1,5 +1,5 @@
 import { Construct } from 'constructs';
-import { SubnetSelection } from '../../../aws-ec2';
+import { ISecurityGroup, SubnetSelection } from '../../../aws-ec2';
 import { FargateService, FargateTaskDefinition } from '../../../aws-ecs';
 import { FeatureFlags } from '../../../core';
 import * as cxapi from '../../../cx-api';
@@ -25,6 +25,12 @@ export interface NetworkLoadBalancedFargateServiceProps extends NetworkLoadBalan
    */
   readonly taskSubnets?: SubnetSelection;
 
+  /**
+   * The security groups to associate with the service. If you do not specify a security group, a new security group is created.
+   *
+   * @default - A new security group is created.
+   */
+  readonly securityGroups?: ISecurityGroup[];
 }
 
 /**
@@ -102,6 +108,7 @@ export class NetworkLoadBalancedFargateService extends NetworkLoadBalancedServic
       platformVersion: props.platformVersion,
       deploymentController: props.deploymentController,
       circuitBreaker: props.circuitBreaker,
+      securityGroups: props.securityGroups,
       vpcSubnets: props.taskSubnets,
       enableExecuteCommand: props.enableExecuteCommand,
       capacityProviderStrategies: props.capacityProviderStrategies,
diff --git a/packages/aws-cdk-lib/aws-ecs-patterns/test/fargate/load-balanced-fargate-service.test.ts b/packages/aws-cdk-lib/aws-ecs-patterns/test/fargate/load-balanced-fargate-service.test.ts
index 5092f257a96fb..18b6b929f76f6 100644
--- a/packages/aws-cdk-lib/aws-ecs-patterns/test/fargate/load-balanced-fargate-service.test.ts
+++ b/packages/aws-cdk-lib/aws-ecs-patterns/test/fargate/load-balanced-fargate-service.test.ts
@@ -2022,4 +2022,48 @@ describe('NetworkLoadBalancedFargateService', () => {
       },
     });
   });
+
+  test('specify security group', () => {
+    // GIVEN
+    const stack = new cdk.Stack();
+    const vpc = new ec2.Vpc(stack, 'Vpc');
+    const cluster = new ecs.Cluster(stack, 'Cluster', { vpc, clusterName: 'MyCluster' });
+    const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup', {
+      allowAllOutbound: false,
+      description: 'Example',
+      securityGroupName: 'Rolly',
+      vpc,
+    });
+
+    // WHEN
+    new ecsPatterns.NetworkLoadBalancedFargateService(stack, 'Service', {
+      cluster,
+      taskImageOptions: {
+        image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
+      },
+      securityGroups: [securityGroup],
+    });
+
+    // THEN
+    Template.fromStack(stack).hasResourceProperties('AWS::ECS::Service', {
+      LaunchType: 'FARGATE',
+    });
+
+    Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', {
+      GroupDescription: 'Example',
+      GroupName: 'Rolly',
+      SecurityGroupEgress: [
+        {
+          CidrIp: '255.255.255.255/32',
+          Description: 'Disallow all traffic',
+          FromPort: 252,
+          IpProtocol: 'icmp',
+          ToPort: 86,
+        },
+      ],
+      VpcId: {
+        Ref: 'Vpc8378EB38',
+      },
+    });
+  });
 });

From 4582ac5c9e2cd9c7de289be06682ecd5b813b26a Mon Sep 17 00:00:00 2001
From: Jimmy Gaussen <jimmy.gaussen@gmail.com>
Date: Wed, 13 Mar 2024 18:50:28 +0100
Subject: [PATCH 2/4] chore(msk-alpha): update KafkaVersion (#29440)

### Issue # (if applicable)

Could not find any in the backlog

### Reason for this change

Update the CDK listed Kafka versions to match the current availability,
as well as add missing deprecated versions

### Description of changes

* Added latest version
* `3.6.0` also supports tiered storage, see
[docs](https://docs.aws.amazon.com/msk/latest/developerguide/msk-tiered-storage.html#msk-tiered-storage-requirements).
I replaced the prefix check with a list of supported versions, as I'm
not sure if say every reason after 3.6.0 will support it, and the
`.tiered` prefix isn't consistently applied anymore
* Added two unlisted, deprecated versions, as they are still returned by
the SDK. The goal is to remove any differences between the SDK and the
CDK to ease future automation

### Description of how you validated changes

I compared the current CDK versions to live SDK data, using the
`kafka:ListKafkaVersions` API results.

### 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*

---------

Co-authored-by: GZ <yuanhaoz@amazon.com>
---
 packages/@aws-cdk/aws-msk-alpha/README.md     |  5 +--
 .../aws-msk-alpha/lib/cluster-version.ts      | 35 ++++++++++++++++++-
 .../aws-msk-alpha/test/cluster.test.ts        |  8 ++++-
 3 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/packages/@aws-cdk/aws-msk-alpha/README.md b/packages/@aws-cdk/aws-msk-alpha/README.md
index 81b74be3aa279..8155f8829a756 100644
--- a/packages/@aws-cdk/aws-msk-alpha/README.md
+++ b/packages/@aws-cdk/aws-msk-alpha/README.md
@@ -217,7 +217,8 @@ You can configure an MSK cluster storage mode using the `storageMode` property.
 Tiered storage is a low-cost storage tier for Amazon MSK that scales to virtually unlimited storage,
 making it cost-effective to build streaming data applications.
 
-> Visit [Tiered storage](https://docs.aws.amazon.com/msk/latest/developerguide/msk-tiered-storage.html) for more details.
+> Visit [Tiered storage](https://docs.aws.amazon.com/msk/latest/developerguide/msk-tiered-storage.html)
+to see the list of compatible Kafka versions and for more details.
 
 ```ts
 declare const vpc: ec2.Vpc;
@@ -225,7 +226,7 @@ declare const bucket: s3.IBucket;
 
 const cluster = new msk.Cluster(this, 'cluster', {
   clusterName: 'myCluster',
-  kafkaVersion: msk.KafkaVersion.V2_8_2_TIERED,
+  kafkaVersion: msk.KafkaVersion.V3_6_0,
   vpc,
   storageMode: msk.StorageMode.TIERED,
 });
diff --git a/packages/@aws-cdk/aws-msk-alpha/lib/cluster-version.ts b/packages/@aws-cdk/aws-msk-alpha/lib/cluster-version.ts
index 405c0c6ee0ecc..b3c5277018b1c 100644
--- a/packages/@aws-cdk/aws-msk-alpha/lib/cluster-version.ts
+++ b/packages/@aws-cdk/aws-msk-alpha/lib/cluster-version.ts
@@ -11,6 +11,15 @@ export class KafkaVersion {
    */
   public static readonly V1_1_1 = KafkaVersion.of('1.1.1');
 
+  /**
+   * **Deprecated by Amazon MSK. You can't create a Kafka cluster with a deprecated version.**
+   *
+   * Kafka version 2.1.0
+   *
+   * @deprecated use the latest runtime instead
+   */
+  public static readonly V2_1_0 = KafkaVersion.of('2.1.0');
+
   /**
    * Kafka version 2.2.1
    */
@@ -21,6 +30,15 @@ export class KafkaVersion {
    */
   public static readonly V2_3_1 = KafkaVersion.of('2.3.1');
 
+  /**
+   * **Deprecated by Amazon MSK. You can't create a Kafka cluster with a deprecated version.**
+   *
+   * Kafka version 2.4.1
+   *
+   * @deprecated use the latest runtime instead
+   */
+  public static readonly V2_4_1 = KafkaVersion.of('2.4.1');
+
   /**
    * Kafka version 2.4.1
    */
@@ -111,6 +129,11 @@ export class KafkaVersion {
    */
   public static readonly V3_5_1 = KafkaVersion.of('3.5.1');
 
+  /**
+   * Kafka version 3.6.0
+   */
+  public static readonly V3_6_0 = KafkaVersion.of('3.6.0');
+
   /**
    * Custom cluster version
    * @param version custom version number
@@ -119,6 +142,16 @@ export class KafkaVersion {
     return new KafkaVersion(version);
   }
 
+  /**
+   * List of Kafka versions that support tiered storage
+   *
+   * @see https://docs.aws.amazon.com/msk/latest/developerguide/msk-tiered-storage.html#msk-tiered-storage-requirements
+   */
+  private static readonly TIERED_STORAGE_COMPATIBLE_VERSIONS = [
+    KafkaVersion.V2_8_2_TIERED,
+    KafkaVersion.V3_6_0,
+  ].map(({ version }) => version);
+
   /**
    *
    * @param version cluster version number
@@ -129,6 +162,6 @@ export class KafkaVersion {
    * Checks if the cluster version supports tiered storage mode.
    */
   public isTieredStorageCompatible() {
-    return this.version.endsWith('.tiered');
+    return KafkaVersion.TIERED_STORAGE_COMPATIBLE_VERSIONS.includes(this.version);
   };
 }
diff --git a/packages/@aws-cdk/aws-msk-alpha/test/cluster.test.ts b/packages/@aws-cdk/aws-msk-alpha/test/cluster.test.ts
index babbb235b40a3..7c4bd6a10f4ec 100644
--- a/packages/@aws-cdk/aws-msk-alpha/test/cluster.test.ts
+++ b/packages/@aws-cdk/aws-msk-alpha/test/cluster.test.ts
@@ -790,6 +790,12 @@ describe('MSK Cluster', () => {
 
   describe('created with storage mode', () => {
     describe('with tiered storage mode', () => {
+      test('version.isTieredStorageCompatible', () => {
+        expect(msk.KafkaVersion.V2_8_2_TIERED.isTieredStorageCompatible()).toBeTruthy();
+        expect(msk.KafkaVersion.V3_5_1.isTieredStorageCompatible()).toBeFalsy();
+        expect(msk.KafkaVersion.V3_6_0.isTieredStorageCompatible()).toBeTruthy();
+      });
+
       test('create a cluster with tiered storage mode', () => {
         new msk.Cluster(stack, 'Cluster', {
           clusterName: 'cluster',
@@ -797,7 +803,7 @@ describe('MSK Cluster', () => {
           kafkaVersion: msk.KafkaVersion.V2_8_2_TIERED,
           vpc,
           storageMode: msk.StorageMode.TIERED,
-        }),
+        });
         Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', {
           StorageMode: 'TIERED',
         });

From 135b5208dce849f49b6f540f7199ece057a7ef22 Mon Sep 17 00:00:00 2001
From: Calvin Combs <66279577+comcalvi@users.noreply.github.com>
Date: Wed, 13 Mar 2024 13:20:12 -0700
Subject: [PATCH 3/4] feat(CLI): improved nested stack diff (#29172)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

### Issue # (if applicable)


### Reason for this change

The existing nested stack diff places a fake property, `NestedTemplate`, in the templates to be diffed. This prevents displaying resource replacement information in the diff, like we do for top level stacks. This PR does *not* add changeset replacement information from changesets, but it does add replacement information from the spec.

### Description of changes

Reworked nested stack diff to treat nested stacks as top level stacks. This improves the visual UX and sets us up for using changesets with nested stacks.

#### Before

<img width="957" alt="Screenshot 2024-02-19 at 1 47 59 PM" src="https://github.com/aws/aws-cdk/assets/66279577/a94275c4-e7c3-4d2c-a924-ee61c36bea4d">


#### After
<img width="957" alt="Screenshot 2024-02-19 at 1 48 48 PM" src="https://github.com/aws/aws-cdk/assets/66279577/5263aaf9-ef2f-4228-b413-81e780c4b8f8">



### Description of how you validated changes

Unit tests + manual tests.

### 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*
---
 .../cloudformation-diff/lib/diff-template.ts  |   6 +-
 .../cloudformation-diff/lib/format.ts         |   8 +-
 packages/aws-cdk/lib/api/deployments.ts       |  10 +-
 .../api/evaluate-cloudformation-template.ts   |  34 +-
 .../aws-cdk/lib/api/hotswap-deployments.ts    |  22 +-
 .../aws-cdk/lib/api/nested-stack-helpers.ts   |  85 ++--
 packages/aws-cdk/lib/cdk-toolkit.ts           |  16 +-
 packages/aws-cdk/lib/diff.ts                  |  35 +-
 .../api/cloudformation-deployments.test.ts    | 381 ++++++++++--------
 .../api/hotswap/nested-stacks-hotswap.test.ts | 251 ++++++------
 packages/aws-cdk/test/diff.test.ts            | 357 +++++++++++++---
 ...with-two-nested-stacks-stack.template.json |   7 +-
 ...mbda-two-stacks-stack.nested.template.json |   4 +-
 packages/aws-cdk/test/util.ts                 |   4 +-
 14 files changed, 757 insertions(+), 463 deletions(-)

diff --git a/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts b/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts
index 1902d757f486d..284bb3a8d5f46 100644
--- a/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts
+++ b/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts
@@ -54,7 +54,7 @@ export function fullDiff(
   normalize(newTemplate);
   const theDiff = diffTemplate(currentTemplate, newTemplate);
   if (changeSet) {
-    filterFalsePositivies(theDiff, changeSet);
+    filterFalsePositives(theDiff, changeSet);
     addImportInformation(theDiff, changeSet);
   }
   if (isImport) {
@@ -64,7 +64,7 @@ export function fullDiff(
   return theDiff;
 }
 
-function diffTemplate(
+export function diffTemplate(
   currentTemplate: { [key: string]: any },
   newTemplate: { [key: string]: any },
 ): types.TemplateDiff {
@@ -235,7 +235,7 @@ function addImportInformation(diff: types.TemplateDiff, changeSet?: CloudFormati
   }
 }
 
-function filterFalsePositivies(diff: types.TemplateDiff, changeSet: CloudFormation.DescribeChangeSetOutput) {
+function filterFalsePositives(diff: types.TemplateDiff, changeSet: CloudFormation.DescribeChangeSetOutput) {
   const replacements = findResourceReplacements(changeSet);
   diff.resources.forEachDifference((logicalId: string, change: types.ResourceDifference) => {
     if (change.resourceType.includes('AWS::Serverless')) {
diff --git a/packages/@aws-cdk/cloudformation-diff/lib/format.ts b/packages/@aws-cdk/cloudformation-diff/lib/format.ts
index 7935f774fd468..724af468c2f45 100644
--- a/packages/@aws-cdk/cloudformation-diff/lib/format.ts
+++ b/packages/@aws-cdk/cloudformation-diff/lib/format.ts
@@ -30,7 +30,7 @@ export interface FormatStream extends NodeJS.WritableStream {
 export function formatDifferences(
   stream: FormatStream,
   templateDiff: TemplateDiff,
-  logicalToPathMap: { [logicalId: string]: string } = { },
+  logicalToPathMap: { [logicalId: string]: string } = {},
   context: number = 3) {
   const formatter = new Formatter(stream, logicalToPathMap, templateDiff, context);
 
@@ -59,7 +59,7 @@ export function formatDifferences(
 export function formatSecurityChanges(
   stream: NodeJS.WritableStream,
   templateDiff: TemplateDiff,
-  logicalToPathMap: {[logicalId: string]: string} = {},
+  logicalToPathMap: { [logicalId: string]: string } = {},
   context?: number) {
   const formatter = new Formatter(stream, logicalToPathMap, templateDiff, context);
 
@@ -254,7 +254,7 @@ class Formatter {
           const oldStr = JSON.stringify(oldObject, null, 2);
           const newStr = JSON.stringify(newObject, null, 2);
           const diff = _diffStrings(oldStr, newStr, this.context);
-          for (let i = 0 ; i < diff.length ; i++) {
+          for (let i = 0; i < diff.length; i++) {
             this.print('%s   %s %s', linePrefix, i === 0 ? '└─' : '  ', diff[i]);
           }
         } else {
@@ -466,7 +466,7 @@ function _diffStrings(oldStr: string, newStr: string, context: number): string[]
   function _findIndent(lines: string[]): number {
     let indent = Number.MAX_SAFE_INTEGER;
     for (const line of lines) {
-      for (let i = 1 ; i < line.length ; i++) {
+      for (let i = 1; i < line.length; i++) {
         if (line.charAt(i) !== ' ') {
           indent = indent > i - 1 ? i - 1 : indent;
           break;
diff --git a/packages/aws-cdk/lib/api/deployments.ts b/packages/aws-cdk/lib/api/deployments.ts
index 925cdebd45e15..b7bea90c56c28 100644
--- a/packages/aws-cdk/lib/api/deployments.ts
+++ b/packages/aws-cdk/lib/api/deployments.ts
@@ -7,7 +7,7 @@ import { CredentialsOptions, SdkForEnvironment, SdkProvider } from './aws-auth/s
 import { deployStack, DeployStackResult, destroyStack, DeploymentMethod } from './deploy-stack';
 import { EnvironmentResources, EnvironmentResourcesRegistry } from './environment-resources';
 import { HotswapMode } from './hotswap/common';
-import { loadCurrentTemplateWithNestedStacks, loadCurrentTemplate, flattenNestedStackNames, TemplateWithNestedStackCount } from './nested-stack-helpers';
+import { loadCurrentTemplateWithNestedStacks, loadCurrentTemplate, RootTemplateWithNestedStacks } from './nested-stack-helpers';
 import { CloudFormationStack, Template, ResourcesToImport, ResourceIdentifierSummaries } from './util/cloudformation';
 import { StackActivityProgress } from './util/cloudformation/stack-activity-monitor';
 import { replaceEnvPlaceholders } from './util/placeholders';
@@ -327,13 +327,9 @@ export class Deployments {
   public async readCurrentTemplateWithNestedStacks(
     rootStackArtifact: cxapi.CloudFormationStackArtifact,
     retrieveProcessedTemplate: boolean = false,
-  ): Promise<TemplateWithNestedStackCount> {
+  ): Promise<RootTemplateWithNestedStacks> {
     const sdk = (await this.prepareSdkWithLookupOrDeployRole(rootStackArtifact)).stackSdk;
-    const templateWithNestedStacks = await loadCurrentTemplateWithNestedStacks(rootStackArtifact, sdk, retrieveProcessedTemplate);
-    return {
-      deployedTemplate: templateWithNestedStacks.deployedTemplate,
-      nestedStackCount: flattenNestedStackNames(templateWithNestedStacks.nestedStackNames).length,
-    };
+    return loadCurrentTemplateWithNestedStacks(rootStackArtifact, sdk, retrieveProcessedTemplate);
   }
 
   public async readCurrentTemplate(stackArtifact: cxapi.CloudFormationStackArtifact): Promise<Template> {
diff --git a/packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts b/packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts
index 329bf2ec9ba59..5a1cc675bff85 100644
--- a/packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts
+++ b/packages/aws-cdk/lib/api/evaluate-cloudformation-template.ts
@@ -1,7 +1,7 @@
 import * as AWS from 'aws-sdk';
 import { PromiseResult } from 'aws-sdk/lib/request';
 import { ISDK } from './aws-auth';
-import { NestedStackNames } from './nested-stack-helpers';
+import { NestedStackTemplates } from './nested-stack-helpers';
 
 export interface ListStackResources {
   listStackResources(): Promise<AWS.CloudFormation.StackResourceSummary[]>;
@@ -102,7 +102,7 @@ export interface EvaluateCloudFormationTemplateProps {
   readonly partition: string;
   readonly urlSuffix: (region: string) => string;
   readonly sdk: ISDK;
-  readonly nestedStackNames?: { [nestedStackLogicalId: string]: NestedStackNames };
+  readonly nestedStacks?: { [nestedStackLogicalId: string]: NestedStackTemplates };
 }
 
 export class EvaluateCloudFormationTemplate {
@@ -114,7 +114,7 @@ export class EvaluateCloudFormationTemplate {
   private readonly partition: string;
   private readonly urlSuffix: (region: string) => string;
   private readonly sdk: ISDK;
-  private readonly nestedStackNames: { [nestedStackLogicalId: string]: NestedStackNames };
+  private readonly nestedStacks: { [nestedStackLogicalId: string]: NestedStackTemplates };
   private readonly stackResources: ListStackResources;
   private readonly lookupExport: LookupExport;
 
@@ -136,7 +136,7 @@ export class EvaluateCloudFormationTemplate {
     this.sdk = props.sdk;
 
     // We need names of nested stack so we can evaluate cross stack references
-    this.nestedStackNames = props.nestedStackNames ?? {};
+    this.nestedStacks = props.nestedStacks ?? {};
 
     // The current resources of the Stack.
     // We need them to figure out the physical name of a resource in case it wasn't specified by the user.
@@ -163,7 +163,7 @@ export class EvaluateCloudFormationTemplate {
       partition: this.partition,
       urlSuffix: this.urlSuffix,
       sdk: this.sdk,
-      nestedStackNames: this.nestedStackNames,
+      nestedStacks: this.nestedStacks,
     });
   }
 
@@ -386,17 +386,15 @@ export class EvaluateCloudFormationTemplate {
     }
 
     if (foundResource.ResourceType == 'AWS::CloudFormation::Stack' && attribute?.startsWith('Outputs.')) {
-      // need to resolve attributes from another stack's Output section
-      const dependantStackName = this.findNestedStack(logicalId, this.nestedStackNames);
-      if (!dependantStackName) {
+      const dependantStack = this.findNestedStack(logicalId, this.nestedStacks);
+      if (!dependantStack || !dependantStack.physicalName) {
         //this is a newly created nested stack and cannot be hotswapped
         return undefined;
       }
-      const dependantStackTemplate = this.template.Resources[logicalId];
       const evaluateCfnTemplate = await this.createNestedEvaluateCloudFormationTemplate(
-        dependantStackName,
-        dependantStackTemplate?.Properties?.NestedTemplate,
-        dependantStackTemplate.newValue?.Properties?.Parameters);
+        dependantStack.physicalName,
+        dependantStack.generatedTemplate,
+        dependantStack.generatedTemplate.Parameters!);
 
       // Split Outputs.<refName> into 'Outputs' and '<refName>' and recursively call evaluate
       return evaluateCfnTemplate.evaluateCfnExpression({ 'Fn::GetAtt': attribute.split(/\.(.*)/s) });
@@ -406,14 +404,14 @@ export class EvaluateCloudFormationTemplate {
     return this.formatResourceAttribute(foundResource, attribute);
   }
 
-  private findNestedStack(logicalId: string, nestedStackNames: {
-    [nestedStackLogicalId: string]: NestedStackNames;
-  }): string | undefined {
-    for (const [nestedStackLogicalId, { nestedChildStackNames, nestedStackPhysicalName }] of Object.entries(nestedStackNames)) {
+  private findNestedStack(logicalId: string, nestedStacks: {
+    [nestedStackLogicalId: string]: NestedStackTemplates;
+  }): NestedStackTemplates | undefined {
+    for (const nestedStackLogicalId of Object.keys(nestedStacks)) {
       if (nestedStackLogicalId === logicalId) {
-        return nestedStackPhysicalName;
+        return nestedStacks[nestedStackLogicalId];
       }
-      const checkInNestedChildStacks = this.findNestedStack(logicalId, nestedChildStackNames);
+      const checkInNestedChildStacks = this.findNestedStack(logicalId, nestedStacks[nestedStackLogicalId].nestedStackTemplates);
       if (checkInNestedChildStacks) return checkInNestedChildStacks;
     }
     return undefined;
diff --git a/packages/aws-cdk/lib/api/hotswap-deployments.ts b/packages/aws-cdk/lib/api/hotswap-deployments.ts
index 51404d624b92e..efebb414d6f92 100644
--- a/packages/aws-cdk/lib/api/hotswap-deployments.ts
+++ b/packages/aws-cdk/lib/api/hotswap-deployments.ts
@@ -11,7 +11,7 @@ import { isHotswappableEcsServiceChange } from './hotswap/ecs-services';
 import { isHotswappableLambdaFunctionChange } from './hotswap/lambda-functions';
 import { skipChangeForS3DeployCustomResourcePolicy, isHotswappableS3BucketDeploymentChange } from './hotswap/s3-bucket-deployments';
 import { isHotswappableStateMachineChange } from './hotswap/stepfunctions-state-machines';
-import { loadCurrentTemplateWithNestedStacks, NestedStackNames } from './nested-stack-helpers';
+import { NestedStackTemplates, loadCurrentTemplateWithNestedStacks } from './nested-stack-helpers';
 import { CloudFormationStack } from './util/cloudformation';
 import { print } from '../logging';
 
@@ -78,12 +78,12 @@ export async function tryHotswapDeployment(
     partition: (await sdk.currentAccount()).partition,
     urlSuffix: (region) => sdk.getEndpointSuffix(region),
     sdk,
-    nestedStackNames: currentTemplate.nestedStackNames,
+    nestedStacks: currentTemplate.nestedStacks,
   });
 
-  const stackChanges = cfn_diff.fullDiff(currentTemplate.deployedTemplate, stackArtifact.template);
+  const stackChanges = cfn_diff.fullDiff(currentTemplate.deployedRootTemplate, stackArtifact.template);
   const { hotswappableChanges, nonHotswappableChanges } = await classifyResourceChanges(
-    stackChanges, evaluateCfnTemplate, sdk, currentTemplate.nestedStackNames,
+    stackChanges, evaluateCfnTemplate, sdk, currentTemplate.nestedStacks,
   );
 
   logNonHotswappableChanges(nonHotswappableChanges, hotswapMode);
@@ -109,7 +109,7 @@ async function classifyResourceChanges(
   stackChanges: cfn_diff.TemplateDiff,
   evaluateCfnTemplate: EvaluateCloudFormationTemplate,
   sdk: ISDK,
-  nestedStackNames: { [nestedStackName: string]: NestedStackNames },
+  nestedStackNames: { [nestedStackName: string]: NestedStackTemplates },
 ): Promise<ClassifiedResourceChanges> {
   const resourceDifferences = getStackResourceDifferences(stackChanges);
 
@@ -225,12 +225,12 @@ function filterDict<T>(dict: { [key: string]: T }, func: (t: T) => boolean): { [
 async function findNestedHotswappableChanges(
   logicalId: string,
   change: cfn_diff.ResourceDifference,
-  nestedStackNames: { [nestedStackName: string]: NestedStackNames },
+  nestedStackTemplates: { [nestedStackName: string]: NestedStackTemplates },
   evaluateCfnTemplate: EvaluateCloudFormationTemplate,
   sdk: ISDK,
 ): Promise<ClassifiedResourceChanges> {
-  const nestedStackName = nestedStackNames[logicalId].nestedStackPhysicalName;
-  if (!nestedStackName) {
+  const nestedStack = nestedStackTemplates[logicalId];
+  if (!nestedStack.physicalName) {
     return {
       hotswappableChanges: [],
       nonHotswappableChanges: [{
@@ -244,14 +244,14 @@ async function findNestedHotswappableChanges(
   }
 
   const evaluateNestedCfnTemplate = await evaluateCfnTemplate.createNestedEvaluateCloudFormationTemplate(
-    nestedStackName, change.newValue?.Properties?.NestedTemplate, change.newValue?.Properties?.Parameters,
+    nestedStack.physicalName, nestedStack.generatedTemplate, change.newValue?.Properties?.Parameters,
   );
 
   const nestedDiff = cfn_diff.fullDiff(
-    change.oldValue?.Properties?.NestedTemplate, change.newValue?.Properties?.NestedTemplate,
+    nestedStackTemplates[logicalId].deployedTemplate, nestedStackTemplates[logicalId].generatedTemplate,
   );
 
-  return classifyResourceChanges(nestedDiff, evaluateNestedCfnTemplate, sdk, nestedStackNames[logicalId].nestedChildStackNames);
+  return classifyResourceChanges(nestedDiff, evaluateNestedCfnTemplate, sdk, nestedStackTemplates[logicalId].nestedStackTemplates);
 }
 
 /** Returns 'true' if a pair of changes is for the same resource. */
diff --git a/packages/aws-cdk/lib/api/nested-stack-helpers.ts b/packages/aws-cdk/lib/api/nested-stack-helpers.ts
index acbbb1e2a9245..3242794aa1039 100644
--- a/packages/aws-cdk/lib/api/nested-stack-helpers.ts
+++ b/packages/aws-cdk/lib/api/nested-stack-helpers.ts
@@ -5,59 +5,38 @@ import { ISDK } from './aws-auth';
 import { LazyListStackResources, ListStackResources } from './evaluate-cloudformation-template';
 import { CloudFormationStack, Template } from './util/cloudformation';
 
-export interface TemplateWithNestedStackNames {
+export interface NestedStackTemplates {
+  readonly physicalName: string | undefined;
   readonly deployedTemplate: Template;
-  readonly nestedStackNames: { [nestedStackLogicalId: string]: NestedStackNames };
+  readonly generatedTemplate: Template;
+  readonly nestedStackTemplates: { [nestedStackLogicalId: string]: NestedStackTemplates};
 }
 
-export interface NestedStackNames {
-  readonly nestedStackPhysicalName: string | undefined;
-  readonly nestedChildStackNames: { [logicalId: string]: NestedStackNames };
-}
-
-export interface TemplateWithNestedStackCount {
-  readonly deployedTemplate: Template;
-  readonly nestedStackCount: number;
+export interface RootTemplateWithNestedStacks {
+  readonly deployedRootTemplate: Template;
+  readonly nestedStacks: { [nestedStackLogicalId: string]: NestedStackTemplates };
 }
 
 /**
- * Reads the currently deployed template from CloudFormation and adds a
- * property, `NestedTemplate`, to any nested stacks that appear in either
- * the deployed template or the newly synthesized template. `NestedTemplate`
- * is populated with contents of the nested template by mutating the
- * `template` property of `rootStackArtifact`. This is done for all
- * nested stack resources to arbitrary depths.
+ * Reads the currently deployed template and all of its nested stack templates from CloudFormation.
  */
 export async function loadCurrentTemplateWithNestedStacks(
   rootStackArtifact: cxapi.CloudFormationStackArtifact, sdk: ISDK,
   retrieveProcessedTemplate: boolean = false,
-): Promise<TemplateWithNestedStackNames> {
-  const deployedTemplate = await loadCurrentTemplate(rootStackArtifact, sdk, retrieveProcessedTemplate);
-  const nestedStackNames = await addNestedTemplatesToGeneratedAndDeployedStacks(rootStackArtifact, sdk, {
+): Promise<RootTemplateWithNestedStacks> {
+  const deployedRootTemplate = await loadCurrentTemplate(rootStackArtifact, sdk, retrieveProcessedTemplate);
+  const nestedStacks = await loadNestedStacks(rootStackArtifact, sdk, {
     generatedTemplate: rootStackArtifact.template,
-    deployedTemplate: deployedTemplate,
+    deployedTemplate: deployedRootTemplate,
     deployedStackName: rootStackArtifact.stackName,
   });
 
   return {
-    deployedTemplate,
-    nestedStackNames,
+    deployedRootTemplate,
+    nestedStacks,
   };
 }
 
-export function flattenNestedStackNames(nestedStackNames: { [nestedStackLogicalId: string]: NestedStackNames }): string[] {
-  const nameList = [];
-  for (const key of Object.keys(nestedStackNames)) {
-    nameList.push(key);
-
-    if (Object.keys(nestedStackNames[key].nestedChildStackNames).length !== 0) {
-      flattenNestedStacksHelper(nestedStackNames[key].nestedChildStackNames, nameList);
-    }
-  }
-
-  return nameList;
-}
-
 /**
  * Returns the currently deployed template from CloudFormation that corresponds to `stackArtifact`.
  */
@@ -76,13 +55,13 @@ async function loadCurrentStackTemplate(
   return stack.template();
 }
 
-async function addNestedTemplatesToGeneratedAndDeployedStacks(
+async function loadNestedStacks(
   rootStackArtifact: cxapi.CloudFormationStackArtifact,
   sdk: ISDK,
   parentTemplates: StackTemplates,
-): Promise<{ [nestedStackLogicalId: string]: NestedStackNames }> {
+): Promise<{ [nestedStackLogicalId: string]: NestedStackTemplates }> {
   const listStackResources = parentTemplates.deployedStackName ? new LazyListStackResources(sdk, parentTemplates.deployedStackName) : undefined;
-  const nestedStackNames: { [nestedStackLogicalId: string]: NestedStackNames } = {};
+  const nestedStacks: { [nestedStackLogicalId: string]: NestedStackTemplates } = {};
   for (const [nestedStackLogicalId, generatedNestedStackResource] of Object.entries(parentTemplates.generatedTemplate.Resources ?? {})) {
     if (!isCdkManagedNestedStack(generatedNestedStackResource)) {
       continue;
@@ -91,19 +70,11 @@ async function addNestedTemplatesToGeneratedAndDeployedStacks(
     const assetPath = generatedNestedStackResource.Metadata['aws:asset:path'];
     const nestedStackTemplates = await getNestedStackTemplates(rootStackArtifact, assetPath, nestedStackLogicalId, listStackResources, sdk);
 
-    generatedNestedStackResource.Properties.NestedTemplate = nestedStackTemplates.generatedTemplate;
-
-    const deployedParentTemplate = parentTemplates.deployedTemplate;
-    deployedParentTemplate.Resources = deployedParentTemplate.Resources ?? {};
-    const deployedNestedStackResource = deployedParentTemplate.Resources[nestedStackLogicalId] ?? {};
-    deployedParentTemplate.Resources[nestedStackLogicalId] = deployedNestedStackResource;
-    deployedNestedStackResource.Type = deployedNestedStackResource.Type ?? 'AWS::CloudFormation::Stack';
-    deployedNestedStackResource.Properties = deployedNestedStackResource.Properties ?? {};
-    deployedNestedStackResource.Properties.NestedTemplate = nestedStackTemplates.deployedTemplate;
-
-    nestedStackNames[nestedStackLogicalId] = {
-      nestedStackPhysicalName: nestedStackTemplates.deployedStackName,
-      nestedChildStackNames: await addNestedTemplatesToGeneratedAndDeployedStacks(
+    nestedStacks[nestedStackLogicalId] = {
+      deployedTemplate: nestedStackTemplates.deployedTemplate,
+      generatedTemplate: nestedStackTemplates.generatedTemplate,
+      physicalName: nestedStackTemplates.deployedStackName,
+      nestedStackTemplates: await loadNestedStacks(
         rootStackArtifact,
         sdk,
         nestedStackTemplates,
@@ -111,7 +82,7 @@ async function addNestedTemplatesToGeneratedAndDeployedStacks(
     };
   }
 
-  return nestedStackNames;
+  return nestedStacks;
 }
 
 async function getNestedStackTemplates(
@@ -153,16 +124,6 @@ function isCdkManagedNestedStack(stackResource: any): stackResource is NestedSta
   return stackResource.Type === 'AWS::CloudFormation::Stack' && stackResource.Metadata && stackResource.Metadata['aws:asset:path'];
 }
 
-function flattenNestedStacksHelper(nestedStackNames: { [logicalId: string]: NestedStackNames }, nameList: string[]) {
-  for (const key of Object.keys(nestedStackNames)) {
-    nameList.push(key);
-
-    if (Object.keys(nestedStackNames[key].nestedChildStackNames).length !== 0) {
-      flattenNestedStacksHelper(nestedStackNames[key].nestedChildStackNames, nameList);
-    }
-  }
-}
-
 interface StackTemplates {
   readonly generatedTemplate: any;
   readonly deployedTemplate: any;
diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts
index c67b02dbc9cf2..05aeee002c068 100644
--- a/packages/aws-cdk/lib/cdk-toolkit.ts
+++ b/packages/aws-cdk/lib/cdk-toolkit.ts
@@ -156,7 +156,7 @@ export class CdkToolkit {
       const template = deserializeStructure(await fs.readFile(options.templatePath, { encoding: 'UTF-8' }));
       diffs = options.securityOnly
         ? numberFromBool(printSecurityDiff(template, stacks.firstStack, RequireApproval.Broadening, changeSet))
-        : printStackDiff(template, stacks.firstStack, strict, contextLines, quiet, changeSet, stream);
+        : printStackDiff(template, stacks.firstStack.template, strict, contextLines, quiet, changeSet, stream);
     } else {
       // Compare N stacks against deployed templates
       for (const stack of stacks.stackArtifacts) {
@@ -164,11 +164,11 @@ export class CdkToolkit {
           stream.write(format('Stack %s\n', chalk.bold(stack.displayName)));
         }
 
-        const templateWithNames = await this.props.deployments.readCurrentTemplateWithNestedStacks(
+        const templateWithNestedStacks = await this.props.deployments.readCurrentTemplateWithNestedStacks(
           stack, options.compareAgainstProcessedTemplate,
         );
-        const currentTemplate = templateWithNames.deployedTemplate;
-        const nestedStackCount = templateWithNames.nestedStackCount;
+        const currentTemplate = templateWithNestedStacks.deployedRootTemplate;
+        const nestedStacks = templateWithNestedStacks.nestedStacks;
 
         const resourcesToImport = await this.tryGetResources(await this.props.deployments.resolveEnvironment(stack));
         if (resourcesToImport) {
@@ -203,10 +203,10 @@ export class CdkToolkit {
         // pass a boolean to print if the stack is a migrate stack in order to set all resource diffs to import
         const stackCount =
         options.securityOnly
-          ? (numberFromBool(printSecurityDiff(currentTemplate, stack, RequireApproval.Broadening, changeSet)) > 0 ? 1 : 0)
-          : (printStackDiff(currentTemplate, stack, strict, contextLines, quiet, changeSet, stream, !!resourcesToImport) > 0 ? 1 : 0);
+          ? (numberFromBool(printSecurityDiff(currentTemplate, stack, RequireApproval.Broadening, changeSet)))
+          : (printStackDiff(currentTemplate, stack, strict, contextLines, quiet, changeSet, stream, nestedStacks, !!resourcesToImport));
 
-        diffs += stackCount + nestedStackCount;
+        diffs += stackCount;
       }
     }
 
@@ -1531,4 +1531,4 @@ function buildParameterMap(parameters: {
   }
 
   return parameterMap;
-}
\ No newline at end of file
+}
diff --git a/packages/aws-cdk/lib/diff.ts b/packages/aws-cdk/lib/diff.ts
index fa897430ad37b..b49f288fc2534 100644
--- a/packages/aws-cdk/lib/diff.ts
+++ b/packages/aws-cdk/lib/diff.ts
@@ -1,8 +1,10 @@
+import { format } from 'util';
 import * as cxschema from '@aws-cdk/cloud-assembly-schema';
 import * as cfnDiff from '@aws-cdk/cloudformation-diff';
 import * as cxapi from '@aws-cdk/cx-api';
 import { CloudFormation } from 'aws-sdk';
 import * as chalk from 'chalk';
+import { NestedStackTemplates } from './api/nested-stack-helpers';
 import { print, warning } from './logging';
 
 /**
@@ -14,7 +16,7 @@ import { print, warning } from './logging';
  * @param context     lines of context to use in arbitrary JSON diff
  * @param quiet       silences \'There were no differences\' messages
  *
- * @returns the count of differences that were rendered.
+ * @returns the number of stacks in this stack tree that have differences, including the top-level root stack
  */
 export function printStackDiff(
   oldTemplate: any,
@@ -23,7 +25,8 @@ export function printStackDiff(
   context: number,
   quiet: boolean,
   changeSet?: CloudFormation.DescribeChangeSetOutput,
-  stream?: cfnDiff.FormatStream,
+  stream: cfnDiff.FormatStream = process.stderr,
+  nestedStackTemplates?: { [nestedStackLogicalId: string]: NestedStackTemplates },
   isImport?: boolean): number {
 
   let diff = cfnDiff.fullDiff(oldTemplate, newTemplate.template, changeSet, isImport);
@@ -49,8 +52,10 @@ export function printStackDiff(
     });
   }
 
+  let stackDiffCount = 0;
   if (!diff.isEmpty) {
-    cfnDiff.formatDifferences(stream || process.stderr, diff, {
+    stackDiffCount++;
+    cfnDiff.formatDifferences(stream, diff, {
       ...logicalIdMapFromTemplate(oldTemplate),
       ...buildLogicalToPathMap(newTemplate),
     }, context);
@@ -61,7 +66,29 @@ export function printStackDiff(
     print(chalk.yellow(`Omitted ${filteredChangesCount} changes because they are likely mangled non-ASCII characters. Use --strict to print them.`));
   }
 
-  return diff.differenceCount;
+  for (const nestedStackLogicalId of Object.keys(nestedStackTemplates ?? {})) {
+    if (!nestedStackTemplates) {
+      break;
+    }
+    const nestedStack = nestedStackTemplates[nestedStackLogicalId];
+    if (!quiet) {
+      stream.write(format('Stack %s\n', chalk.bold(nestedStack.physicalName ?? nestedStackLogicalId)));
+    }
+
+    (newTemplate as any)._template = nestedStack.generatedTemplate;
+    stackDiffCount += printStackDiff(
+      nestedStack.deployedTemplate,
+      newTemplate,
+      strict,
+      context,
+      quiet,
+      undefined,
+      stream,
+      nestedStack.nestedStackTemplates,
+    );
+  }
+
+  return stackDiffCount;
 }
 
 export enum RequireApproval {
diff --git a/packages/aws-cdk/test/api/cloudformation-deployments.test.ts b/packages/aws-cdk/test/api/cloudformation-deployments.test.ts
index ac1fed6176e1b..cbaf7c3d8746c 100644
--- a/packages/aws-cdk/test/api/cloudformation-deployments.test.ts
+++ b/packages/aws-cdk/test/api/cloudformation-deployments.test.ts
@@ -246,39 +246,16 @@ test('readCurrentTemplateWithNestedStacks() can handle non-Resources in the temp
   );
 
   // WHEN
-  const nestedStackCount = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).nestedStackCount;
-  const deployedTemplate = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).deployedTemplate;
+  const deployedTemplate = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).deployedRootTemplate;
+  const nestedStacks = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).nestedStacks;
 
   // THEN
-  expect(nestedStackCount).toEqual(1);
   expect(deployedTemplate).toEqual({
     Resources: {
       NestedStack: {
         Type: 'AWS::CloudFormation::Stack',
         Properties: {
           TemplateURL: 'https://www.magic-url.com',
-          NestedTemplate: {
-            Resources: {
-              NestedResource: {
-                Type: 'AWS::Something',
-                Properties: {
-                  Property: 'old-value',
-                },
-              },
-            },
-            Outputs: {
-              NestedOutput: {
-                Value: {
-                  Ref: 'NestedResource',
-                },
-              },
-            },
-            Parameters: {
-              NestedParam: {
-                Type: 'String',
-              },
-            },
-          },
         },
         Metadata: {
           'aws:asset:path': 'one-output-one-param-stack.nested.template.json',
@@ -293,33 +270,62 @@ test('readCurrentTemplateWithNestedStacks() can handle non-Resources in the temp
         Type: 'AWS::CloudFormation::Stack',
         Properties: {
           TemplateURL: 'https://www.magic-url.com',
-          NestedTemplate: {
-            Resources: {
-              NestedResource: {
-                Type: 'AWS::Something',
-                Properties: {
-                  Property: 'new-value',
-                },
-              },
+        },
+        Metadata: {
+          'aws:asset:path': 'one-output-one-param-stack.nested.template.json',
+        },
+      },
+    },
+  });
+
+  expect(nestedStacks).toEqual({
+    NestedStack: {
+      deployedTemplate: {
+        Outputs: {
+          NestedOutput: {
+            Value: {
+              Ref: 'NestedResource',
             },
-            Outputs: {
-              NestedOutput: {
-                Value: {
-                  Ref: 'NestedResource',
-                },
-              },
+          },
+        },
+        Parameters: {
+          NestedParam: {
+            Type: 'String',
+          },
+        },
+        Resources: {
+          NestedResource: {
+            Properties: {
+              Property: 'old-value',
             },
-            Parameters: {
-              NestedParam: {
-                Type: 'Number',
-              },
+            Type: 'AWS::Something',
+          },
+        },
+      },
+      generatedTemplate: {
+        Outputs: {
+          NestedOutput: {
+            Value: {
+              Ref: 'NestedResource',
             },
           },
         },
-        Metadata: {
-          'aws:asset:path': 'one-output-one-param-stack.nested.template.json',
+        Parameters: {
+          NestedParam: {
+            Type: 'Number',
+          },
+        },
+        Resources: {
+          NestedResource: {
+            Properties: {
+              Property: 'new-value',
+            },
+            Type: 'AWS::Something',
+          },
         },
       },
+      nestedStackTemplates: {},
+      physicalName: 'NestedStack',
     },
   });
 });
@@ -453,65 +459,16 @@ test('readCurrentTemplateWithNestedStacks() with a 3-level nested + sibling stru
   );
 
   // WHEN
-  const nestedStackCount = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).nestedStackCount;
-  const deployedTemplate = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).deployedTemplate;
+  const deployedTemplate = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).deployedRootTemplate;
+  const nestedStacks = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).nestedStacks;
 
   // THEN
-  expect(nestedStackCount).toEqual(3);
   expect(deployedTemplate).toEqual({
     Resources: {
       NestedStack: {
         Type: 'AWS::CloudFormation::Stack',
         Properties: {
           TemplateURL: 'https://www.magic-url.com',
-          NestedTemplate: {
-            Resources: {
-              GrandChildStackA: {
-                Type: 'AWS::CloudFormation::Stack',
-                Properties: {
-                  TemplateURL: 'https://www.magic-url.com',
-                  NestedTemplate: {
-                    Resources: {
-                      SomeResource: {
-                        Type: 'AWS::Something',
-                        Properties: {
-                          Property: 'old-value',
-                        },
-                      },
-                    },
-                  },
-                },
-                Metadata: {
-                  'aws:asset:path': 'one-resource-stack.nested.template.json',
-                },
-              },
-              GrandChildStackB: {
-                Type: 'AWS::CloudFormation::Stack',
-                Properties: {
-                  TemplateURL: 'https://www.magic-url.com',
-                  NestedTemplate: {
-                    Resources: {
-                      SomeResource: {
-                        Type: 'AWS::Something',
-                        Properties: {
-                          Property: 'old-value',
-                        },
-                      },
-                    },
-                  },
-                },
-                Metadata: {
-                  'aws:asset:path': 'one-resource-stack.nested.template.json',
-                },
-              },
-              SomeResource: {
-                Type: 'AWS::Something',
-                Properties: {
-                  Property: 'old-value',
-                },
-              },
-            },
-          },
         },
         Metadata: {
           'aws:asset:path': 'one-resource-two-stacks-stack.nested.template.json',
@@ -526,59 +483,123 @@ test('readCurrentTemplateWithNestedStacks() with a 3-level nested + sibling stru
         Type: 'AWS::CloudFormation::Stack',
         Properties: {
           TemplateURL: 'https://www.magic-url.com',
-          NestedTemplate: {
+        },
+        Metadata: {
+          'aws:asset:path': 'one-resource-two-stacks-stack.nested.template.json',
+        },
+      },
+    },
+  });
+
+  expect(nestedStacks).toEqual({
+    NestedStack: {
+      deployedTemplate: {
+        Resources: {
+          GrandChildStackA: {
+            Metadata: {
+              'aws:asset:path': 'one-resource-stack.nested.template.json',
+            },
+            Properties: {
+              TemplateURL: 'https://www.magic-url.com',
+            },
+            Type: 'AWS::CloudFormation::Stack',
+          },
+          GrandChildStackB: {
+            Metadata: {
+              'aws:asset:path': 'one-resource-stack.nested.template.json',
+            },
+            Properties: {
+              TemplateURL: 'https://www.magic-url.com',
+            },
+            Type: 'AWS::CloudFormation::Stack',
+          },
+          SomeResource: {
+            Properties: {
+              Property: 'old-value',
+            },
+            Type: 'AWS::Something',
+          },
+        },
+      },
+      generatedTemplate: {
+        Resources: {
+          GrandChildStackA: {
+            Metadata: {
+              'aws:asset:path': 'one-resource-stack.nested.template.json',
+            },
+            Properties: {
+              TemplateURL: 'https://www.magic-url.com',
+            },
+            Type: 'AWS::CloudFormation::Stack',
+          },
+          GrandChildStackB: {
+            Metadata: {
+              'aws:asset:path': 'one-resource-stack.nested.template.json',
+            },
+            Properties: {
+              TemplateURL: 'https://www.magic-url.com',
+            },
+            Type: 'AWS::CloudFormation::Stack',
+          },
+          SomeResource: {
+            Properties: {
+              Property: 'new-value',
+            },
+            Type: 'AWS::Something',
+          },
+        },
+      },
+      nestedStackTemplates: {
+        GrandChildStackA: {
+          deployedTemplate: {
             Resources: {
-              GrandChildStackA: {
-                Type: 'AWS::CloudFormation::Stack',
+              SomeResource: {
                 Properties: {
-                  TemplateURL: 'https://www.magic-url.com',
-                  NestedTemplate: {
-                    Resources: {
-                      SomeResource: {
-                        Type: 'AWS::Something',
-                        Properties: {
-                          Property: 'new-value',
-                        },
-                      },
-                    },
-                  },
-                },
-                Metadata: {
-                  'aws:asset:path': 'one-resource-stack.nested.template.json',
+                  Property: 'old-value',
                 },
+                Type: 'AWS::Something',
               },
-              GrandChildStackB: {
-                Type: 'AWS::CloudFormation::Stack',
+            },
+          },
+          generatedTemplate: {
+            Resources: {
+              SomeResource: {
                 Properties: {
-                  TemplateURL: 'https://www.magic-url.com',
-                  NestedTemplate: {
-                    Resources: {
-                      SomeResource: {
-                        Type: 'AWS::Something',
-                        Properties: {
-                          Property: 'new-value',
-                        },
-                      },
-                    },
-                  },
-                },
-                Metadata: {
-                  'aws:asset:path': 'one-resource-stack.nested.template.json',
+                  Property: 'new-value',
                 },
+                Type: 'AWS::Something',
               },
+            },
+          },
+          nestedStackTemplates: {},
+          physicalName: 'GrandChildStackA',
+        },
+        GrandChildStackB: {
+          deployedTemplate: {
+            Resources: {
               SomeResource: {
+                Properties: {
+                  Property: 'old-value',
+                },
                 Type: 'AWS::Something',
+              },
+            },
+          },
+          generatedTemplate: {
+            Resources: {
+              SomeResource: {
                 Properties: {
                   Property: 'new-value',
                 },
+                Type: 'AWS::Something',
               },
             },
           },
-        },
-        Metadata: {
-          'aws:asset:path': 'one-resource-two-stacks-stack.nested.template.json',
+          nestedStackTemplates: {},
+          physicalName: 'GrandChildStackB',
         },
       },
+      physicalName: 'NestedStack',
     },
   });
 });
@@ -612,26 +633,47 @@ test('readCurrentTemplateWithNestedStacks() on an undeployed parent stack with a
   });
 
   // WHEN
-  const nestedStackCount = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).nestedStackCount;
-  const deployedTemplate = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).deployedTemplate;
+  const deployedTemplate = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).deployedRootTemplate;
+  const nestedStacks = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).nestedStacks;
 
   // THEN
-  expect(nestedStackCount).toEqual(2);
-  expect(deployedTemplate).toEqual({
-    Resources: {
-      NestedStack: {
-        Type: 'AWS::CloudFormation::Stack',
-        Properties: {
-          NestedTemplate: {
+  expect(deployedTemplate).toEqual({});
+  expect(nestedStacks).toEqual({
+    NestedStack: {
+      deployedTemplate: {},
+      generatedTemplate: {
+        Resources: {
+          SomeResource: {
+            Type: 'AWS::Something',
+            Properties: {
+              Property: 'new-value',
+            },
+          },
+          NestedStack: {
+            Type: 'AWS::CloudFormation::Stack',
+            Properties: {
+              TemplateURL: 'https://www.magic-url.com',
+            },
+            Metadata: {
+              'aws:asset:path': 'one-resource-stack.nested.template.json',
+            },
+          },
+        },
+      },
+      nestedStackTemplates: {
+        NestedStack: {
+          deployedTemplate: {},
+          generatedTemplate: {
             Resources: {
-              NestedStack: {
-                Type: 'AWS::CloudFormation::Stack',
+              SomeResource: {
+                Type: 'AWS::Something',
                 Properties: {
-                  NestedTemplate: {},
+                  Property: 'new-value',
                 },
               },
             },
           },
+          nestedStackTemplates: {},
         },
       },
     },
@@ -787,27 +829,16 @@ test('readCurrentTemplateWithNestedStacks() succesfully ignores stacks without m
   ));
 
   // WHEN
-  const nestedStackCount = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).nestedStackCount;
-  const deployedTemplate = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).deployedTemplate;
+  const deployedTemplate = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).deployedRootTemplate;
+  const nestedStacks = (await deployments.readCurrentTemplateWithNestedStacks(rootStack)).nestedStacks;
 
   // THEN
-  expect(nestedStackCount).toEqual(1);
   expect(deployedTemplate).toEqual({
     Resources: {
       WithMetadata: {
         Type: 'AWS::CloudFormation::Stack',
         Properties: {
           TemplateURL: 'https://www.magic-url.com',
-          NestedTemplate: {
-            Resources: {
-              SomeResource: {
-                Type: 'AWS::Something',
-                Properties: {
-                  Property: 'old-value',
-                },
-              },
-            },
-          },
         },
         Metadata: {
           'aws:asset:path': 'one-resource-stack.nested.template.json',
@@ -835,16 +866,6 @@ test('readCurrentTemplateWithNestedStacks() succesfully ignores stacks without m
         Type: 'AWS::CloudFormation::Stack',
         Properties: {
           TemplateURL: 'https://www.magic-url.com',
-          NestedTemplate: {
-            Resources: {
-              SomeResource: {
-                Type: 'AWS::Something',
-                Properties: {
-                  Property: 'new-value',
-                },
-              },
-            },
-          },
         },
         Metadata: {
           'aws:asset:path': 'one-resource-stack.nested.template.json',
@@ -852,6 +873,32 @@ test('readCurrentTemplateWithNestedStacks() succesfully ignores stacks without m
       },
     },
   });
+  expect(nestedStacks).toEqual({
+    WithMetadata: {
+      deployedTemplate: {
+        Resources: {
+          SomeResource: {
+            Properties: {
+              Property: 'old-value',
+            },
+            Type: 'AWS::Something',
+          },
+        },
+      },
+      generatedTemplate: {
+        Resources: {
+          SomeResource: {
+            Properties: {
+              Property: 'new-value',
+            },
+            Type: 'AWS::Something',
+          },
+        },
+      },
+      physicalName: 'one-resource-stack',
+      nestedStackTemplates: {},
+    },
+  });
 });
 
 function pushStackResourceSummaries(stackName: string, ...items: CloudFormation.StackResourceSummary[]) {
diff --git a/packages/aws-cdk/test/api/hotswap/nested-stacks-hotswap.test.ts b/packages/aws-cdk/test/api/hotswap/nested-stacks-hotswap.test.ts
index cb499f24bd3b7..318638b72000c 100644
--- a/packages/aws-cdk/test/api/hotswap/nested-stacks-hotswap.test.ts
+++ b/packages/aws-cdk/test/api/hotswap/nested-stacks-hotswap.test.ts
@@ -8,7 +8,6 @@ let mockUpdateLambdaCode: (params: Lambda.Types.UpdateFunctionCodeRequest) => La
 let mockPublishVersion: jest.Mock<Lambda.FunctionConfiguration, Lambda.PublishVersionRequest[]>;
 let hotswapMockSdkProvider: setup.HotswapMockSdkProvider;
 
-// TODO: more tests for parent vs child containing hotswappable changes
 describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hotswapMode) => {
   test('can hotswap a lambda function in a 1-level nested stack', async () => {
     // GIVEN
@@ -18,14 +17,14 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       updateFunctionCode: mockUpdateLambdaCode,
     });
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'LambdaRoot',
       template: {
         Resources: {
           NestedStack: {
             Type: 'AWS::CloudFormation::Stack',
             Properties: {
-              TemplateURL: 'https://www.magic-url.com',
+              TemplateURL: 'https://www.amazoff.com',
             },
             Metadata: {
               'aws:asset:path': 'one-lambda-stack.nested.template.json',
@@ -35,7 +34,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
     setup.addTemplateToCloudFormationLookupMock(testStack({
       stackName: 'NestedStack',
       template: {
@@ -50,7 +49,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
@@ -63,10 +62,10 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       ),
     );
 
-    const cdkStackArtifact = testStack({ stackName: 'LambdaRoot', template: rootStack.template });
-
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+    oldRootStack.template.Resources.NestedStack.Properties.TemplateURL = 'https://www.amazon.com';
+    const newRootStack = testStack({ stackName: 'LambdaRoot', template: oldRootStack.template });
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
     // THEN
     expect(deployStackResult).not.toBeUndefined();
@@ -85,14 +84,14 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       updateFunctionCode: mockUpdateLambdaCode,
     });
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'TwoLevelLambdaRoot',
       template: {
         Resources: {
           ChildStack: {
             Type: 'AWS::CloudFormation::Stack',
             Properties: {
-              TemplateURL: 'https://www.magic-url.com',
+              TemplateURL: 'https://www.amazoff.com',
             },
             Metadata: {
               'aws:asset:path': 'one-lambda-one-stack-stack.nested.template.json',
@@ -102,8 +101,9 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
-    setup.addTemplateToCloudFormationLookupMock(testStack({
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
+
+    const oldChildStack = testStack({
       stackName: 'ChildStack',
       template: {
         Resources: {
@@ -117,13 +117,13 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'child-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
           GrandChildStack: {
             Type: 'AWS::CloudFormation::Stack',
             Properties: {
-              TemplateURL: 'https://www.magic-url.com',
+              TemplateURL: 'https://www.amazoff.com',
             },
             Metadata: {
               'aws:asset:path': 'one-lambda-stack.nested.template.json',
@@ -131,7 +131,9 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
           },
         },
       },
-    }));
+    });
+    setup.addTemplateToCloudFormationLookupMock(oldChildStack);
+
     setup.addTemplateToCloudFormationLookupMock(testStack({
       stackName: 'GrandChildStack',
       template: {
@@ -146,7 +148,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
@@ -164,10 +166,15 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       ),
     );
 
-    const cdkStackArtifact = testStack({ stackName: 'TwoLevelLambdaRoot', template: rootStack.template });
-
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+    oldRootStack.template.Resources.ChildStack.Properties.TemplateURL = 'https://www.amazon.com';
+    oldChildStack.template.Resources.GrandChildStack.Properties.TemplateURL = 'https://www.amazon.com';
+
+    // write the new templates to disk
+    const newRootStack = testStack({ stackName: oldRootStack.stackName, template: oldRootStack.template });
+    testStack({ stackName: oldChildStack.stackName, template: oldChildStack.template });
+
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
     // THEN
     expect(deployStackResult).not.toBeUndefined();
@@ -191,7 +198,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       updateFunctionCode: mockUpdateLambdaCode,
     });
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'SiblingLambdaRoot',
       template: {
         Resources: {
@@ -214,14 +221,14 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'root-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
     setup.addTemplateToCloudFormationLookupMock(testStack({
       stackName: 'NestedStack',
       template: {
@@ -236,7 +243,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
@@ -249,11 +256,12 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       ),
     );
 
-    rootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
-    const cdkStackArtifact = testStack({ stackName: 'SiblingLambdaRoot', template: rootStack.template });
-
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+    oldRootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
+    oldRootStack.template.Resources.NestedStack.Properties.TemplateURL = 'https://www.amazon.com';
+    // write the updated templates to disk
+    const newRootStack = testStack({ stackName: oldRootStack.stackName, template: oldRootStack.template });
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
     // THEN
     expect(deployStackResult).not.toBeUndefined();
@@ -279,7 +287,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       updateFunctionCode: mockUpdateLambdaCode,
     });
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'NonHotswappableRoot',
       template: {
         Resources: {
@@ -302,14 +310,14 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'root-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
     setup.addTemplateToCloudFormationLookupMock(testStack({
       stackName: 'NestedStack',
       template: {
@@ -325,7 +333,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
@@ -338,12 +346,13 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       ),
     );
 
-    rootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
-    const cdkStackArtifact = testStack({ stackName: 'NonHotswappableRoot', template: rootStack.template });
+    oldRootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
+    oldRootStack.template.Resources.NestedStack.Properties.TemplateURL = 'https://www.amazon.com';
+    const newRootStack = testStack({ stackName: oldRootStack.stackName, template: oldRootStack.template });
 
     if (hotswapMode === HotswapMode.FALL_BACK) {
       // WHEN
-      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
       // THEN
       expect(deployStackResult).toBeUndefined();
@@ -351,7 +360,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
 
     } else if (hotswapMode === HotswapMode.HOTSWAP_ONLY) {
       // WHEN
-      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
       // THEN
       expect(deployStackResult).not.toBeUndefined();
@@ -373,7 +382,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       updateFunctionCode: mockUpdateLambdaCode,
     });
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'NestedStackDeletionRoot',
       template: {
         Resources: {
@@ -396,14 +405,14 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'root-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
     setup.addTemplateToCloudFormationLookupMock(testStack({
       stackName: 'NestedStack',
       template: {
@@ -418,7 +427,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
@@ -431,20 +440,20 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       ),
     );
 
-    rootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
-    delete rootStack.template.Resources.NestedStack;
-    const cdkStackArtifact = testStack({ stackName: 'NestedStackDeletionRoot', template: rootStack.template });
+    oldRootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
+    delete oldRootStack.template.Resources.NestedStack;
+    const newRootStack = testStack({ stackName: oldRootStack.stackName, template: oldRootStack.template });
 
     if (hotswapMode === HotswapMode.FALL_BACK) {
       // WHEN
-      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
       // THEN
       expect(deployStackResult).toBeUndefined();
       expect(mockUpdateLambdaCode).not.toHaveBeenCalled();
     } else if (hotswapMode === HotswapMode.HOTSWAP_ONLY) {
       // WHEN
-      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
       // THEN
       expect(deployStackResult).not.toBeUndefined();
@@ -466,7 +475,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       updateFunctionCode: mockUpdateLambdaCode,
     });
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'NestedStackCreationRoot',
       template: {
         Resources: {
@@ -480,30 +489,31 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'root-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
 
-    rootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
-    rootStack.template.Resources.NestedStack = {
+    oldRootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
+    oldRootStack.template.Resources.NestedStack = {
       Type: 'AWS::CloudFormation::Stack',
       Properties: {
-        TemplateURL: 'https://www.magic-url.com',
+        TemplateURL: 'https://www.amazon.com',
       },
       Metadata: {
         'aws:asset:path': 'one-lambda-stack.nested.template.json',
       },
     };
-    const cdkStackArtifact = testStack({ stackName: 'NestedStackCreationRoot', template: rootStack.template });
+    // we need this because testStack() immediately writes the template to disk, so changing the template afterwards is not going to update the file.
+    const newRootStack = testStack({ stackName: oldRootStack.stackName, template: oldRootStack.template });
 
     if (hotswapMode === HotswapMode.FALL_BACK) {
       // WHEN
-      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
       // THEN
       expect(deployStackResult).toBeUndefined();
@@ -511,7 +521,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
 
     } else if (hotswapMode === HotswapMode.HOTSWAP_ONLY) {
       // WHEN
-      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
       // THEN
       expect(deployStackResult).not.toBeUndefined();
@@ -533,7 +543,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       updateFunctionCode: mockUpdateLambdaCode,
     });
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'NestedStackTypeChangeRoot',
       template: {
         Resources: {
@@ -547,7 +557,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'root-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
           FutureNestedStack: {
@@ -560,30 +570,31 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'spooky-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
 
-    rootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
-    rootStack.template.Resources.FutureNestedStack = {
+    oldRootStack.template.Resources.Func.Properties.Code.S3Bucket = 'new-bucket';
+    oldRootStack.template.Resources.FutureNestedStack = {
       Type: 'AWS::CloudFormation::Stack',
       Properties: {
-        TemplateURL: 'https://www.magic-url.com',
+        TemplateURL: 'https://www.amazon.com',
       },
       Metadata: {
         'aws:asset:path': 'one-lambda-stack.nested.template.json',
       },
     };
-    const cdkStackArtifact = testStack({ stackName: 'NestedStackTypeChangeRoot', template: rootStack.template });
+    // write the updated template to disk
+    const newRootStack = testStack({ stackName: oldRootStack.stackName, template: oldRootStack.template });
 
     if (hotswapMode === HotswapMode.FALL_BACK) {
       // WHEN
-      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
       // THEN
       expect(deployStackResult).toBeUndefined();
@@ -591,7 +602,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
 
     } else if (hotswapMode === HotswapMode.HOTSWAP_ONLY) {
       // WHEN
-      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+      const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
       // THEN
       expect(deployStackResult).not.toBeUndefined();
@@ -620,11 +631,11 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
         },
       },
       Metadata: {
-        'aws:asset:path': 'old-path',
+        'aws:asset:path': 'old-lambda-path',
       },
     };
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'MultiLayerRoot',
       template: {
         Resources: {
@@ -642,8 +653,9 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
-    setup.addTemplateToCloudFormationLookupMock(testStack({
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
+
+    const oldChildStack = testStack({
       stackName: 'ChildStack',
       template: {
         Resources: {
@@ -668,7 +680,9 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
           Func: lambdaFunctionResource,
         },
       },
-    }));
+    });
+    setup.addTemplateToCloudFormationLookupMock(oldChildStack);
+
     setup.addTemplateToCloudFormationLookupMock(testStack({
       stackName: 'GrandChildStackA',
       template: {
@@ -708,11 +722,16 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       setup.stackSummaryOf('Func', 'AWS::Lambda::Function', 'grandchild-B-function'),
     );
 
-    rootStack.template.Resources.Func.Properties.Code.S3Key = 'new-key';
-    const cdkStackArtifact = testStack({ stackName: 'MultiLayerRoot', template: rootStack.template });
-
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+    oldRootStack.template.Resources.Func.Properties.Code.S3Key = 'new-key';
+    oldRootStack.template.Resources.ChildStack.Properties.TemplateURL = 'https://www.amazon.com';
+    oldChildStack.template.Resources.GrandChildStackA.Properties.TemplateURL = 'https://www.amazon.com';
+    oldChildStack.template.Resources.GrandChildStackB.Properties.TemplateURL = 'https://www.amazon.com';
+
+    const newRootStack = testStack({ stackName: oldRootStack.stackName, template: oldRootStack.template });
+    //testStack({ stackName: oldChildStack.stackName, template: oldChildStack.template });
+
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack);
 
     // THEN
     expect(deployStackResult).not.toBeUndefined();
@@ -796,7 +815,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
@@ -809,10 +828,10 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       ),
     );
 
-    const cdkStackArtifact = testStack({ stackName: 'LambdaRoot', template: rootStack.template });
+    rootStack.template.Resources.NestedStack.Properties.TemplateURL = 'https://www.amazon.com';
 
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact, {
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, rootStack, {
       S3BucketParam: 'bucket-param-value',
       S3KeyParam: 'key-param-value',
     });
@@ -826,8 +845,8 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
     });
   });
 
-  test('can hotswap a lambda function in a 2-level nested stack with dependency on a output of 2nd level sibling stack', async () => {
-    // GIVEN: RootStack has one child stack `FirstLevelRootStack` which further has two child stacks
+  test('can hotswap a lambda function in a 2-level nested stack with dependency on an output of 2nd level sibling stack', async () => {
+    // GIVEN: RootStack has one child stack `FirstLevelNestedStack` which further has two child stacks
     // `NestedLambdaStack` and `NestedSiblingStack`. `NestedLambdaStack` takes two parameters s3Key
     // and s3Bucket and use them for a Lambda function.
     // RootStack resolves s3Bucket from a root template parameter and passed to FirstLevelRootStack which
@@ -838,11 +857,11 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       updateFunctionCode: mockUpdateLambdaCode,
     });
 
-    const rootStack = testStack({
+    const oldRootStack = testStack({
       stackName: 'RootStack',
       template: {
         Resources: {
-          FirstLevelRootStack: {
+          FirstLevelNestedStack: {
             Type: 'AWS::CloudFormation::Stack',
             Properties: {
               TemplateURL: 'https://www.magic-url.com',
@@ -866,8 +885,8 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       },
     });
 
-    const firstLevelRootStack = testStack({
-      stackName: 'FirstLevelRootStack',
+    const oldFirstLevelNestedStack = testStack({
+      stackName: 'FirstLevelNestedStack',
       template: {
         Resources: {
           NestedLambdaStack: {
@@ -925,7 +944,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
           },
         },
         Metadata: {
-          'aws:asset:path': 'old-path',
+          'aws:asset:path': 'old-lambda-path',
         },
       },
     });
@@ -936,40 +955,39 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
         Outputs: {
           NestedOutput: { Value: 's3-key-value-from-output' },
         },
-        Metadata: {
-          'aws:asset:path': 'old-path',
-        },
       },
     });
 
-    setup.addTemplateToCloudFormationLookupMock(rootStack);
-    setup.addTemplateToCloudFormationLookupMock(firstLevelRootStack);
+    setup.addTemplateToCloudFormationLookupMock(oldRootStack);
+    setup.addTemplateToCloudFormationLookupMock(oldFirstLevelNestedStack);
     setup.addTemplateToCloudFormationLookupMock(nestedLambdaStack);
     setup.addTemplateToCloudFormationLookupMock(nestedSiblingStack);
 
-    setup.pushNestedStackResourceSummaries('RootStack',
-      setup.stackSummaryOf('FirstLevelRootStack', 'AWS::CloudFormation::Stack',
-        'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/FirstLevelRootStack/abcd',
+    setup.pushNestedStackResourceSummaries(oldRootStack.stackName,
+      setup.stackSummaryOf(oldFirstLevelNestedStack.stackName, 'AWS::CloudFormation::Stack',
+        `arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/${oldFirstLevelNestedStack.stackName}/abcd`,
       ),
     );
-
-    setup.pushNestedStackResourceSummaries('FirstLevelRootStack',
-      setup.stackSummaryOf('NestedLambdaStack', 'AWS::CloudFormation::Stack',
-        'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/NestedLambdaStack/abcd',
+    setup.pushNestedStackResourceSummaries(oldFirstLevelNestedStack.stackName,
+      setup.stackSummaryOf(nestedLambdaStack.stackName, 'AWS::CloudFormation::Stack',
+        `arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/${nestedLambdaStack.stackName}/abcd`,
       ),
-      setup.stackSummaryOf('NestedSiblingStack', 'AWS::CloudFormation::Stack',
-        'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/NestedSiblingStack/abcd',
+      setup.stackSummaryOf(nestedSiblingStack.stackName, 'AWS::CloudFormation::Stack',
+        `arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/${nestedSiblingStack.stackName}/abcd`,
       ),
     );
-    setup.pushNestedStackResourceSummaries('NestedLambdaStack',
+    setup.pushNestedStackResourceSummaries(nestedLambdaStack.stackName,
       setup.stackSummaryOf('Func', 'AWS::Lambda::Function', 'nested-lambda-function'),
     );
-    setup.pushNestedStackResourceSummaries('NestedSiblingStack');
-
-    const cdkStackArtifact = testStack({ stackName: 'RootStack', template: rootStack.template });
+    setup.pushNestedStackResourceSummaries(nestedSiblingStack.stackName);
+    oldRootStack.template.Resources.FirstLevelNestedStack.Properties.TemplateURL = 'https://www.amazon.com';
+    oldFirstLevelNestedStack.template.Resources.NestedLambdaStack.Properties.TemplateURL = 'https://www.amazon.com';
+    oldFirstLevelNestedStack.template.Resources.NestedSiblingStack.Properties.TemplateURL = 'https://www.amazon.com';
+    const newRootStack = testStack({ stackName: oldRootStack.stackName, template: oldRootStack.template });
+    testStack({ stackName: oldFirstLevelNestedStack.stackName, template: oldFirstLevelNestedStack.template });
 
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact, {
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, newRootStack, {
       S3BucketParam: 'new-bucket',
     });
 
@@ -1046,7 +1064,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
@@ -1059,10 +1077,10 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       ),
     );
 
-    const cdkStackArtifact = testStack({ stackName: 'LambdaRoot', template: rootStack.template });
+    rootStack.template.Resources.NestedStack.Properties.TemplateURL = 'https://www.amazon.com';
 
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, rootStack);
 
     // THEN
     expect(deployStackResult).not.toBeUndefined();
@@ -1129,9 +1147,9 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
         },
       },
     });
-
     setup.addTemplateToCloudFormationLookupMock(rootStack);
-    setup.addTemplateToCloudFormationLookupMock(testStack({
+
+    const childStack = testStack({
       stackName: 'ChildStack',
       template: {
         Resources: {
@@ -1145,7 +1163,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
           GrandChildStack: {
@@ -1159,7 +1177,9 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
           },
         },
       },
-    }));
+    });
+    setup.addTemplateToCloudFormationLookupMock(childStack);
+
     setup.addTemplateToCloudFormationLookupMock(testStack({
       stackName: 'GrandChildStack',
       template: {
@@ -1174,7 +1194,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
               FunctionName: 'my-function',
             },
             Metadata: {
-              'aws:asset:path': 'old-path',
+              'aws:asset:path': 'old-lambda-path',
             },
           },
         },
@@ -1192,10 +1212,12 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
         'arn:aws:cloudformation:bermuda-triangle-1337:123456789012:stack/GrandChildStack/abcd',
       ),
     );
-    const cdkStackArtifact = testStack({ stackName: 'LambdaRoot', template: rootStack.template });
+
+    rootStack.template.Resources.ChildStack.Properties.TemplateURL = 'https://www.amazon.com';
+    childStack.template.Resources.GrandChildStack.Properties.TemplateURL = 'https://www.amazon.com';
 
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact, {
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, rootStack, {
       GrandChildS3BucketParam: 'child-bucket-param-value',
       GrandChildS3KeyParam: 'child-key-param-value',
       ChildS3BucketParam: 'bucket-param-value',
@@ -1232,7 +1254,7 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
           NestedStack: {
             Type: 'AWS::CloudFormation::Stack',
             Properties: {
-              TemplateURL: 'https://www.magic-url.com',
+              TemplateURL: 'https://www.amazoff.com',
             },
             Metadata: {
               'aws:asset:path': 'one-lambda-version-stack.nested.template.json',
@@ -1273,10 +1295,9 @@ describe.each([HotswapMode.FALL_BACK, HotswapMode.HOTSWAP_ONLY])('%p mode', (hot
       ),
     );
 
-    const cdkStackArtifact = testStack({ stackName: 'LambdaRoot', template: rootStack.template });
-
     // WHEN
-    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
+    rootStack.template.Resources.NestedStack.Properties.TemplateURL = 'https://www.amazon.com';
+    const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, rootStack);
 
     // THEN
     expect(deployStackResult).not.toBeUndefined();
diff --git a/packages/aws-cdk/test/diff.test.ts b/packages/aws-cdk/test/diff.test.ts
index a7b5905e12f87..8dd11bb0b5fce 100644
--- a/packages/aws-cdk/test/diff.test.ts
+++ b/packages/aws-cdk/test/diff.test.ts
@@ -7,11 +7,119 @@ import { instanceMockFrom, MockCloudExecutable } from './util';
 import { Deployments } from '../lib/api/deployments';
 import { CdkToolkit } from '../lib/cdk-toolkit';
 import * as cfn from '../lib/api/util/cloudformation';
+import { NestedStackTemplates } from '../lib/api/nested-stack-helpers';
+import * as fs from 'fs';
 
 let cloudExecutable: MockCloudExecutable;
 let cloudFormation: jest.Mocked<Deployments>;
 let toolkit: CdkToolkit;
 
+describe('imports', () => {
+  beforeEach(() => {
+    const outputToJson = {
+      '//': 'This file is generated by cdk migrate. It will be automatically deleted after the first successful deployment of this app to the environment of the original resources.',
+      'Source': 'localfile',
+      'Resources': [],
+    };
+    fs.writeFileSync('migrate.json', JSON.stringify(outputToJson, null, 2));
+
+    jest.spyOn(cfn, 'createDiffChangeSet').mockImplementationOnce(async () => {
+      return {
+        Changes: [
+          {
+            ResourceChange: {
+              Action: 'Import',
+              LogicalResourceId: 'Queue',
+            },
+          },
+          {
+            ResourceChange: {
+              Action: 'Import',
+              LogicalResourceId: 'Bucket',
+            },
+          },
+          {
+            ResourceChange: {
+              Action: 'Import',
+              LogicalResourceId: 'Queue2',
+            },
+          },
+        ],
+      };
+    });
+    cloudExecutable = new MockCloudExecutable({
+      stacks: [{
+        stackName: 'A',
+        template: {
+          Resources: {
+            Queue: {
+              Type: 'AWS::SQS::Queue',
+            },
+            Queue2: {
+              Type: 'AWS::SQS::Queue',
+            },
+            Bucket: {
+              Type: 'AWS::S3::Bucket',
+            },
+          },
+        },
+      }],
+    });
+
+    cloudFormation = instanceMockFrom(Deployments);
+
+    toolkit = new CdkToolkit({
+      cloudExecutable,
+      deployments: cloudFormation,
+      configuration: cloudExecutable.configuration,
+      sdkProvider: cloudExecutable.sdkProvider,
+    });
+
+    // Default implementations
+    cloudFormation.readCurrentTemplateWithNestedStacks.mockImplementation((_stackArtifact: CloudFormationStackArtifact) => {
+      return Promise.resolve({
+        deployedRootTemplate: {},
+        nestedStacks: {},
+      });
+    });
+    cloudFormation.deployStack.mockImplementation((options) => Promise.resolve({
+      noOp: true,
+      outputs: {},
+      stackArn: '',
+      stackArtifact: options.stack,
+    }));
+  });
+
+  afterEach(() => {
+    fs.rmSync('migrate.json');
+  });
+
+  test('imports', async () => {
+    // GIVEN
+    const buffer = new StringWritable();
+
+    // WHEN
+    const exitCode = await toolkit.diff({
+      stackNames: ['A'],
+      stream: buffer,
+      changeSet: true,
+    });
+
+    // THEN
+    const plainTextOutput = buffer.data.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, '');
+    expect(plainTextOutput).toContain(`Stack A
+Parameters and rules created during migration do not affect resource configuration.
+Resources
+[←] AWS::SQS::Queue Queue import
+[←] AWS::SQS::Queue Queue2 import
+[←] AWS::S3::Bucket Bucket import
+`);
+
+    expect(buffer.data.trim()).toContain('✨  Number of stacks with differences: 1');
+    expect(exitCode).toBe(0);
+  });
+});
+
 describe('non-nested stacks', () => {
   beforeEach(() => {
     cloudExecutable = new MockCloudExecutable({
@@ -56,13 +164,13 @@ describe('non-nested stacks', () => {
     cloudFormation.readCurrentTemplateWithNestedStacks.mockImplementation((stackArtifact: CloudFormationStackArtifact) => {
       if (stackArtifact.stackName === 'D') {
         return Promise.resolve({
-          deployedTemplate: { resource: 'D' },
-          nestedStackCount: 0,
+          deployedRootTemplate: { resource: 'D' },
+          nestedStacks: {},
         });
       }
       return Promise.resolve({
-        deployedTemplate: {},
-        nestedStackCount: 0,
+        deployedRootTemplate: {},
+        nestedStacks: {},
       });
     });
     cloudFormation.deployStack.mockImplementation((options) => Promise.resolve({
@@ -223,48 +331,82 @@ describe('nested stacks', () => {
         stackArtifact.template.Resources = {
           AdditionChild: {
             Type: 'AWS::CloudFormation::Stack',
-            Resources: {
-              SomeResource: {
-                Type: 'AWS::Something',
-                Properties: {
-                  Prop: 'added-value',
-                },
-              },
+            Properties: {
+              TemplateURL: 'addition-child-url-old',
             },
           },
           DeletionChild: {
             Type: 'AWS::CloudFormation::Stack',
-            Resources: {
-              SomeResource: {
-                Type: 'AWS::Something',
-              },
+            Properties: {
+              TemplateURL: 'deletion-child-url-old',
             },
           },
           ChangedChild: {
             Type: 'AWS::CloudFormation::Stack',
-            Resources: {
-              SomeResource: {
-                Type: 'AWS::Something',
-                Properties: {
-                  Prop: 'new-value',
-                },
-              },
+            Properties: {
+              TemplateURL: 'changed-child-url-old',
+            },
+          },
+          UnchangedChild: {
+            Type: 'AWS::CloudFormation::Stack',
+            Properties: {
+              TemplateURL: 'changed-child-url-constant',
             },
           },
         };
         return Promise.resolve({
-          deployedTemplate: {
+          deployedRootTemplate: {
             Resources: {
               AdditionChild: {
                 Type: 'AWS::CloudFormation::Stack',
+                Properties: {
+                  TemplateURL: 'addition-child-url-new',
+                },
+              },
+              DeletionChild: {
+                Type: 'AWS::CloudFormation::Stack',
+                Properties: {
+                  TemplateURL: 'deletion-child-url-new',
+                },
+              },
+              ChangedChild: {
+                Type: 'AWS::CloudFormation::Stack',
+                Properties: {
+                  TemplateURL: 'changed-child-url-new',
+                },
+              },
+              UnchangedChild: {
+                Type: 'AWS::CloudFormation::Stack',
+                Properties: {
+                  TemplateURL: 'changed-child-url-constant',
+                },
+              },
+            },
+          },
+          nestedStacks: {
+            AdditionChild: {
+              deployedTemplate: {
                 Resources: {
                   SomeResource: {
                     Type: 'AWS::Something',
                   },
                 },
               },
-              DeletionChild: {
-                Type: 'AWS::CloudFormation::Stack',
+              generatedTemplate: {
+                Resources: {
+                  SomeResource: {
+                    Type: 'AWS::Something',
+                    Properties: {
+                      Prop: 'added-value',
+                    },
+                  },
+                },
+              },
+              nestedStackTemplates: {},
+              physicalName: 'AdditionChild',
+            },
+            DeletionChild: {
+              deployedTemplate: {
                 Resources: {
                   SomeResource: {
                     Type: 'AWS::Something',
@@ -274,8 +416,18 @@ describe('nested stacks', () => {
                   },
                 },
               },
-              ChangedChild: {
-                Type: 'AWS::CloudFormation::Stack',
+              generatedTemplate: {
+                Resources: {
+                  SomeResource: {
+                    Type: 'AWS::Something',
+                  },
+                },
+              },
+              nestedStackTemplates: {},
+              physicalName: 'DeletionChild',
+            },
+            ChangedChild: {
+              deployedTemplate: {
                 Resources: {
                   SomeResource: {
                     Type: 'AWS::Something',
@@ -285,19 +437,61 @@ describe('nested stacks', () => {
                   },
                 },
               },
+              generatedTemplate: {
+                Resources: {
+                  SomeResource: {
+                    Type: 'AWS::Something',
+                    Properties: {
+                      Prop: 'new-value',
+                    },
+                  },
+                },
+              },
+              nestedStackTemplates: {},
+              physicalName: 'ChangedChild',
+            },
+            newChild: {
+              deployedTemplate: {},
+              generatedTemplate: {
+                Resources: {
+                  SomeResource: {
+                    Type: 'AWS::Something',
+                    Properties: {
+                      Prop: 'new-value',
+                    },
+                  },
+                },
+              },
+              nestedStackTemplates: {
+                newGrandChild: {
+                  deployedTemplate: {},
+                  generatedTemplate: {
+                    Resources: {
+                      SomeResource: {
+                        Type: 'AWS::Something',
+                        Properties: {
+                          Prop: 'new-value',
+                        },
+                      },
+                    },
+                  },
+                  physicalName: undefined,
+                  nestedStackTemplates: {},
+                } as NestedStackTemplates,
+              },
+              physicalName: undefined,
             },
           },
-          nestedStackCount: 3,
         });
       }
       return Promise.resolve({
-        deployedTemplate: {},
-        nestedStackCount: 0,
+        deployedRootTemplate: {},
+        nestedStacks: {},
       });
     });
   });
 
-  test('diff can diff nested stacks', async () => {
+  test('diff can diff nested stacks and display the nested stack logical ID if has not been deployed or otherwise has no physical name', async () => {
     // GIVEN
     const buffer = new StringWritable();
 
@@ -305,6 +499,7 @@ describe('nested stacks', () => {
     const exitCode = await toolkit.diff({
       stackNames: ['Parent'],
       stream: buffer,
+      changeSet: false,
     });
 
     // THEN
@@ -313,23 +508,47 @@ describe('nested stacks', () => {
     expect(plainTextOutput.trim()).toEqual(`Stack Parent
 Resources
 [~] AWS::CloudFormation::Stack AdditionChild
- └─ [~] Resources
-     └─ [~] .SomeResource:
-         └─ [+] Added: .Properties
+ └─ [~] TemplateURL
+     ├─ [-] addition-child-url-new
+     └─ [+] addition-child-url-old
 [~] AWS::CloudFormation::Stack DeletionChild
- └─ [~] Resources
-     └─ [~] .SomeResource:
-         └─ [-] Removed: .Properties
+ └─ [~] TemplateURL
+     ├─ [-] deletion-child-url-new
+     └─ [+] deletion-child-url-old
 [~] AWS::CloudFormation::Stack ChangedChild
- └─ [~] Resources
-     └─ [~] .SomeResource:
-         └─ [~] .Properties:
-             └─ [~] .Prop:
-                 ├─ [-] old-value
-                 └─ [+] new-value
+ └─ [~] TemplateURL
+     ├─ [-] changed-child-url-new
+     └─ [+] changed-child-url-old
+
+Stack AdditionChild
+Resources
+[~] AWS::Something SomeResource
+ └─ [+] Prop
+     └─ added-value
+
+Stack DeletionChild
+Resources
+[~] AWS::Something SomeResource
+ └─ [-] Prop
+     └─ value-to-be-removed
+
+Stack ChangedChild
+Resources
+[~] AWS::Something SomeResource
+ └─ [~] Prop
+     ├─ [-] old-value
+     └─ [+] new-value
 
+Stack newChild
+Resources
+[+] AWS::Something SomeResource
+
+Stack newGrandChild
+Resources
+[+] AWS::Something SomeResource
 
-✨  Number of stacks with differences: 4`);
+
+✨  Number of stacks with differences: 6`);
 
     expect(exitCode).toBe(0);
   });
@@ -352,23 +571,47 @@ Resources
     expect(plainTextOutput.trim()).toEqual(`Stack Parent
 Resources
 [~] AWS::CloudFormation::Stack AdditionChild
- └─ [~] Resources
-     └─ [~] .SomeResource:
-         └─ [+] Added: .Properties
+ └─ [~] TemplateURL
+     ├─ [-] addition-child-url-new
+     └─ [+] addition-child-url-old
 [~] AWS::CloudFormation::Stack DeletionChild
- └─ [~] Resources
-     └─ [~] .SomeResource:
-         └─ [-] Removed: .Properties
+ └─ [~] TemplateURL
+     ├─ [-] deletion-child-url-new
+     └─ [+] deletion-child-url-old
 [~] AWS::CloudFormation::Stack ChangedChild
- └─ [~] Resources
-     └─ [~] .SomeResource:
-         └─ [~] .Properties:
-             └─ [~] .Prop:
-                 ├─ [-] old-value
-                 └─ [+] new-value
+ └─ [~] TemplateURL
+     ├─ [-] changed-child-url-new
+     └─ [+] changed-child-url-old
+
+Stack AdditionChild
+Resources
+[~] AWS::Something SomeResource
+ └─ [+] Prop
+     └─ added-value
+
+Stack DeletionChild
+Resources
+[~] AWS::Something SomeResource
+ └─ [-] Prop
+     └─ value-to-be-removed
+
+Stack ChangedChild
+Resources
+[~] AWS::Something SomeResource
+ └─ [~] Prop
+     ├─ [-] old-value
+     └─ [+] new-value
+
+Stack newChild
+Resources
+[+] AWS::Something SomeResource
+
+Stack newGrandChild
+Resources
+[+] AWS::Something SomeResource
 
 
-✨  Number of stacks with differences: 4`);
+✨  Number of stacks with differences: 6`);
 
     expect(exitCode).toBe(0);
     expect(changeSetSpy).not.toHaveBeenCalled();
diff --git a/packages/aws-cdk/test/nested-stack-templates/one-stack-with-two-nested-stacks-stack.template.json b/packages/aws-cdk/test/nested-stack-templates/one-stack-with-two-nested-stacks-stack.template.json
index bdf9ed5cb2c51..e0bcd1cb3ab43 100644
--- a/packages/aws-cdk/test/nested-stack-templates/one-stack-with-two-nested-stacks-stack.template.json
+++ b/packages/aws-cdk/test/nested-stack-templates/one-stack-with-two-nested-stacks-stack.template.json
@@ -3,7 +3,7 @@
     "NestedLambdaStack": {
       "Type": "AWS::CloudFormation::Stack",
       "Properties": {
-        "TemplateURL": "https://www.magic-url.com",
+        "TemplateURL": "https://www.amazon.com",
         "Parameters": {
           "referenceToS3BucketParam": {
             "Ref": "S3BucketParam"
@@ -23,7 +23,7 @@
     "NestedSiblingStack": {
       "Type": "AWS::CloudFormation::Stack",
       "Properties": {
-        "TemplateURL": "https://www.magic-url.com"
+        "TemplateURL": "https://www.amazon.com"
       },
       "Metadata": {
         "aws:asset:path": "one-output-stack.nested.template.json"
@@ -32,7 +32,8 @@
   },
   "Parameters": {
     "S3BucketParam": {
-      "Type": "String"
+      "Type": "String",
+      "Description": "S3 bucket for asset"
     }
   }
 }
diff --git a/packages/aws-cdk/test/nested-stack-templates/one-unnamed-lambda-two-stacks-stack.nested.template.json b/packages/aws-cdk/test/nested-stack-templates/one-unnamed-lambda-two-stacks-stack.nested.template.json
index 2ac6271955cf4..a1adcd776d469 100644
--- a/packages/aws-cdk/test/nested-stack-templates/one-unnamed-lambda-two-stacks-stack.nested.template.json
+++ b/packages/aws-cdk/test/nested-stack-templates/one-unnamed-lambda-two-stacks-stack.nested.template.json
@@ -15,7 +15,7 @@
     "GrandChildStackA": {
       "Type": "AWS::CloudFormation::Stack",
       "Properties": {
-        "TemplateURL": "https://www.magic-url.com"
+        "TemplateURL": "https://www.amazon.com"
       },
       "Metadata": {
         "aws:asset:path": "one-unnamed-lambda-stack.nested.template.json"
@@ -24,7 +24,7 @@
     "GrandChildStackB": {
       "Type": "AWS::CloudFormation::Stack",
       "Properties": {
-        "TemplateURL": "https://www.magic-url.com"
+        "TemplateURL": "https://www.amazon.com"
       },
       "Metadata": {
         "aws:asset:path": "one-unnamed-lambda-stack.nested.template.json"
diff --git a/packages/aws-cdk/test/util.ts b/packages/aws-cdk/test/util.ts
index ecc262e948153..879d6572f369b 100644
--- a/packages/aws-cdk/test/util.ts
+++ b/packages/aws-cdk/test/util.ts
@@ -37,9 +37,9 @@ export class MockCloudExecutable extends CloudExecutable {
   public readonly configuration: Configuration;
   public readonly sdkProvider: MockSdkProvider;
 
-  constructor(assembly: TestAssembly) {
+  constructor(assembly: TestAssembly, sdkProviderArg?: MockSdkProvider) {
     const configuration = new Configuration();
-    const sdkProvider = new MockSdkProvider();
+    const sdkProvider = sdkProviderArg ?? new MockSdkProvider();
 
     super({
       configuration,

From 6fef789e14a0f53317da9ca4f319950d33f86ed1 Mon Sep 17 00:00:00 2001
From: Michael Sambol <sambol.michael@gmail.com>
Date: Thu, 14 Mar 2024 09:01:26 -0600
Subject: [PATCH 4/4] feat(rds): proxy for mariadb (#29412)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

MariaDB is grouped with MySQL, hence adding `MYSQL` as the engine family for MariaDB.

<img width="749" alt="Screenshot 2024-03-08 at 12 02 36 PM" src="https://github.com/aws/aws-cdk/assets/3310356/382d5561-6115-4bc1-a7e7-fb4deda57c73">


Closes #29402.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
---
 .../aws-cdk-rds-proxy-mariadb.assets.json     |   19 +
 .../aws-cdk-rds-proxy-mariadb.template.json   |  816 ++++++++++
 .../integ.proxy-mariadb.js.snapshot/cdk.out   |    1 +
 ...efaultTestDeployAssert9D9B7FF3.assets.json |   19 +
 ...aultTestDeployAssert9D9B7FF3.template.json |   36 +
 .../integ.json                                |   20 +
 .../manifest.json                             |  317 ++++
 .../integ.proxy-mariadb.js.snapshot/tree.json | 1329 +++++++++++++++++
 .../test/aws-rds/test/integ.proxy-mariadb.ts  |   45 +
 packages/aws-cdk-lib/aws-rds/README.md        |    4 +-
 .../aws-rds/lib/instance-engine.ts            |    1 +
 .../aws-cdk-lib/aws-rds/test/proxy.test.ts    |   67 +-
 12 files changed, 2670 insertions(+), 4 deletions(-)
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/aws-cdk-rds-proxy-mariadb.assets.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/aws-cdk-rds-proxy-mariadb.template.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/cdk.out
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.assets.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.template.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/integ.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/manifest.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/tree.json
 create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.ts

diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/aws-cdk-rds-proxy-mariadb.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/aws-cdk-rds-proxy-mariadb.assets.json
new file mode 100644
index 0000000000000..09256e0b2b86d
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/aws-cdk-rds-proxy-mariadb.assets.json
@@ -0,0 +1,19 @@
+{
+  "version": "36.0.0",
+  "files": {
+    "f0fff306f7e137bbf1a002fa55210d252f5846dc8e753143422b180e68469441": {
+      "source": {
+        "path": "aws-cdk-rds-proxy-mariadb.template.json",
+        "packaging": "file"
+      },
+      "destinations": {
+        "current_account-current_region": {
+          "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
+          "objectKey": "f0fff306f7e137bbf1a002fa55210d252f5846dc8e753143422b180e68469441.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-rds/test/integ.proxy-mariadb.js.snapshot/aws-cdk-rds-proxy-mariadb.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/aws-cdk-rds-proxy-mariadb.template.json
new file mode 100644
index 0000000000000..df22dfd1df50b
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/aws-cdk-rds-proxy-mariadb.template.json
@@ -0,0 +1,816 @@
+{
+ "Resources": {
+  "vpcA2121C38": {
+   "Type": "AWS::EC2::VPC",
+   "Properties": {
+    "CidrBlock": "10.0.0.0/16",
+    "EnableDnsHostnames": true,
+    "EnableDnsSupport": true,
+    "InstanceTenancy": "default",
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc"
+     }
+    ]
+   }
+  },
+  "vpcPublicSubnet1Subnet2E65531E": {
+   "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": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "vpcPublicSubnet1RouteTable48A2DF9B": {
+   "Type": "AWS::EC2::RouteTable",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "vpcPublicSubnet1RouteTableAssociation5D3F4579": {
+   "Type": "AWS::EC2::SubnetRouteTableAssociation",
+   "Properties": {
+    "RouteTableId": {
+     "Ref": "vpcPublicSubnet1RouteTable48A2DF9B"
+    },
+    "SubnetId": {
+     "Ref": "vpcPublicSubnet1Subnet2E65531E"
+    }
+   }
+  },
+  "vpcPublicSubnet1DefaultRoute10708846": {
+   "Type": "AWS::EC2::Route",
+   "Properties": {
+    "DestinationCidrBlock": "0.0.0.0/0",
+    "GatewayId": {
+     "Ref": "vpcIGWE57CBDCA"
+    },
+    "RouteTableId": {
+     "Ref": "vpcPublicSubnet1RouteTable48A2DF9B"
+    }
+   },
+   "DependsOn": [
+    "vpcVPCGW7984C166"
+   ]
+  },
+  "vpcPublicSubnet1EIPDA49DCBE": {
+   "Type": "AWS::EC2::EIP",
+   "Properties": {
+    "Domain": "vpc",
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1"
+     }
+    ]
+   }
+  },
+  "vpcPublicSubnet1NATGateway9C16659E": {
+   "Type": "AWS::EC2::NatGateway",
+   "Properties": {
+    "AllocationId": {
+     "Fn::GetAtt": [
+      "vpcPublicSubnet1EIPDA49DCBE",
+      "AllocationId"
+     ]
+    },
+    "SubnetId": {
+     "Ref": "vpcPublicSubnet1Subnet2E65531E"
+    },
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1"
+     }
+    ]
+   },
+   "DependsOn": [
+    "vpcPublicSubnet1DefaultRoute10708846",
+    "vpcPublicSubnet1RouteTableAssociation5D3F4579"
+   ]
+  },
+  "vpcPublicSubnet2Subnet009B674F": {
+   "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": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "vpcPublicSubnet2RouteTableEB40D4CB": {
+   "Type": "AWS::EC2::RouteTable",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "vpcPublicSubnet2RouteTableAssociation21F81B59": {
+   "Type": "AWS::EC2::SubnetRouteTableAssociation",
+   "Properties": {
+    "RouteTableId": {
+     "Ref": "vpcPublicSubnet2RouteTableEB40D4CB"
+    },
+    "SubnetId": {
+     "Ref": "vpcPublicSubnet2Subnet009B674F"
+    }
+   }
+  },
+  "vpcPublicSubnet2DefaultRouteA1EC0F60": {
+   "Type": "AWS::EC2::Route",
+   "Properties": {
+    "DestinationCidrBlock": "0.0.0.0/0",
+    "GatewayId": {
+     "Ref": "vpcIGWE57CBDCA"
+    },
+    "RouteTableId": {
+     "Ref": "vpcPublicSubnet2RouteTableEB40D4CB"
+    }
+   },
+   "DependsOn": [
+    "vpcVPCGW7984C166"
+   ]
+  },
+  "vpcPublicSubnet2EIP9B3743B1": {
+   "Type": "AWS::EC2::EIP",
+   "Properties": {
+    "Domain": "vpc",
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2"
+     }
+    ]
+   }
+  },
+  "vpcPublicSubnet2NATGateway9B8AE11A": {
+   "Type": "AWS::EC2::NatGateway",
+   "Properties": {
+    "AllocationId": {
+     "Fn::GetAtt": [
+      "vpcPublicSubnet2EIP9B3743B1",
+      "AllocationId"
+     ]
+    },
+    "SubnetId": {
+     "Ref": "vpcPublicSubnet2Subnet009B674F"
+    },
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2"
+     }
+    ]
+   },
+   "DependsOn": [
+    "vpcPublicSubnet2DefaultRouteA1EC0F60",
+    "vpcPublicSubnet2RouteTableAssociation21F81B59"
+   ]
+  },
+  "vpcPrivateSubnet1Subnet934893E8": {
+   "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": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "vpcPrivateSubnet1RouteTableB41A48CC": {
+   "Type": "AWS::EC2::RouteTable",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "vpcPrivateSubnet1RouteTableAssociation67945127": {
+   "Type": "AWS::EC2::SubnetRouteTableAssociation",
+   "Properties": {
+    "RouteTableId": {
+     "Ref": "vpcPrivateSubnet1RouteTableB41A48CC"
+    },
+    "SubnetId": {
+     "Ref": "vpcPrivateSubnet1Subnet934893E8"
+    }
+   }
+  },
+  "vpcPrivateSubnet1DefaultRoute1AA8E2E5": {
+   "Type": "AWS::EC2::Route",
+   "Properties": {
+    "DestinationCidrBlock": "0.0.0.0/0",
+    "NatGatewayId": {
+     "Ref": "vpcPublicSubnet1NATGateway9C16659E"
+    },
+    "RouteTableId": {
+     "Ref": "vpcPrivateSubnet1RouteTableB41A48CC"
+    }
+   }
+  },
+  "vpcPrivateSubnet2Subnet7031C2BA": {
+   "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": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "vpcPrivateSubnet2RouteTable7280F23E": {
+   "Type": "AWS::EC2::RouteTable",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "vpcPrivateSubnet2RouteTableAssociation007E94D3": {
+   "Type": "AWS::EC2::SubnetRouteTableAssociation",
+   "Properties": {
+    "RouteTableId": {
+     "Ref": "vpcPrivateSubnet2RouteTable7280F23E"
+    },
+    "SubnetId": {
+     "Ref": "vpcPrivateSubnet2Subnet7031C2BA"
+    }
+   }
+  },
+  "vpcPrivateSubnet2DefaultRouteB0E07F99": {
+   "Type": "AWS::EC2::Route",
+   "Properties": {
+    "DestinationCidrBlock": "0.0.0.0/0",
+    "NatGatewayId": {
+     "Ref": "vpcPublicSubnet2NATGateway9B8AE11A"
+    },
+    "RouteTableId": {
+     "Ref": "vpcPrivateSubnet2RouteTable7280F23E"
+    }
+   }
+  },
+  "vpcIGWE57CBDCA": {
+   "Type": "AWS::EC2::InternetGateway",
+   "Properties": {
+    "Tags": [
+     {
+      "Key": "Name",
+      "Value": "aws-cdk-rds-proxy-mariadb/vpc"
+     }
+    ]
+   }
+  },
+  "vpcVPCGW7984C166": {
+   "Type": "AWS::EC2::VPCGatewayAttachment",
+   "Properties": {
+    "InternetGatewayId": {
+     "Ref": "vpcIGWE57CBDCA"
+    },
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "SecretEncryptionKey40C82244": {
+   "Type": "AWS::KMS::Key",
+   "Properties": {
+    "KeyPolicy": {
+     "Statement": [
+      {
+       "Action": "kms:*",
+       "Effect": "Allow",
+       "Principal": {
+        "AWS": {
+         "Fn::Join": [
+          "",
+          [
+           "arn:",
+           {
+            "Ref": "AWS::Partition"
+           },
+           ":iam::",
+           {
+            "Ref": "AWS::AccountId"
+           },
+           ":root"
+          ]
+         ]
+        }
+       },
+       "Resource": "*"
+      },
+      {
+       "Action": [
+        "kms:CreateGrant",
+        "kms:Decrypt",
+        "kms:DescribeKey",
+        "kms:Encrypt",
+        "kms:GenerateDataKey*",
+        "kms:ReEncrypt*"
+       ],
+       "Condition": {
+        "StringEquals": {
+         "kms:ViaService": {
+          "Fn::Join": [
+           "",
+           [
+            "secretsmanager.",
+            {
+             "Ref": "AWS::Region"
+            },
+            ".amazonaws.com"
+           ]
+          ]
+         }
+        }
+       },
+       "Effect": "Allow",
+       "Principal": {
+        "AWS": {
+         "Fn::Join": [
+          "",
+          [
+           "arn:",
+           {
+            "Ref": "AWS::Partition"
+           },
+           ":iam::",
+           {
+            "Ref": "AWS::AccountId"
+           },
+           ":root"
+          ]
+         ]
+        }
+       },
+       "Resource": "*"
+      },
+      {
+       "Action": "kms:Decrypt",
+       "Condition": {
+        "StringEquals": {
+         "kms:ViaService": {
+          "Fn::Join": [
+           "",
+           [
+            "secretsmanager.",
+            {
+             "Ref": "AWS::Region"
+            },
+            ".amazonaws.com"
+           ]
+          ]
+         }
+        }
+       },
+       "Effect": "Allow",
+       "Principal": {
+        "AWS": {
+         "Fn::GetAtt": [
+          "mariaDBProxyIAMRoleB91DE271",
+          "Arn"
+         ]
+        }
+       },
+       "Resource": "*"
+      }
+     ],
+     "Version": "2012-10-17"
+    }
+   },
+   "UpdateReplacePolicy": "Retain",
+   "DeletionPolicy": "Retain"
+  },
+  "mariaDBInstanceSubnetGroupA17E5651": {
+   "Type": "AWS::RDS::DBSubnetGroup",
+   "Properties": {
+    "DBSubnetGroupDescription": "Subnet group for mariaDBInstance database",
+    "SubnetIds": [
+     {
+      "Ref": "vpcPrivateSubnet1Subnet934893E8"
+     },
+     {
+      "Ref": "vpcPrivateSubnet2Subnet7031C2BA"
+     }
+    ]
+   }
+  },
+  "mariaDBInstanceSecurityGroup1C05EFED": {
+   "Type": "AWS::EC2::SecurityGroup",
+   "Properties": {
+    "GroupDescription": "Security group for mariaDBInstance database",
+    "SecurityGroupEgress": [
+     {
+      "CidrIp": "0.0.0.0/0",
+      "Description": "Allow all outbound traffic by default",
+      "IpProtocol": "-1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "mariaDBInstanceSecurityGroupfromawscdkrdsproxymariadbmariaDBProxyProxySecurityGroup4F55583FIndirectPort44A97795": {
+   "Type": "AWS::EC2::SecurityGroupIngress",
+   "Properties": {
+    "Description": "Allow connections to the database Instance from the Proxy",
+    "FromPort": {
+     "Fn::GetAtt": [
+      "mariaDBInstance7DFDB9B1",
+      "Endpoint.Port"
+     ]
+    },
+    "GroupId": {
+     "Fn::GetAtt": [
+      "mariaDBInstanceSecurityGroup1C05EFED",
+      "GroupId"
+     ]
+    },
+    "IpProtocol": "tcp",
+    "SourceSecurityGroupId": {
+     "Fn::GetAtt": [
+      "mariaDBProxyProxySecurityGroupFD730755",
+      "GroupId"
+     ]
+    },
+    "ToPort": {
+     "Fn::GetAtt": [
+      "mariaDBInstance7DFDB9B1",
+      "Endpoint.Port"
+     ]
+    }
+   }
+  },
+  "mariaDBInstanceSecretED322D85": {
+   "Type": "AWS::SecretsManager::Secret",
+   "Properties": {
+    "Description": {
+     "Fn::Join": [
+      "",
+      [
+       "Generated by the CDK for stack: ",
+       {
+        "Ref": "AWS::StackName"
+       }
+      ]
+     ]
+    },
+    "GenerateSecretString": {
+     "ExcludeCharacters": "\"@/\\",
+     "GenerateStringKey": "password",
+     "PasswordLength": 30,
+     "SecretStringTemplate": "{\"username\":\"master\"}"
+    },
+    "KmsKeyId": {
+     "Fn::GetAtt": [
+      "SecretEncryptionKey40C82244",
+      "Arn"
+     ]
+    }
+   },
+   "UpdateReplacePolicy": "Delete",
+   "DeletionPolicy": "Delete"
+  },
+  "mariaDBInstanceSecretAttachment900E3C52": {
+   "Type": "AWS::SecretsManager::SecretTargetAttachment",
+   "Properties": {
+    "SecretId": {
+     "Ref": "mariaDBInstanceSecretED322D85"
+    },
+    "TargetId": {
+     "Ref": "mariaDBInstance7DFDB9B1"
+    },
+    "TargetType": "AWS::RDS::DBInstance"
+   }
+  },
+  "mariaDBInstance7DFDB9B1": {
+   "Type": "AWS::RDS::DBInstance",
+   "Properties": {
+    "AllocatedStorage": "100",
+    "CopyTagsToSnapshot": true,
+    "DBInstanceClass": "db.t3.medium",
+    "DBSubnetGroupName": {
+     "Ref": "mariaDBInstanceSubnetGroupA17E5651"
+    },
+    "Engine": "mariadb",
+    "EngineVersion": "10.6.16",
+    "MasterUserPassword": {
+     "Fn::Join": [
+      "",
+      [
+       "{{resolve:secretsmanager:",
+       {
+        "Ref": "mariaDBInstanceSecretED322D85"
+       },
+       ":SecretString:password::}}"
+      ]
+     ]
+    },
+    "MasterUsername": {
+     "Fn::Join": [
+      "",
+      [
+       "{{resolve:secretsmanager:",
+       {
+        "Ref": "mariaDBInstanceSecretED322D85"
+       },
+       ":SecretString:username::}}"
+      ]
+     ]
+    },
+    "StorageType": "gp2",
+    "VPCSecurityGroups": [
+     {
+      "Fn::GetAtt": [
+       "mariaDBInstanceSecurityGroup1C05EFED",
+       "GroupId"
+      ]
+     }
+    ]
+   },
+   "UpdateReplacePolicy": "Delete",
+   "DeletionPolicy": "Delete"
+  },
+  "mariaDBProxyIAMRoleB91DE271": {
+   "Type": "AWS::IAM::Role",
+   "Properties": {
+    "AssumeRolePolicyDocument": {
+     "Statement": [
+      {
+       "Action": "sts:AssumeRole",
+       "Effect": "Allow",
+       "Principal": {
+        "Service": "rds.amazonaws.com"
+       }
+      }
+     ],
+     "Version": "2012-10-17"
+    }
+   }
+  },
+  "mariaDBProxyIAMRoleDefaultPolicyF4BE519B": {
+   "Type": "AWS::IAM::Policy",
+   "Properties": {
+    "PolicyDocument": {
+     "Statement": [
+      {
+       "Action": [
+        "secretsmanager:DescribeSecret",
+        "secretsmanager:GetSecretValue"
+       ],
+       "Effect": "Allow",
+       "Resource": {
+        "Ref": "mariaDBInstanceSecretAttachment900E3C52"
+       }
+      },
+      {
+       "Action": "kms:Decrypt",
+       "Effect": "Allow",
+       "Resource": {
+        "Fn::GetAtt": [
+         "SecretEncryptionKey40C82244",
+         "Arn"
+        ]
+       }
+      }
+     ],
+     "Version": "2012-10-17"
+    },
+    "PolicyName": "mariaDBProxyIAMRoleDefaultPolicyF4BE519B",
+    "Roles": [
+     {
+      "Ref": "mariaDBProxyIAMRoleB91DE271"
+     }
+    ]
+   }
+  },
+  "mariaDBProxyProxySecurityGroupFD730755": {
+   "Type": "AWS::EC2::SecurityGroup",
+   "Properties": {
+    "GroupDescription": "SecurityGroup for Database Proxy",
+    "SecurityGroupEgress": [
+     {
+      "CidrIp": "0.0.0.0/0",
+      "Description": "Allow all outbound traffic by default",
+      "IpProtocol": "-1"
+     }
+    ],
+    "VpcId": {
+     "Ref": "vpcA2121C38"
+    }
+   }
+  },
+  "mariaDBProxy23E8B2BB": {
+   "Type": "AWS::RDS::DBProxy",
+   "Properties": {
+    "Auth": [
+     {
+      "AuthScheme": "SECRETS",
+      "IAMAuth": "DISABLED",
+      "SecretArn": {
+       "Ref": "mariaDBInstanceSecretAttachment900E3C52"
+      }
+     }
+    ],
+    "DBProxyName": "awscdkrdsproxymariadbmariaDBProxyB0A701B2",
+    "EngineFamily": "MYSQL",
+    "RequireTLS": true,
+    "RoleArn": {
+     "Fn::GetAtt": [
+      "mariaDBProxyIAMRoleB91DE271",
+      "Arn"
+     ]
+    },
+    "VpcSecurityGroupIds": [
+     {
+      "Fn::GetAtt": [
+       "mariaDBProxyProxySecurityGroupFD730755",
+       "GroupId"
+      ]
+     }
+    ],
+    "VpcSubnetIds": [
+     {
+      "Ref": "vpcPrivateSubnet1Subnet934893E8"
+     },
+     {
+      "Ref": "vpcPrivateSubnet2Subnet7031C2BA"
+     }
+    ]
+   }
+  },
+  "mariaDBProxyProxyTargetGroup960ACB39": {
+   "Type": "AWS::RDS::DBProxyTargetGroup",
+   "Properties": {
+    "ConnectionPoolConfigurationInfo": {
+     "ConnectionBorrowTimeout": 30,
+     "MaxConnectionsPercent": 50
+    },
+    "DBInstanceIdentifiers": [
+     {
+      "Ref": "mariaDBInstance7DFDB9B1"
+     }
+    ],
+    "DBProxyName": {
+     "Ref": "mariaDBProxy23E8B2BB"
+    },
+    "TargetGroupName": "default"
+   }
+  }
+ },
+ "Parameters": {
+  "BootstrapVersion": {
+   "Type": "AWS::SSM::Parameter::Value<String>",
+   "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-rds/test/integ.proxy-mariadb.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/cdk.out
new file mode 100644
index 0000000000000..1f0068d32659a
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.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-rds/test/integ.proxy-mariadb.js.snapshot/databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.assets.json
new file mode 100644
index 0000000000000..1d4ef8153edea
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.assets.json
@@ -0,0 +1,19 @@
+{
+  "version": "36.0.0",
+  "files": {
+    "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
+      "source": {
+        "path": "databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.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-rds/test/integ.proxy-mariadb.js.snapshot/databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.template.json
new file mode 100644
index 0000000000000..ad9d0fb73d1dd
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.template.json
@@ -0,0 +1,36 @@
+{
+ "Parameters": {
+  "BootstrapVersion": {
+   "Type": "AWS::SSM::Parameter::Value<String>",
+   "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-rds/test/integ.proxy-mariadb.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/integ.json
new file mode 100644
index 0000000000000..227e6f88af581
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/integ.json
@@ -0,0 +1,20 @@
+{
+  "version": "36.0.0",
+  "testCases": {
+    "database-proxy-mariadb-integ-test/DefaultTest": {
+      "stacks": [
+        "aws-cdk-rds-proxy-mariadb"
+      ],
+      "diffAssets": true,
+      "cdkCommandOptions": {
+        "deploy": {
+          "args": {
+            "rollback": true
+          }
+        }
+      },
+      "assertionStack": "database-proxy-mariadb-integ-test/DefaultTest/DeployAssert",
+      "assertionStackName": "databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3"
+    }
+  }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/manifest.json
new file mode 100644
index 0000000000000..8b423ee7ee9ca
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/manifest.json
@@ -0,0 +1,317 @@
+{
+  "version": "36.0.0",
+  "artifacts": {
+    "aws-cdk-rds-proxy-mariadb.assets": {
+      "type": "cdk:asset-manifest",
+      "properties": {
+        "file": "aws-cdk-rds-proxy-mariadb.assets.json",
+        "requiresBootstrapStackVersion": 6,
+        "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
+      }
+    },
+    "aws-cdk-rds-proxy-mariadb": {
+      "type": "aws:cloudformation:stack",
+      "environment": "aws://unknown-account/unknown-region",
+      "properties": {
+        "templateFile": "aws-cdk-rds-proxy-mariadb.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}/f0fff306f7e137bbf1a002fa55210d252f5846dc8e753143422b180e68469441.json",
+        "requiresBootstrapStackVersion": 6,
+        "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
+        "additionalDependencies": [
+          "aws-cdk-rds-proxy-mariadb.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": [
+        "aws-cdk-rds-proxy-mariadb.assets"
+      ],
+      "metadata": {
+        "/aws-cdk-rds-proxy-mariadb/vpc/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcA2121C38"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/Subnet": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet1Subnet2E65531E"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/RouteTable": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet1RouteTable48A2DF9B"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/RouteTableAssociation": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet1RouteTableAssociation5D3F4579"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/DefaultRoute": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet1DefaultRoute10708846"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/EIP": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet1EIPDA49DCBE"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/NATGateway": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet1NATGateway9C16659E"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/Subnet": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet2Subnet009B674F"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/RouteTable": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet2RouteTableEB40D4CB"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/RouteTableAssociation": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet2RouteTableAssociation21F81B59"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/DefaultRoute": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet2DefaultRouteA1EC0F60"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/EIP": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet2EIP9B3743B1"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/NATGateway": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPublicSubnet2NATGateway9B8AE11A"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1/Subnet": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPrivateSubnet1Subnet934893E8"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1/RouteTable": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPrivateSubnet1RouteTableB41A48CC"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1/RouteTableAssociation": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPrivateSubnet1RouteTableAssociation67945127"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1/DefaultRoute": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPrivateSubnet1DefaultRoute1AA8E2E5"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2/Subnet": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPrivateSubnet2Subnet7031C2BA"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2/RouteTable": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPrivateSubnet2RouteTable7280F23E"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2/RouteTableAssociation": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPrivateSubnet2RouteTableAssociation007E94D3"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2/DefaultRoute": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcPrivateSubnet2DefaultRouteB0E07F99"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/IGW": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcIGWE57CBDCA"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/vpc/VPCGW": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "vpcVPCGW7984C166"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/SecretEncryptionKey/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "SecretEncryptionKey40C82244"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBInstance/SubnetGroup/Default": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBInstanceSubnetGroupA17E5651"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBInstance/SecurityGroup/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBInstanceSecurityGroup1C05EFED"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBInstance/SecurityGroup/from awscdkrdsproxymariadbmariaDBProxyProxySecurityGroup4F55583F:{IndirectPort}": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBInstanceSecurityGroupfromawscdkrdsproxymariadbmariaDBProxyProxySecurityGroup4F55583FIndirectPort44A97795"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBInstance/Secret/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBInstanceSecretED322D85"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBInstance/Secret/Attachment/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBInstanceSecretAttachment900E3C52"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBInstance/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBInstance7DFDB9B1"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBProxy/IAMRole/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBProxyIAMRoleB91DE271"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBProxy/IAMRole/DefaultPolicy/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBProxyIAMRoleDefaultPolicyF4BE519B"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBProxy/ProxySecurityGroup/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBProxyProxySecurityGroupFD730755"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBProxy/Resource": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBProxy23E8B2BB"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/mariaDBProxy/ProxyTargetGroup": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "mariaDBProxyProxyTargetGroup960ACB39"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/BootstrapVersion": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "BootstrapVersion"
+          }
+        ],
+        "/aws-cdk-rds-proxy-mariadb/CheckBootstrapVersion": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "CheckBootstrapVersion"
+          }
+        ]
+      },
+      "displayName": "aws-cdk-rds-proxy-mariadb"
+    },
+    "databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.assets": {
+      "type": "cdk:asset-manifest",
+      "properties": {
+        "file": "databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.assets.json",
+        "requiresBootstrapStackVersion": 6,
+        "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version"
+      }
+    },
+    "databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3": {
+      "type": "aws:cloudformation:stack",
+      "environment": "aws://unknown-account/unknown-region",
+      "properties": {
+        "templateFile": "databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.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": [
+          "databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.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": [
+        "databaseproxymariadbintegtestDefaultTestDeployAssert9D9B7FF3.assets"
+      ],
+      "metadata": {
+        "/database-proxy-mariadb-integ-test/DefaultTest/DeployAssert/BootstrapVersion": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "BootstrapVersion"
+          }
+        ],
+        "/database-proxy-mariadb-integ-test/DefaultTest/DeployAssert/CheckBootstrapVersion": [
+          {
+            "type": "aws:cdk:logicalId",
+            "data": "CheckBootstrapVersion"
+          }
+        ]
+      },
+      "displayName": "database-proxy-mariadb-integ-test/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-rds/test/integ.proxy-mariadb.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/tree.json
new file mode 100644
index 0000000000000..b0c1987a150b8
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.js.snapshot/tree.json
@@ -0,0 +1,1329 @@
+{
+  "version": "tree-0.1",
+  "tree": {
+    "id": "App",
+    "path": "",
+    "children": {
+      "aws-cdk-rds-proxy-mariadb": {
+        "id": "aws-cdk-rds-proxy-mariadb",
+        "path": "aws-cdk-rds-proxy-mariadb",
+        "children": {
+          "vpc": {
+            "id": "vpc",
+            "path": "aws-cdk-rds-proxy-mariadb/vpc",
+            "children": {
+              "Resource": {
+                "id": "Resource",
+                "path": "aws-cdk-rds-proxy-mariadb/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": "aws-cdk-rds-proxy-mariadb/vpc"
+                      }
+                    ]
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "PublicSubnet1": {
+                "id": "PublicSubnet1",
+                "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1",
+                "children": {
+                  "Subnet": {
+                    "id": "Subnet",
+                    "path": "aws-cdk-rds-proxy-mariadb/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": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "Acl": {
+                    "id": "Acl",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/Acl",
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "RouteTable": {
+                    "id": "RouteTable",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/RouteTable",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+                      "aws:cdk:cloudformation:props": {
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "RouteTableAssociation": {
+                    "id": "RouteTableAssociation",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/RouteTableAssociation",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+                      "aws:cdk:cloudformation:props": {
+                        "routeTableId": {
+                          "Ref": "vpcPublicSubnet1RouteTable48A2DF9B"
+                        },
+                        "subnetId": {
+                          "Ref": "vpcPublicSubnet1Subnet2E65531E"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "DefaultRoute": {
+                    "id": "DefaultRoute",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/DefaultRoute",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+                      "aws:cdk:cloudformation:props": {
+                        "destinationCidrBlock": "0.0.0.0/0",
+                        "gatewayId": {
+                          "Ref": "vpcIGWE57CBDCA"
+                        },
+                        "routeTableId": {
+                          "Ref": "vpcPublicSubnet1RouteTable48A2DF9B"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "EIP": {
+                    "id": "EIP",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/EIP",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::EIP",
+                      "aws:cdk:cloudformation:props": {
+                        "domain": "vpc",
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1"
+                          }
+                        ]
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "NATGateway": {
+                    "id": "NATGateway",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1/NATGateway",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway",
+                      "aws:cdk:cloudformation:props": {
+                        "allocationId": {
+                          "Fn::GetAtt": [
+                            "vpcPublicSubnet1EIPDA49DCBE",
+                            "AllocationId"
+                          ]
+                        },
+                        "subnetId": {
+                          "Ref": "vpcPublicSubnet1Subnet2E65531E"
+                        },
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet1"
+                          }
+                        ]
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "PublicSubnet2": {
+                "id": "PublicSubnet2",
+                "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2",
+                "children": {
+                  "Subnet": {
+                    "id": "Subnet",
+                    "path": "aws-cdk-rds-proxy-mariadb/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": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "Acl": {
+                    "id": "Acl",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/Acl",
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "RouteTable": {
+                    "id": "RouteTable",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/RouteTable",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+                      "aws:cdk:cloudformation:props": {
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "RouteTableAssociation": {
+                    "id": "RouteTableAssociation",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/RouteTableAssociation",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+                      "aws:cdk:cloudformation:props": {
+                        "routeTableId": {
+                          "Ref": "vpcPublicSubnet2RouteTableEB40D4CB"
+                        },
+                        "subnetId": {
+                          "Ref": "vpcPublicSubnet2Subnet009B674F"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "DefaultRoute": {
+                    "id": "DefaultRoute",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/DefaultRoute",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+                      "aws:cdk:cloudformation:props": {
+                        "destinationCidrBlock": "0.0.0.0/0",
+                        "gatewayId": {
+                          "Ref": "vpcIGWE57CBDCA"
+                        },
+                        "routeTableId": {
+                          "Ref": "vpcPublicSubnet2RouteTableEB40D4CB"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "EIP": {
+                    "id": "EIP",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/EIP",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::EIP",
+                      "aws:cdk:cloudformation:props": {
+                        "domain": "vpc",
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2"
+                          }
+                        ]
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "NATGateway": {
+                    "id": "NATGateway",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2/NATGateway",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway",
+                      "aws:cdk:cloudformation:props": {
+                        "allocationId": {
+                          "Fn::GetAtt": [
+                            "vpcPublicSubnet2EIP9B3743B1",
+                            "AllocationId"
+                          ]
+                        },
+                        "subnetId": {
+                          "Ref": "vpcPublicSubnet2Subnet009B674F"
+                        },
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-cdk-rds-proxy-mariadb/vpc/PublicSubnet2"
+                          }
+                        ]
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "PrivateSubnet1": {
+                "id": "PrivateSubnet1",
+                "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1",
+                "children": {
+                  "Subnet": {
+                    "id": "Subnet",
+                    "path": "aws-cdk-rds-proxy-mariadb/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": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "Acl": {
+                    "id": "Acl",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1/Acl",
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "RouteTable": {
+                    "id": "RouteTable",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1/RouteTable",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+                      "aws:cdk:cloudformation:props": {
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "RouteTableAssociation": {
+                    "id": "RouteTableAssociation",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1/RouteTableAssociation",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+                      "aws:cdk:cloudformation:props": {
+                        "routeTableId": {
+                          "Ref": "vpcPrivateSubnet1RouteTableB41A48CC"
+                        },
+                        "subnetId": {
+                          "Ref": "vpcPrivateSubnet1Subnet934893E8"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "DefaultRoute": {
+                    "id": "DefaultRoute",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet1/DefaultRoute",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+                      "aws:cdk:cloudformation:props": {
+                        "destinationCidrBlock": "0.0.0.0/0",
+                        "natGatewayId": {
+                          "Ref": "vpcPublicSubnet1NATGateway9C16659E"
+                        },
+                        "routeTableId": {
+                          "Ref": "vpcPrivateSubnet1RouteTableB41A48CC"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "PrivateSubnet2": {
+                "id": "PrivateSubnet2",
+                "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2",
+                "children": {
+                  "Subnet": {
+                    "id": "Subnet",
+                    "path": "aws-cdk-rds-proxy-mariadb/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": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "Acl": {
+                    "id": "Acl",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2/Acl",
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "RouteTable": {
+                    "id": "RouteTable",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2/RouteTable",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable",
+                      "aws:cdk:cloudformation:props": {
+                        "tags": [
+                          {
+                            "key": "Name",
+                            "value": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "RouteTableAssociation": {
+                    "id": "RouteTableAssociation",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2/RouteTableAssociation",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation",
+                      "aws:cdk:cloudformation:props": {
+                        "routeTableId": {
+                          "Ref": "vpcPrivateSubnet2RouteTable7280F23E"
+                        },
+                        "subnetId": {
+                          "Ref": "vpcPrivateSubnet2Subnet7031C2BA"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "DefaultRoute": {
+                    "id": "DefaultRoute",
+                    "path": "aws-cdk-rds-proxy-mariadb/vpc/PrivateSubnet2/DefaultRoute",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::Route",
+                      "aws:cdk:cloudformation:props": {
+                        "destinationCidrBlock": "0.0.0.0/0",
+                        "natGatewayId": {
+                          "Ref": "vpcPublicSubnet2NATGateway9B8AE11A"
+                        },
+                        "routeTableId": {
+                          "Ref": "vpcPrivateSubnet2RouteTable7280F23E"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "IGW": {
+                "id": "IGW",
+                "path": "aws-cdk-rds-proxy-mariadb/vpc/IGW",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway",
+                  "aws:cdk:cloudformation:props": {
+                    "tags": [
+                      {
+                        "key": "Name",
+                        "value": "aws-cdk-rds-proxy-mariadb/vpc"
+                      }
+                    ]
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "VPCGW": {
+                "id": "VPCGW",
+                "path": "aws-cdk-rds-proxy-mariadb/vpc/VPCGW",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment",
+                  "aws:cdk:cloudformation:props": {
+                    "internetGatewayId": {
+                      "Ref": "vpcIGWE57CBDCA"
+                    },
+                    "vpcId": {
+                      "Ref": "vpcA2121C38"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "constructs.Construct",
+              "version": "10.3.0"
+            }
+          },
+          "SecretEncryptionKey": {
+            "id": "SecretEncryptionKey",
+            "path": "aws-cdk-rds-proxy-mariadb/SecretEncryptionKey",
+            "children": {
+              "Resource": {
+                "id": "Resource",
+                "path": "aws-cdk-rds-proxy-mariadb/SecretEncryptionKey/Resource",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::KMS::Key",
+                  "aws:cdk:cloudformation:props": {
+                    "keyPolicy": {
+                      "Statement": [
+                        {
+                          "Action": "kms:*",
+                          "Effect": "Allow",
+                          "Principal": {
+                            "AWS": {
+                              "Fn::Join": [
+                                "",
+                                [
+                                  "arn:",
+                                  {
+                                    "Ref": "AWS::Partition"
+                                  },
+                                  ":iam::",
+                                  {
+                                    "Ref": "AWS::AccountId"
+                                  },
+                                  ":root"
+                                ]
+                              ]
+                            }
+                          },
+                          "Resource": "*"
+                        },
+                        {
+                          "Action": [
+                            "kms:CreateGrant",
+                            "kms:Decrypt",
+                            "kms:DescribeKey",
+                            "kms:Encrypt",
+                            "kms:GenerateDataKey*",
+                            "kms:ReEncrypt*"
+                          ],
+                          "Condition": {
+                            "StringEquals": {
+                              "kms:ViaService": {
+                                "Fn::Join": [
+                                  "",
+                                  [
+                                    "secretsmanager.",
+                                    {
+                                      "Ref": "AWS::Region"
+                                    },
+                                    ".amazonaws.com"
+                                  ]
+                                ]
+                              }
+                            }
+                          },
+                          "Effect": "Allow",
+                          "Principal": {
+                            "AWS": {
+                              "Fn::Join": [
+                                "",
+                                [
+                                  "arn:",
+                                  {
+                                    "Ref": "AWS::Partition"
+                                  },
+                                  ":iam::",
+                                  {
+                                    "Ref": "AWS::AccountId"
+                                  },
+                                  ":root"
+                                ]
+                              ]
+                            }
+                          },
+                          "Resource": "*"
+                        },
+                        {
+                          "Action": "kms:Decrypt",
+                          "Condition": {
+                            "StringEquals": {
+                              "kms:ViaService": {
+                                "Fn::Join": [
+                                  "",
+                                  [
+                                    "secretsmanager.",
+                                    {
+                                      "Ref": "AWS::Region"
+                                    },
+                                    ".amazonaws.com"
+                                  ]
+                                ]
+                              }
+                            }
+                          },
+                          "Effect": "Allow",
+                          "Principal": {
+                            "AWS": {
+                              "Fn::GetAtt": [
+                                "mariaDBProxyIAMRoleB91DE271",
+                                "Arn"
+                              ]
+                            }
+                          },
+                          "Resource": "*"
+                        }
+                      ],
+                      "Version": "2012-10-17"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "constructs.Construct",
+              "version": "10.3.0"
+            }
+          },
+          "mariaDBInstance": {
+            "id": "mariaDBInstance",
+            "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance",
+            "children": {
+              "SubnetGroup": {
+                "id": "SubnetGroup",
+                "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/SubnetGroup",
+                "children": {
+                  "Default": {
+                    "id": "Default",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/SubnetGroup/Default",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::RDS::DBSubnetGroup",
+                      "aws:cdk:cloudformation:props": {
+                        "dbSubnetGroupDescription": "Subnet group for mariaDBInstance database",
+                        "subnetIds": [
+                          {
+                            "Ref": "vpcPrivateSubnet1Subnet934893E8"
+                          },
+                          {
+                            "Ref": "vpcPrivateSubnet2Subnet7031C2BA"
+                          }
+                        ]
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "SecurityGroup": {
+                "id": "SecurityGroup",
+                "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/SecurityGroup",
+                "children": {
+                  "Resource": {
+                    "id": "Resource",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/SecurityGroup/Resource",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup",
+                      "aws:cdk:cloudformation:props": {
+                        "groupDescription": "Security group for mariaDBInstance database",
+                        "securityGroupEgress": [
+                          {
+                            "cidrIp": "0.0.0.0/0",
+                            "description": "Allow all outbound traffic by default",
+                            "ipProtocol": "-1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "from awscdkrdsproxymariadbmariaDBProxyProxySecurityGroup4F55583F:{IndirectPort}": {
+                    "id": "from awscdkrdsproxymariadbmariaDBProxyProxySecurityGroup4F55583F:{IndirectPort}",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/SecurityGroup/from awscdkrdsproxymariadbmariaDBProxyProxySecurityGroup4F55583F:{IndirectPort}",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroupIngress",
+                      "aws:cdk:cloudformation:props": {
+                        "description": "Allow connections to the database Instance from the Proxy",
+                        "fromPort": {
+                          "Fn::GetAtt": [
+                            "mariaDBInstance7DFDB9B1",
+                            "Endpoint.Port"
+                          ]
+                        },
+                        "groupId": {
+                          "Fn::GetAtt": [
+                            "mariaDBInstanceSecurityGroup1C05EFED",
+                            "GroupId"
+                          ]
+                        },
+                        "ipProtocol": "tcp",
+                        "sourceSecurityGroupId": {
+                          "Fn::GetAtt": [
+                            "mariaDBProxyProxySecurityGroupFD730755",
+                            "GroupId"
+                          ]
+                        },
+                        "toPort": {
+                          "Fn::GetAtt": [
+                            "mariaDBInstance7DFDB9B1",
+                            "Endpoint.Port"
+                          ]
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "Secret": {
+                "id": "Secret",
+                "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/Secret",
+                "children": {
+                  "Resource": {
+                    "id": "Resource",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/Secret/Resource",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::SecretsManager::Secret",
+                      "aws:cdk:cloudformation:props": {
+                        "description": {
+                          "Fn::Join": [
+                            "",
+                            [
+                              "Generated by the CDK for stack: ",
+                              {
+                                "Ref": "AWS::StackName"
+                              }
+                            ]
+                          ]
+                        },
+                        "generateSecretString": {
+                          "passwordLength": 30,
+                          "secretStringTemplate": "{\"username\":\"master\"}",
+                          "generateStringKey": "password",
+                          "excludeCharacters": "\"@/\\"
+                        },
+                        "kmsKeyId": {
+                          "Fn::GetAtt": [
+                            "SecretEncryptionKey40C82244",
+                            "Arn"
+                          ]
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "Attachment": {
+                    "id": "Attachment",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/Secret/Attachment",
+                    "children": {
+                      "Resource": {
+                        "id": "Resource",
+                        "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/Secret/Attachment/Resource",
+                        "attributes": {
+                          "aws:cdk:cloudformation:type": "AWS::SecretsManager::SecretTargetAttachment",
+                          "aws:cdk:cloudformation:props": {
+                            "secretId": {
+                              "Ref": "mariaDBInstanceSecretED322D85"
+                            },
+                            "targetId": {
+                              "Ref": "mariaDBInstance7DFDB9B1"
+                            },
+                            "targetType": "AWS::RDS::DBInstance"
+                          }
+                        },
+                        "constructInfo": {
+                          "fqn": "constructs.Construct",
+                          "version": "10.3.0"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "Resource": {
+                "id": "Resource",
+                "path": "aws-cdk-rds-proxy-mariadb/mariaDBInstance/Resource",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::RDS::DBInstance",
+                  "aws:cdk:cloudformation:props": {
+                    "allocatedStorage": "100",
+                    "copyTagsToSnapshot": true,
+                    "dbInstanceClass": "db.t3.medium",
+                    "dbSubnetGroupName": {
+                      "Ref": "mariaDBInstanceSubnetGroupA17E5651"
+                    },
+                    "engine": "mariadb",
+                    "engineVersion": "10.6.16",
+                    "masterUsername": {
+                      "Fn::Join": [
+                        "",
+                        [
+                          "{{resolve:secretsmanager:",
+                          {
+                            "Ref": "mariaDBInstanceSecretED322D85"
+                          },
+                          ":SecretString:username::}}"
+                        ]
+                      ]
+                    },
+                    "masterUserPassword": {
+                      "Fn::Join": [
+                        "",
+                        [
+                          "{{resolve:secretsmanager:",
+                          {
+                            "Ref": "mariaDBInstanceSecretED322D85"
+                          },
+                          ":SecretString:password::}}"
+                        ]
+                      ]
+                    },
+                    "storageType": "gp2",
+                    "vpcSecurityGroups": [
+                      {
+                        "Fn::GetAtt": [
+                          "mariaDBInstanceSecurityGroup1C05EFED",
+                          "GroupId"
+                        ]
+                      }
+                    ]
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "constructs.Construct",
+              "version": "10.3.0"
+            }
+          },
+          "mariaDBProxy": {
+            "id": "mariaDBProxy",
+            "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy",
+            "children": {
+              "IAMRole": {
+                "id": "IAMRole",
+                "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/IAMRole",
+                "children": {
+                  "ImportIAMRole": {
+                    "id": "ImportIAMRole",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/IAMRole/ImportIAMRole",
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "Resource": {
+                    "id": "Resource",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/IAMRole/Resource",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::IAM::Role",
+                      "aws:cdk:cloudformation:props": {
+                        "assumeRolePolicyDocument": {
+                          "Statement": [
+                            {
+                              "Action": "sts:AssumeRole",
+                              "Effect": "Allow",
+                              "Principal": {
+                                "Service": "rds.amazonaws.com"
+                              }
+                            }
+                          ],
+                          "Version": "2012-10-17"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "DefaultPolicy": {
+                    "id": "DefaultPolicy",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/IAMRole/DefaultPolicy",
+                    "children": {
+                      "Resource": {
+                        "id": "Resource",
+                        "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/IAMRole/DefaultPolicy/Resource",
+                        "attributes": {
+                          "aws:cdk:cloudformation:type": "AWS::IAM::Policy",
+                          "aws:cdk:cloudformation:props": {
+                            "policyDocument": {
+                              "Statement": [
+                                {
+                                  "Action": [
+                                    "secretsmanager:DescribeSecret",
+                                    "secretsmanager:GetSecretValue"
+                                  ],
+                                  "Effect": "Allow",
+                                  "Resource": {
+                                    "Ref": "mariaDBInstanceSecretAttachment900E3C52"
+                                  }
+                                },
+                                {
+                                  "Action": "kms:Decrypt",
+                                  "Effect": "Allow",
+                                  "Resource": {
+                                    "Fn::GetAtt": [
+                                      "SecretEncryptionKey40C82244",
+                                      "Arn"
+                                    ]
+                                  }
+                                }
+                              ],
+                              "Version": "2012-10-17"
+                            },
+                            "policyName": "mariaDBProxyIAMRoleDefaultPolicyF4BE519B",
+                            "roles": [
+                              {
+                                "Ref": "mariaDBProxyIAMRoleB91DE271"
+                              }
+                            ]
+                          }
+                        },
+                        "constructInfo": {
+                          "fqn": "constructs.Construct",
+                          "version": "10.3.0"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "ProxySecurityGroup": {
+                "id": "ProxySecurityGroup",
+                "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/ProxySecurityGroup",
+                "children": {
+                  "Resource": {
+                    "id": "Resource",
+                    "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/ProxySecurityGroup/Resource",
+                    "attributes": {
+                      "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup",
+                      "aws:cdk:cloudformation:props": {
+                        "groupDescription": "SecurityGroup for Database Proxy",
+                        "securityGroupEgress": [
+                          {
+                            "cidrIp": "0.0.0.0/0",
+                            "description": "Allow all outbound traffic by default",
+                            "ipProtocol": "-1"
+                          }
+                        ],
+                        "vpcId": {
+                          "Ref": "vpcA2121C38"
+                        }
+                      }
+                    },
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "Resource": {
+                "id": "Resource",
+                "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/Resource",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::RDS::DBProxy",
+                  "aws:cdk:cloudformation:props": {
+                    "auth": [
+                      {
+                        "authScheme": "SECRETS",
+                        "iamAuth": "DISABLED",
+                        "secretArn": {
+                          "Ref": "mariaDBInstanceSecretAttachment900E3C52"
+                        }
+                      }
+                    ],
+                    "dbProxyName": "awscdkrdsproxymariadbmariaDBProxyB0A701B2",
+                    "engineFamily": "MYSQL",
+                    "requireTls": true,
+                    "roleArn": {
+                      "Fn::GetAtt": [
+                        "mariaDBProxyIAMRoleB91DE271",
+                        "Arn"
+                      ]
+                    },
+                    "vpcSecurityGroupIds": [
+                      {
+                        "Fn::GetAtt": [
+                          "mariaDBProxyProxySecurityGroupFD730755",
+                          "GroupId"
+                        ]
+                      }
+                    ],
+                    "vpcSubnetIds": [
+                      {
+                        "Ref": "vpcPrivateSubnet1Subnet934893E8"
+                      },
+                      {
+                        "Ref": "vpcPrivateSubnet2Subnet7031C2BA"
+                      }
+                    ]
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "ProxyTargetGroup": {
+                "id": "ProxyTargetGroup",
+                "path": "aws-cdk-rds-proxy-mariadb/mariaDBProxy/ProxyTargetGroup",
+                "attributes": {
+                  "aws:cdk:cloudformation:type": "AWS::RDS::DBProxyTargetGroup",
+                  "aws:cdk:cloudformation:props": {
+                    "connectionPoolConfigurationInfo": {
+                      "connectionBorrowTimeout": 30,
+                      "maxConnectionsPercent": 50
+                    },
+                    "dbInstanceIdentifiers": [
+                      {
+                        "Ref": "mariaDBInstance7DFDB9B1"
+                      }
+                    ],
+                    "dbProxyName": {
+                      "Ref": "mariaDBProxy23E8B2BB"
+                    },
+                    "targetGroupName": "default"
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              }
+            },
+            "constructInfo": {
+              "fqn": "constructs.Construct",
+              "version": "10.3.0"
+            }
+          },
+          "BootstrapVersion": {
+            "id": "BootstrapVersion",
+            "path": "aws-cdk-rds-proxy-mariadb/BootstrapVersion",
+            "constructInfo": {
+              "fqn": "constructs.Construct",
+              "version": "10.3.0"
+            }
+          },
+          "CheckBootstrapVersion": {
+            "id": "CheckBootstrapVersion",
+            "path": "aws-cdk-rds-proxy-mariadb/CheckBootstrapVersion",
+            "constructInfo": {
+              "fqn": "constructs.Construct",
+              "version": "10.3.0"
+            }
+          }
+        },
+        "constructInfo": {
+          "fqn": "constructs.Construct",
+          "version": "10.3.0"
+        }
+      },
+      "database-proxy-mariadb-integ-test": {
+        "id": "database-proxy-mariadb-integ-test",
+        "path": "database-proxy-mariadb-integ-test",
+        "children": {
+          "DefaultTest": {
+            "id": "DefaultTest",
+            "path": "database-proxy-mariadb-integ-test/DefaultTest",
+            "children": {
+              "Default": {
+                "id": "Default",
+                "path": "database-proxy-mariadb-integ-test/DefaultTest/Default",
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.0"
+                }
+              },
+              "DeployAssert": {
+                "id": "DeployAssert",
+                "path": "database-proxy-mariadb-integ-test/DefaultTest/DeployAssert",
+                "children": {
+                  "BootstrapVersion": {
+                    "id": "BootstrapVersion",
+                    "path": "database-proxy-mariadb-integ-test/DefaultTest/DeployAssert/BootstrapVersion",
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  },
+                  "CheckBootstrapVersion": {
+                    "id": "CheckBootstrapVersion",
+                    "path": "database-proxy-mariadb-integ-test/DefaultTest/DeployAssert/CheckBootstrapVersion",
+                    "constructInfo": {
+                      "fqn": "constructs.Construct",
+                      "version": "10.3.0"
+                    }
+                  }
+                },
+                "constructInfo": {
+                  "fqn": "constructs.Construct",
+                  "version": "10.3.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": "constructs.Construct",
+      "version": "10.3.0"
+    }
+  }
+}
\ No newline at end of file
diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.ts
new file mode 100644
index 0000000000000..c49d0a53ca66c
--- /dev/null
+++ b/packages/@aws-cdk-testing/framework-integ/test/aws-rds/test/integ.proxy-mariadb.ts
@@ -0,0 +1,45 @@
+import * as ec2 from 'aws-cdk-lib/aws-ec2';
+import * as cdk from 'aws-cdk-lib';
+import { RemovalPolicy } from 'aws-cdk-lib';
+import * as integ from '@aws-cdk/integ-tests-alpha';
+import * as kms from 'aws-cdk-lib/aws-kms';
+import * as rds from 'aws-cdk-lib/aws-rds';
+
+const app = new cdk.App();
+const stack = new cdk.Stack(app, 'aws-cdk-rds-proxy-mariadb');
+
+const vpc = new ec2.Vpc(stack, 'vpc', { maxAzs: 2, restrictDefaultSecurityGroup: false });
+const kmsKey = new kms.Key(stack, 'SecretEncryptionKey');
+
+const mariaDBInstance = new rds.DatabaseInstance(stack, 'mariaDBInstance', {
+  engine: rds.DatabaseInstanceEngine.mariaDb({
+    version: rds.MariaDbEngineVersion.VER_10_6_16,
+  }),
+  instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MEDIUM),
+  credentials: rds.Credentials.fromUsername('master', {
+    encryptionKey: kmsKey,
+    excludeCharacters: '"@/\\',
+  }),
+  vpc,
+  removalPolicy: RemovalPolicy.DESTROY,
+});
+
+new rds.DatabaseProxy(stack, 'mariaDBProxy', {
+  borrowTimeout: cdk.Duration.seconds(30),
+  maxConnectionsPercent: 50,
+  secrets: [mariaDBInstance.secret!],
+  proxyTarget: rds.ProxyTarget.fromInstance(mariaDBInstance),
+  vpc,
+});
+
+new integ.IntegTest(app, 'database-proxy-mariadb-integ-test', {
+  testCases: [stack],
+  diffAssets: true,
+  cdkCommandOptions: {
+    deploy: {
+      args: {
+        rollback: true,
+      },
+    },
+  },
+});
diff --git a/packages/aws-cdk-lib/aws-rds/README.md b/packages/aws-cdk-lib/aws-rds/README.md
index 20605a5463abd..7ee7a8df813dc 100644
--- a/packages/aws-cdk-lib/aws-rds/README.md
+++ b/packages/aws-cdk-lib/aws-rds/README.md
@@ -972,7 +972,9 @@ new rds.DatabaseCluster(this, 'dbcluster', {
 ## Creating a Database Proxy
 
 Amazon RDS Proxy sits between your application and your relational database to efficiently manage
-connections to the database and improve scalability of the application. Learn more about at [Amazon RDS Proxy](https://aws.amazon.com/rds/proxy/)
+connections to the database and improve scalability of the application. Learn more about at [Amazon RDS Proxy](https://aws.amazon.com/rds/proxy/). 
+
+RDS Proxy is supported for MySQL, MariaDB, Postgres, and SQL Server.
 
 The following code configures an RDS Proxy for a `DatabaseInstance`.
 
diff --git a/packages/aws-cdk-lib/aws-rds/lib/instance-engine.ts b/packages/aws-cdk-lib/aws-rds/lib/instance-engine.ts
index 3774347e21e61..d705b9494a4fd 100644
--- a/packages/aws-cdk-lib/aws-rds/lib/instance-engine.ts
+++ b/packages/aws-cdk-lib/aws-rds/lib/instance-engine.ts
@@ -570,6 +570,7 @@ class MariaDbInstanceEngine extends InstanceEngineBase {
           majorVersion: version.mariaDbMajorVersion,
         }
         : undefined,
+      engineFamily: 'MYSQL',
     });
   }
 
diff --git a/packages/aws-cdk-lib/aws-rds/test/proxy.test.ts b/packages/aws-cdk-lib/aws-rds/test/proxy.test.ts
index 970f13b09908d..7c1d76a68a416 100644
--- a/packages/aws-cdk-lib/aws-rds/test/proxy.test.ts
+++ b/packages/aws-cdk-lib/aws-rds/test/proxy.test.ts
@@ -79,6 +79,67 @@ describe('proxy', () => {
     });
   });
 
+  test('create a DB proxy for a MariaDB instance', () => {
+    // GIVEN
+    const instance = new rds.DatabaseInstance(stack, 'Instance', {
+      engine: rds.DatabaseInstanceEngine.mariaDb({
+        version: rds.MariaDbEngineVersion.VER_10_6_16,
+      }),
+      vpc,
+    });
+
+    // WHEN
+    new rds.DatabaseProxy(stack, 'Proxy', {
+      proxyTarget: rds.ProxyTarget.fromInstance(instance),
+      secrets: [instance.secret!],
+      vpc,
+    });
+
+    // THEN
+    Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBProxy', {
+      Auth: [
+        {
+          AuthScheme: 'SECRETS',
+          IAMAuth: 'DISABLED',
+          SecretArn: {
+            Ref: 'InstanceSecretAttachment83BEE581',
+          },
+        },
+      ],
+      DBProxyName: 'Proxy',
+      EngineFamily: 'MYSQL',
+      RequireTLS: true,
+      RoleArn: {
+        'Fn::GetAtt': [
+          'ProxyIAMRole2FE8AB0F',
+          'Arn',
+        ],
+      },
+      VpcSubnetIds: [
+        {
+          Ref: 'VPCPrivateSubnet1Subnet8BCA10E0',
+        },
+        {
+          Ref: 'VPCPrivateSubnet2SubnetCFCDAA7A',
+        },
+      ],
+    });
+
+    // THEN
+    Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBProxyTargetGroup', {
+      DBProxyName: {
+        Ref: 'ProxyCB0DFB71',
+      },
+      ConnectionPoolConfigurationInfo: {},
+      DBInstanceIdentifiers: [
+        {
+          Ref: 'InstanceC1063A87',
+        },
+      ],
+      TargetGroupName: 'default',
+    });
+  });
+
   test('create a DB proxy from a cluster', () => {
     // GIVEN
     const cluster = new rds.DatabaseCluster(stack, 'Database', {
@@ -192,8 +253,8 @@ describe('proxy', () => {
       instanceEndpointAddress: 'instance-address',
       port: 5432,
       securityGroups: [],
-      engine: rds.DatabaseInstanceEngine.mariaDb({
-        version: rds.MariaDbEngineVersion.VER_10_0_24,
+      engine: rds.DatabaseInstanceEngine.oracleEe({
+        version: rds.OracleEngineVersion.VER_21,
       }),
     });
 
@@ -203,7 +264,7 @@ describe('proxy', () => {
         vpc,
         secrets: [new secretsmanager.Secret(stack, 'Secret')],
       });
-    }).toThrow(/RDS proxies require an engine family to be specified on the database cluster or instance. No family specified for engine 'mariadb-10\.0\.24'/);
+    }).toThrow(/RDS proxies require an engine family to be specified on the database cluster or instance. No family specified for engine 'oracle-ee-21'/);
   });
 
   test('correctly creates a proxy for an imported Cluster if its engine is known', () => {