Skip to content

Commit

Permalink
Merge branch 'master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Aug 10, 2020
2 parents 131069c + a311428 commit 112bfb7
Show file tree
Hide file tree
Showing 20 changed files with 373 additions and 136 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ You may also find help on these community resources:
and tag it with `aws-cdk`
* Come join the AWS CDK community on [Gitter](https://gitter.im/awslabs/aws-cdk)
* Talk in the CDK channel of the [AWS Developers Slack workspace](https://awsdevelopers.slack.com) (invite required)
* Check out the [partitions.io board](https://partitions.io/cdk)

### Roadmap

Expand Down
7 changes: 7 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,14 @@ export interface CloudFrontWebDistributionProps {

/**
* Unique identifier that specifies the AWS WAF web ACL to associate with this CloudFront distribution.
*
* To specify a web ACL created using the latest version of AWS WAF, use the ACL ARN, for example
* `arn:aws:wafv2:us-east-1:123456789012:global/webacl/ExampleWebACL/473e64fd-f30b-4765-81a0-62ad96dd167a`.
*
* To specify a web ACL created using AWS WAF Classic, use the ACL ID, for example `473e64fd-f30b-4765-81a0-62ad96dd167a`.
*
* @see https://docs.aws.amazon.com/waf/latest/developerguide/what-is-aws-waf.html
* @see https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateDistribution.html#API_CreateDistribution_RequestParameters.
*
* @default - No AWS Web Application Firewall web access control list (web ACL).
*/
Expand Down
18 changes: 18 additions & 0 deletions packages/@aws-cdk/aws-ec2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ itself to 2 Availability Zones.
Therefore, to get the VPC to spread over 3 or more availability zones, you
must specify the environment where the stack will be deployed.

You can gain full control over the availability zones selection strategy by overriding the Stack's [`get availabilityZones()`](https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/core/lib/stack.ts) method:

```ts
class MyStack extends Stack {

get availabilityZones(): string[] {
return ['us-west-2a', 'us-west-2b'];
}

constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
...
}
}
```

Note that overriding the `get availabilityZones()` method will override the default behavior for all constructs defined within the Stack.

### Choosing subnets for resources

When creating resources that create Elastic Network Interfaces (such as
Expand Down
21 changes: 6 additions & 15 deletions packages/@aws-cdk/aws-ec2/lib/volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,14 +290,10 @@ export interface IVolume extends IResource {
* given the ability to AttachVolume if both the Volume and the destination Instance have that
* tag applied to them.
*
* If you need to call this method multiple times on different sets of constructs, then provide a
* unique `tagKeySuffix` for each call; failure to do so will result in an inability to attach this
* volume to some of the grants because it will overwrite the tag.
*
* @param grantee the principal being granted permission.
* @param constructs The list of constructs that will have the generated resource tag applied to them.
* @param tagKeySuffix A suffix to use on the generated Tag key in place of the generated hash value.
* Defaults to a hash calculated from this volume.
* Defaults to a hash calculated from this volume and list of constructs. (DEPRECATED)
*/
grantAttachVolumeByResourceTag(grantee: IGrantable, constructs: Construct[], tagKeySuffix?: string): Grant;

Expand All @@ -324,7 +320,7 @@ export interface IVolume extends IResource {
* @param grantee the principal being granted permission.
* @param constructs The list of constructs that will have the generated resource tag applied to them.
* @param tagKeySuffix A suffix to use on the generated Tag key in place of the generated hash value.
* Defaults to a hash calculated from this volume.
* Defaults to a hash calculated from this volume and list of constructs. (DEPRECATED)
*/
grantDetachVolumeByResourceTag(grantee: IGrantable, constructs: Construct[], tagKeySuffix?: string): Grant;
}
Expand Down Expand Up @@ -497,8 +493,8 @@ abstract class VolumeBase extends Resource implements IVolume {
}

public grantAttachVolumeByResourceTag(grantee: IGrantable, constructs: Construct[], tagKeySuffix?: string): Grant {
const tagKey = `VolumeGrantAttach-${tagKeySuffix ?? this.stringHash(this.node.uniqueId)}`;
const tagValue = this.calculateResourceTagValue(constructs);
const tagValue = this.calculateResourceTagValue([this, ...constructs]);
const tagKey = `VolumeGrantAttach-${tagKeySuffix ?? tagValue.slice(0,10).toUpperCase()}`;
const grantCondition: { [key: string]: string } = {};
grantCondition[`ec2:ResourceTag/${tagKey}`] = tagValue;

Expand Down Expand Up @@ -526,8 +522,8 @@ abstract class VolumeBase extends Resource implements IVolume {
}

public grantDetachVolumeByResourceTag(grantee: IGrantable, constructs: Construct[], tagKeySuffix?: string): Grant {
const tagKey = `VolumeGrantDetach-${tagKeySuffix ?? this.stringHash(this.node.uniqueId)}`;
const tagValue = this.calculateResourceTagValue(constructs);
const tagValue = this.calculateResourceTagValue([this, ...constructs]);
const tagKey = `VolumeGrantDetach-${tagKeySuffix ?? tagValue.slice(0,10).toUpperCase()}`;
const grantCondition: { [key: string]: string } = {};
grantCondition[`ec2:ResourceTag/${tagKey}`] = tagValue;

Expand Down Expand Up @@ -558,11 +554,6 @@ abstract class VolumeBase extends Resource implements IVolume {
return resourceArns;
}

private stringHash(value: string): string {
const md5 = crypto.createHash('md5').update(value).digest('hex');
return md5.slice(0, 8).toUpperCase();
}

private calculateResourceTagValue(constructs: Construct[]): string {
const md5 = crypto.createHash('md5');
constructs.forEach(construct => md5.update(construct.node.uniqueId));
Expand Down
34 changes: 16 additions & 18 deletions packages/@aws-cdk/aws-ec2/test/volume.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ nodeunitShim({
],
Condition: {
'ForAnyValue:StringEquals': {
'ec2:ResourceTag/VolumeGrantAttach-BD7A9717': 'd9a17c1c9e8ef6866e4dbeef41c741b2',
'ec2:ResourceTag/VolumeGrantAttach-B2376B2BDA': 'b2376b2bda65cb40f83c290dd844c4aa',
},
},
}],
Expand All @@ -748,17 +748,17 @@ nodeunitShim({
cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', {
Tags: [
{
Key: 'VolumeGrantAttach-BD7A9717',
Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2',
Key: 'VolumeGrantAttach-B2376B2BDA',
Value: 'b2376b2bda65cb40f83c290dd844c4aa',
},
],
}, ResourcePart.Properties));
cdkExpect(stack).to(haveResourceLike('AWS::EC2::Instance', {
Tags: [
{},
{
Key: 'VolumeGrantAttach-BD7A9717',
Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2',
Key: 'VolumeGrantAttach-B2376B2BDA',
Value: 'b2376b2bda65cb40f83c290dd844c4aa',
},
],
}, ResourcePart.Properties));
Expand Down Expand Up @@ -816,7 +816,7 @@ nodeunitShim({
],
Condition: {
'ForAnyValue:StringEquals': {
'ec2:ResourceTag/VolumeGrantAttach-TestSuffix': 'd9a17c1c9e8ef6866e4dbeef41c741b2',
'ec2:ResourceTag/VolumeGrantAttach-TestSuffix': 'b2376b2bda65cb40f83c290dd844c4aa',
},
},
}],
Expand All @@ -826,7 +826,7 @@ nodeunitShim({
Tags: [
{
Key: 'VolumeGrantAttach-TestSuffix',
Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2',
Value: 'b2376b2bda65cb40f83c290dd844c4aa',
},
],
}, ResourcePart.Properties));
Expand All @@ -835,11 +835,10 @@ nodeunitShim({
{},
{
Key: 'VolumeGrantAttach-TestSuffix',
Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2',
Value: 'b2376b2bda65cb40f83c290dd844c4aa',
},
],
}, ResourcePart.Properties));

test.done();
},

Expand Down Expand Up @@ -1051,7 +1050,7 @@ nodeunitShim({
],
Condition: {
'ForAnyValue:StringEquals': {
'ec2:ResourceTag/VolumeGrantDetach-BD7A9717': 'd9a17c1c9e8ef6866e4dbeef41c741b2',
'ec2:ResourceTag/VolumeGrantDetach-B2376B2BDA': 'b2376b2bda65cb40f83c290dd844c4aa',
},
},
}],
Expand All @@ -1060,17 +1059,17 @@ nodeunitShim({
cdkExpect(stack).to(haveResourceLike('AWS::EC2::Volume', {
Tags: [
{
Key: 'VolumeGrantDetach-BD7A9717',
Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2',
Key: 'VolumeGrantDetach-B2376B2BDA',
Value: 'b2376b2bda65cb40f83c290dd844c4aa',
},
],
}, ResourcePart.Properties));
cdkExpect(stack).to(haveResourceLike('AWS::EC2::Instance', {
Tags: [
{},
{
Key: 'VolumeGrantDetach-BD7A9717',
Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2',
Key: 'VolumeGrantDetach-B2376B2BDA',
Value: 'b2376b2bda65cb40f83c290dd844c4aa',
},
],
}, ResourcePart.Properties));
Expand Down Expand Up @@ -1128,7 +1127,7 @@ nodeunitShim({
],
Condition: {
'ForAnyValue:StringEquals': {
'ec2:ResourceTag/VolumeGrantDetach-TestSuffix': 'd9a17c1c9e8ef6866e4dbeef41c741b2',
'ec2:ResourceTag/VolumeGrantDetach-TestSuffix': 'b2376b2bda65cb40f83c290dd844c4aa',
},
},
}],
Expand All @@ -1138,7 +1137,7 @@ nodeunitShim({
Tags: [
{
Key: 'VolumeGrantDetach-TestSuffix',
Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2',
Value: 'b2376b2bda65cb40f83c290dd844c4aa',
},
],
}, ResourcePart.Properties));
Expand All @@ -1147,11 +1146,10 @@ nodeunitShim({
{},
{
Key: 'VolumeGrantDetach-TestSuffix',
Value: 'd9a17c1c9e8ef6866e4dbeef41c741b2',
Value: 'b2376b2bda65cb40f83c290dd844c4aa',
},
],
}, ResourcePart.Properties));

test.done();
},

Expand Down
30 changes: 28 additions & 2 deletions packages/@aws-cdk/aws-eks/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1018,13 +1018,20 @@ export class Cluster extends Resource implements ICluster {
};

if (!this.endpointAccess._config.publicAccess) {

const privateSubents = this.selectPrivateSubnets().slice(0, 16);

if (privateSubents.length === 0) {
throw new Error('Vpc must contain private subnets to configure private endpoint access');
}

// endpoint access is private only, we need to attach the
// provider to the VPC so that it can access the cluster.
providerProps = {
...providerProps,
vpc: this.vpc,
// lambda can only be accociated with max 16 subnets and they all need to be private.
vpcSubnets: {subnets: this.selectPrivateSubnets().slice(0, 16)},
vpcSubnets: {subnets: privateSubents},
securityGroups: [this.kubctlProviderSecurityGroup],
};
}
Expand All @@ -1049,7 +1056,26 @@ export class Cluster extends Resource implements ICluster {
const privateSubnets: ec2.ISubnet[] = [];

for (const placement of this.vpcSubnets) {
privateSubnets.push(...this.vpc.selectSubnets(placement).subnets.filter(s => s instanceof ec2.PrivateSubnet));

for (const subnet of this.vpc.selectSubnets(placement).subnets) {

if (this.vpc.privateSubnets.includes(subnet)) {
// definitely private, take it.
privateSubnets.push(subnet);
continue;
}

if (this.vpc.publicSubnets.includes(subnet)) {
// definitely public, skip it.
continue;
}

// neither public and nor private - what is it then? this means its a subnet instance that was explicitly passed
// in the subnet selection. since ISubnet doesn't contain information on type, we have to assume its private and let it
// fail at deploy time :\ (its better than filtering it out and preventing a possibly successful deployment)
privateSubnets.push(subnet);
}

}

return privateSubnets;
Expand Down
101 changes: 100 additions & 1 deletion packages/@aws-cdk/aws-eks/test/test.cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,105 @@ export = {

'endpoint access': {

'private endpoint access fails if selected subnets are empty'(test: Test) {

const { stack } = testFixture();

test.throws(() => {
new eks.Cluster(stack, 'Cluster', {
vpc: new ec2.Vpc(stack, 'Vpc'),
version: CLUSTER_VERSION,
endpointAccess: eks.EndpointAccess.PRIVATE,
vpcSubnets: [{ subnetType: ec2.SubnetType.PUBLIC }],
});
}, /Vpc must contain private subnets to configure private endpoint access/);

test.done();
},

'private endpoint access selects only private subnets from looked up vpc'(test: Test) {

const vpcId = 'vpc-12345';
// can't use the regular fixture because it also adds a VPC to the stack, which prevents
// us from setting context.
const stack = new cdk.Stack(new cdk.App(), 'Stack', {
env: {
account: '11112222',
region: 'us-east-1',
},
});
stack.node.setContext(`vpc-provider:account=${stack.account}:filter.vpc-id=${vpcId}:region=${stack.region}:returnAsymmetricSubnets=true`, {
vpcId: vpcId,
vpcCidrBlock: '10.0.0.0/16',
subnetGroups: [
{
name: 'Private',
type: 'Private',
subnets: [
{
subnetId: 'subnet-private-in-us-east-1a',
cidr: '10.0.1.0/24',
availabilityZone: 'us-east-1a',
routeTableId: 'rtb-06068e4c4049921ef',
},
],
},
{
name: 'Public',
type: 'Public',
subnets: [
{
subnetId: 'subnet-public-in-us-east-1c',
cidr: '10.0.0.0/24',
availabilityZone: 'us-east-1c',
routeTableId: 'rtb-0ff08e62195198dbb',
},
],
},
],
});
const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', {
vpcId: vpcId,
});

new eks.Cluster(stack, 'Cluster', {
vpc,
version: CLUSTER_VERSION,
endpointAccess: eks.EndpointAccess.PRIVATE,
});

const nested = stack.node.tryFindChild('@aws-cdk/aws-eks.KubectlProvider') as cdk.NestedStack;
const template = expect(nested).value;

test.deepEqual(template.Resources.Handler886CB40B.Properties.VpcConfig.SubnetIds, [
'subnet-private-in-us-east-1a',
]);

test.done();
},

'private endpoint access considers specific subnet selection'(test: Test) {
const { stack } = testFixture();
new eks.Cluster(stack, 'Cluster', {
version: CLUSTER_VERSION, endpointAccess:
eks.EndpointAccess.PRIVATE,
vpcSubnets: [{subnets: [ec2.PrivateSubnet.fromSubnetAttributes(stack, 'Private1', {
subnetId: 'subnet1',
availabilityZone: 'us-east-1a',
})]}],
});

const nested = stack.node.tryFindChild('@aws-cdk/aws-eks.KubectlProvider') as cdk.NestedStack;
const template = expect(nested).value;

test.deepEqual(template.Resources.Handler886CB40B.Properties.VpcConfig.SubnetIds, [
'subnet1',
]);

test.done();

},

'can configure private endpoint access'(test: Test) {
// GIVEN
const { stack } = testFixture();
Expand Down Expand Up @@ -1669,4 +1768,4 @@ export = {
},

},
};
};
Loading

0 comments on commit 112bfb7

Please sign in to comment.