Skip to content

Commit

Permalink
feat(ec2): natGateways=0 disables private subnets (#8817)
Browse files Browse the repository at this point in the history
**[ISSUE]**
If `natGateways: 0` in VPC but with no subnet configuration. If 0 NAT gateways, private subnets are effectively isolated subnets so it would be a *nice-to-have* to allow this configuration to construct without errors.

**[APPROACH]**
Added another default subnet configuration called `DEFAULT_SUBNET_NO_NAT` that does an even split of Public and Isolated Subnets. 
Added a check before `subnetConfiguration` to determine which is 'default' configuration to use.

**[NOTE]**
Previous use cases should be untouched, changes adjust for our customers' requests to allow for easy configuration. 

Closes #4814

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
BryanPan342 committed Jul 1, 2020
1 parent dfac0df commit 7f432ff
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
8 changes: 5 additions & 3 deletions packages/@aws-cdk/aws-ec2/README.md
Expand Up @@ -48,9 +48,11 @@ distinguishes three different subnet types:
connected to from other instances in the same VPC. A default VPC configuration
will not include isolated subnets,

A default VPC configuration will create public and private subnets, but not
isolated subnets. See *Advanced Subnet Configuration* below for information
on how to change the default subnet configuration.

A default VPC configuration will create public and **private** subnets. However, if
`natGateways:0` **and** `subnetConfiguration` is undefined, default VPC configuration
will create public and **isolated** subnets. See [*Advanced Subnet Configuration*](#advanced-subnet-configuration)
below for information on how to change the default subnet configuration.

Constructs using the VPC will "launch instances" (or more accurately, create
Elastic Network Interfaces) into one or more of the subnets. They all accept
Expand Down
19 changes: 18 additions & 1 deletion packages/@aws-cdk/aws-ec2/lib/vpc.ts
Expand Up @@ -968,6 +968,22 @@ export class Vpc extends VpcBase {
},
];

/**
* The default subnet configuration if natGateways specified to be 0
*
* 1 Public and 1 Isolated Subnet per AZ evenly split
*/
public static readonly DEFAULT_SUBNETS_NO_NAT: SubnetConfiguration[] = [
{
subnetType: SubnetType.PUBLIC,
name: defaultSubnetName(SubnetType.PUBLIC),
},
{
subnetType: SubnetType.ISOLATED,
name: defaultSubnetName(SubnetType.ISOLATED),
},
];

/**
* Import an exported VPC
*/
Expand Down Expand Up @@ -1152,7 +1168,8 @@ export class Vpc extends VpcBase {

this.vpcId = this.resource.ref;

this.subnetConfiguration = ifUndefined(props.subnetConfiguration, Vpc.DEFAULT_SUBNETS);
const defaultSubnet = props.natGateways === 0 ? Vpc.DEFAULT_SUBNETS_NO_NAT : Vpc.DEFAULT_SUBNETS;
this.subnetConfiguration = ifUndefined(props.subnetConfiguration, defaultSubnet);

const natGatewayPlacement = props.natGatewaySubnets || { subnetType: SubnetType.PUBLIC };
const natGatewayCount = determineNatGatewayCount(props.natGateways, this.subnetConfiguration, this.availabilityZones.length);
Expand Down
34 changes: 33 additions & 1 deletion packages/@aws-cdk/aws-ec2/test/vpc.test.ts
Expand Up @@ -417,17 +417,49 @@ nodeunitShim({
test.done();
},

'natGateways = 0 requires there to be no PRIVATE subnets'(test: Test) {
'natGateways = 0 throws if no PRIVATE subnets configured'(test: Test) {
const stack = getTestStack();
test.throws(() => {
new Vpc(stack, 'VPC', {
natGateways: 0,
subnetConfiguration: [
{
name: 'public',
subnetType: SubnetType.PUBLIC,
},
{
name: 'private',
subnetType: SubnetType.PRIVATE,
},
],
});
}, /make sure you don't configure any PRIVATE subnets/);
test.done();

},

'natGateway = 0 defaults with ISOLATED subnet'(test: Test) {
const stack = getTestStack();
new Vpc(stack, 'VPC', {
natGateways: 0,
});
expect(stack).to(haveResource('AWS::EC2::Subnet', hasTags([{
Key: 'aws-cdk:subnet-type',
Value: 'Isolated',
}])));
test.done();
},

'unspecified natGateways constructs with PRIVATE subnet'(test: Test) {
const stack = getTestStack();
new Vpc(stack, 'VPC');
expect(stack).to(haveResource('AWS::EC2::Subnet', hasTags([{
Key: 'aws-cdk:subnet-type',
Value: 'Private',
}])));
test.done();
},

'natGateways = 0 allows RESERVED PRIVATE subnets'(test: Test) {
const stack = getTestStack();
new Vpc(stack, 'VPC', {
Expand Down

0 comments on commit 7f432ff

Please sign in to comment.