Skip to content

Commit

Permalink
feat(cdk): Add support for Aspects (aws#1451)
Browse files Browse the repository at this point in the history
 * The base Aspect class is added and is an idempotent propagating visitor, that
 recurses during the visit action
 * The first aspects are for tags
 * TagManager has been re-implemented to only handle setting removing
 and formatting tags
 * Tags can be included or excluded based on Resource Type, this
 replaces the the need for all previous tag properties
 * VPC, Security Group, KMS Keys, and AutoScaling are updated to use tags
 * Tag Aspects overwrite tags passed into the L1 during initialization
  • Loading branch information
moofish32 committed Jan 14, 2019
1 parent dac9bfa commit 7eda0c2
Show file tree
Hide file tree
Showing 24 changed files with 834 additions and 751 deletions.
28 changes: 3 additions & 25 deletions packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,6 @@ export interface AutoScalingGroupProps {
*/
resourceSignalTimeoutSec?: number;

/**
* The AWS resource tags to associate with the ASG.
*/
tags?: cdk.Tags;

/**
* Default scaling cooldown for this AutoScalingGroup
*
Expand All @@ -161,7 +156,7 @@ export interface AutoScalingGroupProps {
*
* The ASG spans all availability zones.
*/
export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup, cdk.ITaggable, elb.ILoadBalancerTarget, ec2.IConnectable,
export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup, elb.ILoadBalancerTarget, ec2.IConnectable,
elbv2.IApplicationLoadBalancerTarget, elbv2.INetworkLoadBalancerTarget {
/**
* The type of OS instances of this fleet are running.
Expand All @@ -178,11 +173,6 @@ export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup
*/
public readonly role: iam.Role;

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

/**
* Name of the AutoScalingGroup
*/
Expand All @@ -209,8 +199,7 @@ export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup
});
this.connections = new ec2.Connections({ securityGroups: [this.securityGroup] });
this.securityGroups.push(this.securityGroup);
this.tags = new TagManager(this, {initialTags: props.tags});
this.tags.setTag(NAME_TAG, this.node.path, { overwrite: false });
this.apply(new cdk.Tag(NAME_TAG, this.node.path, { applyToLaunchInstances: true }));

this.role = new iam.Role(this, 'InstanceRole', {
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com')
Expand Down Expand Up @@ -255,7 +244,6 @@ export class AutoScalingGroup extends cdk.Construct implements IAutoScalingGroup
launchConfigurationName: launchConfig.ref,
loadBalancerNames: new cdk.Token(() => this.loadBalancerNames.length > 0 ? this.loadBalancerNames : undefined),
targetGroupArns: new cdk.Token(() => this.targetGroupArns.length > 0 ? this.targetGroupArns : undefined),
tags: this.tags,
};

if (props.notificationsTopic) {
Expand Down Expand Up @@ -616,16 +604,6 @@ function renderRollingUpdateConfig(config: RollingUpdateConfiguration = {}): cdk
};
}

class TagManager extends cdk.TagManager {
protected tagFormatResolve(tagGroups: cdk.TagGroups): any {
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};
});
}
}

/**
* Render a number of seconds to a PTnX string.
*/
Expand Down Expand Up @@ -748,4 +726,4 @@ export interface MetricTargetTrackingProps extends BaseTargetTrackingProps {
* Value to keep the metric around
*/
targetValue: number;
}
}
31 changes: 22 additions & 9 deletions packages/@aws-cdk/aws-autoscaling/test/test.auto-scaling-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import autoscaling = require('../lib');

export = {
'default fleet'(test: Test) {
const stack = new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' }});
const stack = getTestStack();
const vpc = mockVpc(stack);

new autoscaling.AutoScalingGroup(stack, 'MyFleet', {
Expand All @@ -18,6 +18,8 @@ export = {
vpc
});

stack.testInvokeAspects();

expect(stack).toMatch({
"Resources": {
"MyFleetInstanceSecurityGroup774E8234": {
Expand Down Expand Up @@ -365,7 +367,8 @@ export = {
},
'can set tags'(test: Test) {
// GIVEN
const stack = new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' }});
const stack = getTestStack();
// new cdk.Stack(undefined, 'MyStack', { env: { region: 'us-east-1', account: '1234' }});
const vpc = mockVpc(stack);

// WHEN
Expand All @@ -378,27 +381,28 @@ export = {
minSuccessfulInstancesPercent: 50,
pauseTimeSec: 345
},
tags: {superfood: 'acai'},
});
asg.tags.setTag('notsuper', 'caramel', {propagate: false});
asg.apply( new cdk.Tag('superfood', 'acai'));
asg.apply( new cdk.Tag('notsuper', 'caramel', { applyToLaunchInstances: false }));

stack.testInvokeAspects();
// THEN
expect(stack).to(haveResource("AWS::AutoScaling::AutoScalingGroup", {
Tags: [
{
Key: 'superfood',
Value: 'acai',
Key: 'Name',
PropagateAtLaunch: true,
Value: 'MyFleet',
},
{
Key: 'Name',
Value: 'MyFleet',
Key: 'superfood',
PropagateAtLaunch: true,
Value: 'acai',
},
{
Key: 'notsuper',
Value: 'caramel',
PropagateAtLaunch: false,
Value: 'caramel',
},
]
}));
Expand All @@ -421,3 +425,12 @@ function mockSecurityGroup(stack: cdk.Stack) {
securityGroupId: 'most-secure',
});
}

class TestStack extends cdk.Stack {
public testInvokeAspects(): void {
this.invokeAspects();
}
}
function getTestStack(): TestStack {
return new TestStack(undefined, 'TestStack', { env: { account: '1234', region: 'us-east-1' } });
}
14 changes: 12 additions & 2 deletions packages/@aws-cdk/aws-autoscaling/test/test.scheduled-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export = {

'autoscaling group has recommended updatepolicy for scheduled actions'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const stack = getTestStack();
const asg = makeAutoScalingGroup(stack);

// WHEN
Expand All @@ -56,6 +56,7 @@ export = {
minCapacity: 10,
});

stack.testInvokeAspects();
// THEN
expect(stack).toMatch({
Resources: {
Expand Down Expand Up @@ -111,4 +112,13 @@ function makeAutoScalingGroup(scope: cdk.Construct) {
machineImage: new ec2.AmazonLinuxImage(),
updateType: autoscaling.UpdateType.RollingUpdate,
});
}
}

class TestStack extends cdk.Stack {
public testInvokeAspects(): void {
this.invokeAspects();
}
}
function getTestStack(): TestStack {
return new TestStack(undefined, 'TestStack', { env: { account: '1234', region: 'us-east-1' } });
}
16 changes: 2 additions & 14 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, IConstruct, ITaggable, Output, TagManager, Tags, Token } from '@aws-cdk/cdk';
import { Construct, IConstruct, Output, Token } from '@aws-cdk/cdk';
import { Connections, IConnectable } from './connections';
import { CfnSecurityGroup, CfnSecurityGroupEgress, CfnSecurityGroupIngress } from './ec2.generated';
import { IPortRange, ISecurityGroupRule } from './security-group-rule';
Expand Down Expand Up @@ -105,11 +105,6 @@ 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 @@ -134,7 +129,7 @@ export interface SecurityGroupProps {
* inline ingress and egress rule (which saves on the total number of resources inside
* the template).
*/
export class SecurityGroup extends SecurityGroupBase implements ITaggable {
export class SecurityGroup extends SecurityGroupBase {
/**
* Import an existing SecurityGroup
*/
Expand All @@ -157,11 +152,6 @@ export class SecurityGroup extends SecurityGroupBase implements ITaggable {
*/
public readonly securityGroupId: string;

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

private readonly securityGroup: CfnSecurityGroup;
private readonly directIngressRules: CfnSecurityGroup.IngressProperty[] = [];
private readonly directEgressRules: CfnSecurityGroup.EgressProperty[] = [];
Expand All @@ -171,7 +161,6 @@ export class SecurityGroup extends SecurityGroupBase implements ITaggable {
constructor(scope: Construct, id: string, props: SecurityGroupProps) {
super(scope, id);

this.tags = new TagManager(this, { initialTags: props.tags});
const groupDescription = props.description || this.node.path;

this.allowAllOutbound = props.allowAllOutbound !== false;
Expand All @@ -182,7 +171,6 @@ export class SecurityGroup extends SecurityGroupBase implements ITaggable {
securityGroupIngress: new Token(() => this.directIngressRules),
securityGroupEgress: new Token(() => this.directEgressRules),
vpcId: props.vpc.vpcId,
tags: this.tags,
});

this.securityGroupId = this.securityGroup.securityGroupId;
Expand Down
Loading

0 comments on commit 7eda0c2

Please sign in to comment.