question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

VPC: allow configuring NAT instances instead of gateways (and a 0 NAT gateways bug)

See original GitHub issue

When 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:closed
  • Created 5 years ago
  • Reactions:12
  • Comments:25 (6 by maintainers)

github_iconTop GitHub Comments

11reactions
ptitjescommented, Feb 12, 2020

Hi all. @rix0rrr, I believe the 0 NAT gateway issue is not fixed.

If I do

    const vpc = new Vpc(this, 'Vpc', {
      cidr: '10.0.0.0/16',
      maxAzs: 1,
      natGateways: 0,
    });

I get the following CDK error:

If you do not want NAT gateways (natGateways=0), make sure you don’t configure any PRIVATE subnets in ‘subnetConfiguration’ (make them PUBLIC or ISOLATED instead)

And if I do

    const vpc = new Vpc(this, 'Vpc', {
      cidr: '10.0.0.0/16',
      maxAzs: 1,
      natGateways: 0,
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'Public',
          subnetType: SubnetType.PUBLIC,
        }
      ],
    });

I get the following CDK error:

There are no ‘Private’ subnet groups in this VPC. Available types: Public

What am I missing ?

7reactions
travtarrcommented, Nov 17, 2019

This seems to be possible with a recent commit #4898 in version 1.16.0 thanks to rix0rrr.

new Vpc(this, `vpc`, {
  cidr: '10.40.0.0/16',
  maxAzs: 2,
  natGateways: 2,
  natGatewayProvider: NatProvider.instance({
    instanceType: InstanceType.of(InstanceClass.T3A, InstanceSize.NANO),
  }),
  gatewayEndpoints: {
    s3: { service: GatewayVpcEndpointAwsService.S3 },
  },
});
Read more comments on GitHub >

github_iconTop Results From Across the Web

Troubleshoot NAT gateways - Amazon Virtual Private Cloud
To view the error message, open the Amazon VPC console, and then choose NAT Gateways. Select the radio button for your NAT gateway,...
Read more >
Configured VPC NAT instances stopped working yesterday ...
Hi, I'm confronted with a really annoying problem currently. My custom VPC (3 public subnets, 3 private subnets -> internet access through ...
Read more >
AWS VPC NAT - NAT Gateway
NAT Gateway devices enables connectivity from instances in a private subnet to Internet, ... AWS allows NAT configuration in 2 ways.
Read more >
AWS NAT Gateways - Easy Cloud - Zendesk
You can use a network address translation (NAT) gateway to enable instances in a private subnet to connect to the internet or other...
Read more >
AWS EC2 Instance unable to use NAT Gateway
Check that the route tables are configured correctly. NAT gateway must be in public subnet with a route that directs all internet traffic...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found