Package: cdk-nat-asg-provider
CDK NAT ASG ProviderUse thisAWS Cloud Development Kit (CDK)library to configure and deploynetwork address translation (NAT) instancesindividually within their ownauto scaling group (ASG)to improve reliability and availability.Works with AWS CDKv2.ProblemAlthough theNAT gatewaysoffered by AWS have high availability, high bandwidth scalability, and minimal administration needs, they can be too expensive for small scale applications. A cheaper alternative, one that AWS mentions in its documentation but does not recommend, is to configure and manage your own NAT instances. One way of doing this is with the CDK usingNatInstanceProvider.import{aws_ec2asec2}from'aws-cdk-lib';//Factorymethodconstructsandconfiguresa`NatInstanceProvider`objectconstprovider=ec2.NatProvider.instance({instanceType:newec2.InstanceType('t2.micro'),});constvpc=newec2.Vpc(this,'Vpc',{natGatewayProvider:provider,});A major downside of this approach is that the created NAT instances will not be automatically replaced if they are stopped for whatever reason.SolutionTo provide better fault tolerance and availability, I implemented a NAT provider calledNatAsgProviderthat places each created NAT instance in its own ASG.import{aws_ec2asec2}from'aws-cdk-lib';import{NatAsgProvider}from'cdk-nat-asg-provider';constprovider=newNatAsgProvider({});constvpc=newec2.Vpc(this,'Vpc',{natGatewayProvider:provider,});LikeNatInstanceProvider,NatAsgProviderextendsNatProvider.How it worksThe number of NAT instances to create and the placement of those NAT instances is dictated by the configuration of the relevantVPCobject using the following configuration properties provided to theVPCconstructor:natGatewaySubnetsSelects the subnets that will have NAT instancesBy default, all public subnets are selectednatGatewaysThe number of NAT instances to createBy default, one NAT instance per AZAt a high-level, this is howNatAsgProviderachieves its purpose:Enables NAT in the EC2 instances, which are running Amazon Linux 2Places each NAT instance in its own ASG, configured by alaunch templateUsescfn-signalin conjunction with aCreationPolicyandUpdatePolicyto suspend work on the stack until the NAT instance signals successful creation or update, respectively, of its ASGAttaches an additionalelastic network interface (ENI)to each NAT instanceEach of these ENI is assigned anelastic IP (EIP) addressSets the default gateway to be the newly attached ENIInstallationTypeScript (npm)npminstallcdk-nat-asg-provideroryarninstallcdk-nat-asg-providerPython (PyPI)pipinstallcdk-nat-asg-providerUsageFor general usage, check out theAPI documentation.Example: Manual testing of NAT configurationI implemented a test environment similar to the one described in theAWS VPC docs. It allows you to manually check whether instances in private subnets can access the internet through the NAT instances by using the NAT instances as bastion servers.The implementation is insrc/manual.integ.ts. It's worth taking a look if you're confused about how to configureVpcandNatAsgProvider.Todeploythe manual integration test, execute theshscriptscripts/manual-integ-testand use thedeploycommand:./scripts/manual-integ-testdeploy<ACCOUNT><AWS_REGION><KEY_PAIR_NAME>[MAX_AZS]MAX_AZSis optional.Todestroythe manual integration test, execute the same script with same arguments using thedestroycommand:./scripts/manual-integ-testdestroy<ACCOUNT><AWS_REGION><KEY_PAIR_NAME>[MAX_AZS]Project configuration viaprojenprojensynthesizes and maintains project configuration. Most of the configuration files, such aspackage.json,.gitignore, and those defining Github Actions workflows, are managed byprojenand are read-only. To add, remove, or modify configuration files, edit.projenrc.jsand then runnpx projen. Check outprojen'sdocumentation websitefor more details.ContributingFeel free to open issues to report bugs or suggest features. Contributions via pull requests are much appreciated.LicenseReleased under theApache 2.0license.