VPC: allow configuring NAT instances instead of gateways (and a 0 NAT gateways bug)
See original GitHub issueWhen using ec2.VpcNetwork
the defaults are to create NAT gateways. I originally scoped this down to just creating a single NAT gateway for my public subnet, and a month later was slogged with a $90 AWS bill, with almost all of that cost attributed to the NAT gateway.
So today I decided to try and rework it to remove the NAT gateway (since my app really doesn’t need it anyway). Tried removing the key, but that uses the defaults (and makes more), so I tried setting the key to 0
. Example config:
const vpc = new ec2.VpcNetwork(this, 'Tokenized-VPC', {
natGateways: 0,
// natGatewayPlacement: {subnetName: 'Public'},
subnetConfiguration: [
{
cidrMask: 26,
name: 'Public',
subnetType: ec2.SubnetType.Public,
},
{
name: 'Application',
subnetType: ec2.SubnetType.Private,
},
],
defaultInstanceTenancy: ec2.DefaultInstanceTenancy.Default,
});
When I ran cdk diff
, I got a number of errors back
Exactly one of [NetworkInterfaceId, VpcPeeringConnectionId, GatewayId, EgressOnlyInternetGatewayId, InstanceId, NatGatewayId] must be specified and not empty
1/9 | 8:27:39 am | UPDATE_FAILED | AWS::EC2::Route | Foo-VPC/ApplicationSubnet2/DefaultRoute (FooVPCApplicationSubnet2DefaultRoute2325F2C6) Exactly one of [NetworkInterfaceId, VpcPeeringConnectionId, GatewayId, EgressOnlyInternetGatewayId, InstanceId, NatGatewayId] must be specified and not empty
VpcPrivateSubnet.addDefaultRouteToNAT (/foo/bar/deploy/aws-ec2/node_modules/@aws-cdk/aws-ec2/lib/vpc.js:259:9)
\_ VpcPrivateSubnet.addDefaultNatRouteEntry (/foo/bar/deploy/aws-ec2/node_modules/@aws-cdk/aws-ec2/lib/vpc.js:316:14)
\_ VpcNetwork.privateSubnets.forEach /foo/bar/deploy/aws-ec2/node_modules/@aws-cdk/aws-ec2/lib/vpc.js:127:31)
\_ Array.forEach (<anonymous>)
\_ new VpcNetwork (/foo/bar/deploy/aws-ec2/node_modules/@aws-cdk/aws-ec2/lib/vpc.js:120:33)
\_ new TokenizedEC2Stack (/foo/bar/deploy/aws-ec2/bin/tokenized.js:15:21)
\_ Object.<anonymous> (/foo/bar/deploy/aws-ec2/bin/tokenized.js:243:1)
\_ Module._compile (internal/modules/cjs/loader.js:689:30)
\_ Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
\_ Module.load (internal/modules/cjs/loader.js:599:32)
\_ tryModuleLoad (internal/modules/cjs/loader.js:538:12)
\_ Function.Module._load (internal/modules/cjs/loader.js:530:3)
\_ Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
\_ startup (internal/bootstrap/node.js:279:19)
\_ bootstrapNodeJSCore (internal/bootstrap/node.js:696:3)
This implies that there isn’t good support currently for when NAT gateways is 0 (may need to improve checks around things there), and as best as I could tell skimming the docs, there isn’t a great way to use VpcNetwork
without a NAT gateway.
Presumably I can use the override methods to ‘reach in’ and patch those keys manually, probably setting GatewayId/EgressOnlyInternetGatewayId it will probably work, but I was wondering if there is currently a ‘better’ solution than that when:
- I have a public subnet that I just want to connect directly to the net (and control connections through security groups, etc)
- I have a private subnet that only requires egress
It may be that most people using CDK have requirements greater than mine and/or don’t mind about the NAT gateway costs, but I feel like someone just playing around may be shockingly surprised at how much $$ the defaults end up costing them. Maybe some doco changes to call this out more explicitly? And/or an example that supports using methods other than the NAT gateway (eg. as mentioned above, or an example that shows how to set it up using the old way with a NAT instance so we can run it on a micro for tiny workloads without costing the world)
Issue Analytics
- State:
- Created 5 years ago
- Reactions:12
- Comments:25 (6 by maintainers)
Top GitHub Comments
Hi all. @rix0rrr, I believe the 0 NAT gateway issue is not fixed.
If I do
I get the following CDK error:
And if I do
I get the following CDK error:
What am I missing ?
This seems to be possible with a recent commit #4898 in version 1.16.0 thanks to rix0rrr.