Skip to content

Commit

Permalink
feat(ec2): Add tag support to security groups (#766)
Browse files Browse the repository at this point in the history
  • Loading branch information
moofish32 committed Sep 26, 2018
1 parent 8628b00 commit ac57507
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ function renderRollingUpdateConfig(config: RollingUpdateConfiguration = {}): cdk

class TagManager extends cdk.TagManager {
protected tagFormatResolve(tagGroups: cdk.TagGroups): any {
const tags = {...tagGroups.nonSitckyTags, ...tagGroups.ancestorTags, ...tagGroups.stickyTags};
const tags = {...tagGroups.nonStickyTags, ...tagGroups.ancestorTags, ...tagGroups.stickyTags};
return Object.keys(tags).map( (key) => {
const propagateAtLaunch = !!tagGroups.propagateTags[key] || !!tagGroups.ancestorTags[key];
return {key, value: tags[key], propagateAtLaunch};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,12 @@
}
],
"SecurityGroupIngress": [],
"Tags": [
{
"Key": "Name",
"Value": "aws-cdk-ec2-integ/Fleet"
}
],
"VpcId": {
"Ref": "VPCB9E5F0B4"
}
Expand Down Expand Up @@ -583,6 +589,7 @@
"ToPort": 80
}
],
"Tags": [],
"VpcId": {
"Ref": "VPCB9E5F0B4"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ export = {
}
],
"SecurityGroupIngress": [],
"Tags": [
{
"Key": "Name",
"Value": "MyFleet"
}
],
"VpcId": "my-vpc"
}
},
Expand Down
16 changes: 14 additions & 2 deletions packages/@aws-cdk/aws-ec2/lib/security-group.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Construct, Output, Token } from '@aws-cdk/cdk';
import { Construct, ITaggable, Output, TagManager, Tags, Token } from '@aws-cdk/cdk';
import { Connections, IConnectable } from './connections';
import { cloudformation } from './ec2.generated';
import { IPortRange, ISecurityGroupRule } from './security-group-rule';
Expand Down Expand Up @@ -89,6 +89,11 @@ export interface SecurityGroupProps {
*/
description?: string;

/**
* The AWS resource tags to associate with the security group.
*/
tags?: Tags;

/**
* The VPC in which to create the security group.
*/
Expand All @@ -102,7 +107,7 @@ export interface SecurityGroupProps {
* inline ingress and egress rule (which saves on the total number of resources inside
* the template).
*/
export class SecurityGroup extends SecurityGroupRef {
export class SecurityGroup extends SecurityGroupRef implements ITaggable {
/**
* An attribute that represents the security group name.
*/
Expand All @@ -118,20 +123,27 @@ export class SecurityGroup extends SecurityGroupRef {
*/
public readonly securityGroupId: string;

/**
* Manage tags for this construct and children
*/
public readonly tags: TagManager;

private readonly securityGroup: cloudformation.SecurityGroupResource;
private readonly directIngressRules: cloudformation.SecurityGroupResource.IngressProperty[] = [];
private readonly directEgressRules: cloudformation.SecurityGroupResource.EgressProperty[] = [];

constructor(parent: Construct, name: string, props: SecurityGroupProps) {
super(parent, name);

this.tags = new TagManager(this, { initialTags: props.tags});
const groupDescription = props.description || this.path;
this.securityGroup = new cloudformation.SecurityGroupResource(this, 'Resource', {
groupName: props.groupName,
groupDescription,
securityGroupIngress: new Token(() => this.directIngressRules),
securityGroupEgress: new Token(() => this.directEgressRules),
vpcId: props.vpc.vpcId,
tags: this.tags,
});

this.securityGroupId = this.securityGroup.securityGroupId;
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-ec2/lib/vpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ export class VpcSubnet extends VpcSubnetRef implements cdk.ITaggable {

constructor(parent: cdk.Construct, name: string, props: VpcSubnetProps) {
super(parent, name);
this.tags = new cdk.TagManager(this, props.tags);
this.tags = new cdk.TagManager(this, {initialTags: props.tags});
this.tags.setTag(NAME_TAG, this.path, {overwrite: false});

this.availabilityZone = props.availabilityZone;
Expand Down
68 changes: 39 additions & 29 deletions packages/@aws-cdk/aws-ec2/test/test.vpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ export = {
cidrMask: 24,
name: 'ingress',
subnetType: SubnetType.Public,
tags: {
type: 'Public',
init: 'No',
},
},
{
cidrMask: 24,
Expand Down Expand Up @@ -155,44 +159,50 @@ export = {
CidrBlock: `10.0.6.${i * 16}/28`
}));
}
expect(stack).to(haveResource("AWS::EC2::Subnet", hasTags(
[
{ Key: 'type', Value: 'Public'},
{ Key: 'init', Value: 'No'},
],
)));
test.done();
},
"with custom subents and natGateways = 2 there should be only two NATGW"(test: Test) {
const stack = getTestStack();
new VpcNetwork(stack, 'TheVPC', {
cidr: '10.0.0.0/21',
natGateways: 2,
subnetConfiguration: [
{
cidrMask: 24,
name: 'ingress',
subnetType: SubnetType.Public,
},
{
cidrMask: 24,
name: 'application',
subnetType: SubnetType.Private,
},
{
cidrMask: 28,
name: 'rds',
subnetType: SubnetType.Isolated,
}
],
maxAZs: 3
cidr: '10.0.0.0/21',
natGateways: 2,
subnetConfiguration: [
{
cidrMask: 24,
name: 'ingress',
subnetType: SubnetType.Public,
},
{
cidrMask: 24,
name: 'application',
subnetType: SubnetType.Private,
},
{
cidrMask: 28,
name: 'rds',
subnetType: SubnetType.Isolated,
}
],
maxAZs: 3
});
expect(stack).to(countResources("AWS::EC2::InternetGateway", 1));
expect(stack).to(countResources("AWS::EC2::NatGateway", 2));
expect(stack).to(countResources("AWS::EC2::Subnet", 9));
for (let i = 0; i < 6; i++) {
expect(stack).to(haveResource("AWS::EC2::Subnet", {
CidrBlock: `10.0.${i}.0/24`
}));
expect(stack).to(haveResource("AWS::EC2::Subnet", {
CidrBlock: `10.0.${i}.0/24`
}));
}
for (let i = 0; i < 3; i++) {
expect(stack).to(haveResource("AWS::EC2::Subnet", {
CidrBlock: `10.0.6.${i * 16}/28`
}));
expect(stack).to(haveResource("AWS::EC2::Subnet", {
CidrBlock: `10.0.6.${i * 16}/28`
}));
}
test.done();
},
Expand Down Expand Up @@ -229,9 +239,9 @@ export = {
expect(stack).to(countResources("AWS::EC2::Subnet", 4));
expect(stack).to(countResources("AWS::EC2::Route", 4));
for (let i = 0; i < 4; i++) {
expect(stack).to(haveResource("AWS::EC2::Subnet", {
CidrBlock: `10.0.${i * 64}.0/18`
}));
expect(stack).to(haveResource("AWS::EC2::Subnet", {
CidrBlock: `10.0.${i * 64}.0/18`
}));
}
expect(stack).to(haveResource("AWS::EC2::Route", {
DestinationCidrBlock: '0.0.0.0/0',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@
"ToPort": 80
}
],
"Tags": [],
"VpcId": {
"Ref": "VPCB9E5F0B4"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@
}
],
"SecurityGroupIngress": [],
"Tags": [],
"VpcId": {
"Ref": "VPCB9E5F0B4"
}
Expand Down
56 changes: 55 additions & 1 deletion packages/@aws-cdk/aws-rds/test/integ.cluster.expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,53 @@
}
}
},
"EncryptionB687BDBB": {
"Type": "AWS::KMS::Key",
"Properties": {
"KeyPolicy": {
"Statement": [
{
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
},
"Resource": "*"
}
],
"Version": "2012-10-17"
}
},
"DeletionPolicy": "Retain"
},
"DatabaseSubnets56F17B9A": {
"Type": "AWS::RDS::DBSubnetGroup",
"Properties": {
Expand All @@ -335,6 +382,7 @@
"GroupDescription": "RDS security group",
"SecurityGroupEgress": [],
"SecurityGroupIngress": [],
"Tags": [],
"VpcId": {
"Ref": "VPCB9E5F0B4"
}
Expand Down Expand Up @@ -376,9 +424,15 @@
"DBSubnetGroupName": {
"Ref": "DatabaseSubnets56F17B9A"
},
"KmsKeyId": {
"Fn::GetAtt": [
"EncryptionB687BDBB",
"Arn"
]
},
"MasterUsername": "admin",
"MasterUserPassword": "7959866cacc02c2d243ecfe177464fe6",
"StorageEncrypted": false,
"StorageEncrypted": true,
"VpcSecurityGroupIds": [
{
"Fn::GetAtt": [
Expand Down
4 changes: 4 additions & 0 deletions packages/@aws-cdk/aws-rds/test/integ.cluster.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ec2 = require('@aws-cdk/aws-ec2');
import kms = require('@aws-cdk/aws-kms');
import cdk = require('@aws-cdk/cdk');
import { DatabaseCluster, DatabaseClusterEngine } from '../lib';
import { ClusterParameterGroup } from '../lib/cluster-parameter-group';
Expand All @@ -14,6 +15,8 @@ const params = new ClusterParameterGroup(stack, 'Params', {
});
params.setParameter('character_set_database', 'utf8mb4');

const kmsKey = new kms.EncryptionKey(stack, 'Encryption');

const cluster = new DatabaseCluster(stack, 'Database', {
engine: DatabaseClusterEngine.Aurora,
masterUser: {
Expand All @@ -26,6 +29,7 @@ const cluster = new DatabaseCluster(stack, 'Database', {
vpc
},
parameterGroup: params,
kmsKeyArn: kmsKey.keyArn,
});

cluster.connections.allowDefaultPortFromAnyIpv4('Open to the world');
Expand Down
8 changes: 4 additions & 4 deletions packages/@aws-cdk/cdk/lib/core/tag-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export interface TagGroups {
/**
* Tags that are overwritten by ancestor tags
*/
nonSitckyTags: Tags;
nonStickyTags: Tags;

/**
* Tags with propagate true not from an ancestor
Expand Down Expand Up @@ -209,14 +209,14 @@ export class TagManager extends Token {
return parentTags;
}

const nonSitckyTags = filterTags(this._tags, {sticky: false});
const nonStickyTags = filterTags(this._tags, {sticky: false});
const stickyTags = filterTags(this._tags, {sticky: true});
const ancestors = this.parent.ancestors();
const ancestorTags = propagatedTags(ancestors);
const propagateTags = filterTags(this._tags, {propagate: true});
return this.tagFormatResolve( {
ancestorTags,
nonSitckyTags,
nonStickyTags,
stickyTags,
propagateTags,
});
Expand Down Expand Up @@ -263,7 +263,7 @@ export class TagManager extends Token {
* additional CloudFormation key for `PropagateAtLaunch`
*/
protected tagFormatResolve(tagGroups: TagGroups): any {
const tags = {...tagGroups.nonSitckyTags, ...tagGroups.ancestorTags, ...tagGroups.stickyTags};
const tags = {...tagGroups.nonStickyTags, ...tagGroups.ancestorTags, ...tagGroups.stickyTags};
for (const key of this.blockedTags) { delete tags[key]; }
return Object.keys(tags).map( key => ({key, value: tags[key]}));
}
Expand Down

0 comments on commit ac57507

Please sign in to comment.