Skip to content

Commit

Permalink
refactor(ec2): API cleanups, more control over UserData (#2954)
Browse files Browse the repository at this point in the history
Clean up EC2 APIs, hide all free-floating subclasses and introduce static factory functions (`Peer` and `Port`).

Start extensibility campaign for UserData. There are now classes for Linux and Windows-formatted UserData, and users can supply their own instance and/or subclass when creating an ASG. Simplify the user of `IMachineImage`.

Fixes #2674.

BREAKING CHANGES:

* **ec2**: `TcpPort` etc have moved to factory method
  on the `Port` class.
* **ec2**: `InstanceTypePair` has moved to factory method
  on `InstanceType`.
* **ec2**: `natDependencies` and `internetDependencies` removed,
  replaced with `internetConnectivityEstablished`.
* **ec2**: removed `selectSubnetIds`.
* **ec2**: removed `isPublicSubnets`.
* **ec2**: `VpnConnection` is now a `Resource`.
* **ec2**: `VpcNetworkProvider` is no longer available directly,
  use `Vpc.fromLookup()` instead.
* **ec2**: `routeTableId` is now a `IRouteTable` object.
* **ec2**: `AnyIPv4` etc have move as factory functions onto `Peer`.
* **ec2**: `IMachineImageSource` => `IMachineImage`.
* **ec2** : `MachineImage` => `MachineImageConfig`.
  • Loading branch information
rix0rrr committed Jun 21, 2019
1 parent c221181 commit c42523e
Show file tree
Hide file tree
Showing 82 changed files with 1,193 additions and 1,051 deletions.
1 change: 1 addition & 0 deletions NOTICE
@@ -1,2 +1,3 @@
AWS Cloud Development Kit (AWS CDK)
Copyright 2018-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.

2 changes: 1 addition & 1 deletion packages/@aws-cdk/assert/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/@aws-cdk/assets/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 25 additions & 10 deletions packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts
Expand Up @@ -175,7 +175,17 @@ export interface AutoScalingGroupProps extends CommonAutoScalingGroupProps {
/**
* AMI to launch
*/
readonly machineImage: ec2.IMachineImageSource;
readonly machineImage: ec2.IMachineImage;

/**
* Specific UserData to use
*
* The UserData may still be mutated after creation.
*
* @default - A UserData object appropriate for the MachineImage's
* Operating System is created.
*/
readonly userData?: ec2.UserData;

/**
* An IAM role to associate with the instance profile assigned to this Auto Scaling Group.
Expand Down Expand Up @@ -354,7 +364,11 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
*/
public readonly autoScalingGroupArn: string;

private readonly userDataLines = new Array<string>();
/**
* UserData for the instances
*/
public readonly userData: ec2.UserData;

private readonly autoScalingGroup: CfnAutoScalingGroup;
private readonly securityGroup: ec2.ISecurityGroup;
private readonly securityGroups: ec2.ISecurityGroup[] = [];
Expand All @@ -381,12 +395,13 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
});

// use delayed evaluation
const machineImage = props.machineImage.getImage(this);
const userDataToken = Lazy.stringValue({ produce: () => Fn.base64((machineImage.os.createUserData(this.userDataLines))) });
const imageConfig = props.machineImage.getImage(this);
this.userData = props.userData || imageConfig.userData || ec2.UserData.forOperatingSystem(imageConfig.osType);
const userDataToken = Lazy.stringValue({ produce: () => Fn.base64(this.userData.render()) });
const securityGroupsToken = Lazy.listValue({ produce: () => this.securityGroups.map(sg => sg.securityGroupId) });

const launchConfig = new CfnLaunchConfiguration(this, 'LaunchConfig', {
imageId: machineImage.imageId,
imageId: imageConfig.imageId,
keyName: props.keyName,
instanceType: props.instanceType.toString(),
securityGroups: securityGroupsToken,
Expand All @@ -409,7 +424,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
throw new Error(`Should have minCapacity (${minCapacity}) <= desiredCapacity (${desiredCapacity}) <= maxCapacity (${maxCapacity})`);
}

const { subnetIds } = props.vpc.selectSubnets(props.vpcSubnets);
const { subnetIds, hasPublic } = props.vpc.selectSubnets(props.vpcSubnets);
const asgProps: CfnAutoScalingGroupProps = {
cooldown: props.cooldown !== undefined ? props.cooldown.toSeconds().toString() : undefined,
minSize: minCapacity.toString(),
Expand All @@ -432,12 +447,12 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
vpcZoneIdentifier: subnetIds
};

if (!props.vpc.isPublicSubnets(subnetIds) && props.associatePublicIpAddress) {
if (!hasPublic && props.associatePublicIpAddress) {
throw new Error("To set 'associatePublicIpAddress: true' you must select Public subnets (vpcSubnets: { subnetType: SubnetType.Public })");
}

this.autoScalingGroup = new CfnAutoScalingGroup(this, 'ASG', asgProps);
this.osType = machineImage.os.type;
this.osType = imageConfig.osType;
this.autoScalingGroupName = this.autoScalingGroup.ref;
this.autoScalingGroupArn = Stack.of(this).formatArn({
service: 'autoscaling',
Expand Down Expand Up @@ -487,8 +502,8 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
* Add command to the startup script of fleet instances.
* The command must be in the scripting language supported by the fleet's OS (i.e. Linux/Windows).
*/
public addUserData(...scriptLines: string[]) {
scriptLines.forEach(scriptLine => this.userDataLines.push(scriptLine));
public addUserData(...commands: string[]) {
this.userData.addCommands(...commands);
}

/**
Expand Down
Expand Up @@ -428,7 +428,7 @@
}
],
"UserData": {
"Fn::Base64": "#!/bin/bash\n"
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
Expand Down Expand Up @@ -467,4 +467,4 @@
}
}
}
}
}
Expand Up @@ -12,7 +12,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', {

new autoscaling.AutoScalingGroup(stack, 'Fleet', {
vpc,
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
});

Expand Down
Expand Up @@ -602,7 +602,7 @@
}
],
"UserData": {
"Fn::Base64": "#!/bin/bash\n"
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
Expand Down Expand Up @@ -735,4 +735,4 @@
]
}
}
}
}
Expand Up @@ -13,7 +13,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', {

const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', {
vpc,
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage(),
});

Expand Down
Expand Up @@ -449,7 +449,7 @@
}
],
"UserData": {
"Fn::Base64": "#!/bin/bash\n"
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
Expand Down Expand Up @@ -667,4 +667,4 @@
}
}
}
}
}
Expand Up @@ -13,7 +13,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', {

const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', {
vpc,
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage(),
});

Expand Down
Expand Up @@ -428,7 +428,7 @@
}
],
"UserData": {
"Fn::Base64": "#!/bin/bash\n"
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
Expand Down Expand Up @@ -502,4 +502,4 @@
}
}
}
}
}
Expand Up @@ -12,7 +12,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', {

const asg = new autoscaling.AutoScalingGroup(stack, 'Fleet', {
vpc,
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
});

Expand Down
Expand Up @@ -581,7 +581,7 @@
}
],
"UserData": {
"Fn::Base64": "#!/bin/bash\n"
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
Expand Down Expand Up @@ -623,4 +623,4 @@
}
}
}
}
}
Expand Up @@ -13,7 +13,7 @@ class TestStack extends cdk.Stack {
});

new asg.AutoScalingGroup(this, 'ASG', {
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
vpc,
machineImage: new ec2.AmazonLinuxImage(),
role
Expand Down
Expand Up @@ -429,7 +429,7 @@
],
"SpotPrice": "0.20",
"UserData": {
"Fn::Base64": "#!/bin/bash\n"
"Fn::Base64": "#!/bin/bash"
}
},
"DependsOn": [
Expand Down Expand Up @@ -468,4 +468,4 @@
}
}
}
}
}
Expand Up @@ -12,7 +12,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', {

new autoscaling.AutoScalingGroup(stack, 'Fleet', {
vpc,
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }),
spotPrice: '0.20'
});
Expand Down

0 comments on commit c42523e

Please sign in to comment.