Skip to content

Commit

Permalink
feat(aws-codedeploy): Add the auto-scaling groups property to ServerD…
Browse files Browse the repository at this point in the history
…eploymentGroup.
  • Loading branch information
skinny85 committed Sep 18, 2018
1 parent 30a40da commit 5859b54
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 2 deletions.
97 changes: 96 additions & 1 deletion packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import autoscaling = require("@aws-cdk/aws-autoscaling");
import cdk = require("@aws-cdk/cdk");
import iam = require("../../aws-iam/lib/role");
import { ServerApplication, ServerApplicationRef } from "./application";
Expand Down Expand Up @@ -61,6 +62,7 @@ export abstract class ServerDeploymentGroupRef extends cdk.Construct {
public abstract readonly deploymentGroupName: DeploymentGroupName;
public abstract readonly deploymentGroupArn: DeploymentGroupArn;
public readonly deploymentConfig: IServerDeploymentConfig;
public abstract readonly autoScalingGroups: autoscaling.AutoScalingGroup[];

constructor(parent: cdk.Construct, id: string, deploymentConfig?: IServerDeploymentConfig) {
super(parent, id);
Expand All @@ -81,6 +83,7 @@ class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef {
public readonly application: ServerApplicationRef;
public readonly deploymentGroupName: DeploymentGroupName;
public readonly deploymentGroupArn: DeploymentGroupArn;
public readonly autoScalingGroups: autoscaling.AutoScalingGroup[];

constructor(parent: cdk.Construct, id: string, props: ServerDeploymentGroupRefProps) {
super(parent, id, props.deploymentConfig);
Expand All @@ -89,9 +92,17 @@ class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef {
this.deploymentGroupName = props.deploymentGroupName;
this.deploymentGroupArn = deploymentGroupName2Arn(props.application.applicationName,
props.deploymentGroupName);
this.autoScalingGroups = [];
}
}

export enum AgentInstallationType {
UBUNTU_14_04 = 1,
UBUNTU_16_04,
AMAZON_LINUX_RHEL,
WINDOWS_SERVER,
}

/**
* Construction properties for {@link ServerDeploymentGroup}.
*/
Expand Down Expand Up @@ -121,6 +132,25 @@ export interface ServerDeploymentGroupProps {
* @default ServerDeploymentConfig#OneAtATime
*/
deploymentConfig?: IServerDeploymentConfig;

/**
* The auto-scaling groups belonging to this Deployment Group.
*
* @default []
*/
autoScalingGroups?: autoscaling.AutoScalingGroup[];

/**
* If you've provided any auto-scaling groups with the {@link #autoScalingGroups} property,
* you can set this property to automatically install the CodeDeploy agent on the instances
* using User Data.
* The value specifies what family does the operating system of the auto-scaling groups
* belongs to, as the installation varies between different systems.
*
* @default the agent will not be automatically installed
* @see https://docs.aws.amazon.com/codedeploy/latest/userguide/codedeploy-agent-operations-install.html
*/
agentInstallationType?: AgentInstallationType;
}

/**
Expand All @@ -129,8 +159,9 @@ export interface ServerDeploymentGroupProps {
export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
public readonly application: ServerApplicationRef;
public readonly role: iam.Role;
public readonly deploymentGroupArn: DeploymentGroupArn;
public readonly deploymentGroupName: DeploymentGroupName;
public readonly deploymentGroupArn: DeploymentGroupArn;
private readonly _autoScalingGroups: autoscaling.AutoScalingGroup[];

constructor(parent: cdk.Construct, id: string, props?: ServerDeploymentGroupProps) {
super(parent, id, props && props.deploymentConfig);
Expand All @@ -141,19 +172,83 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
assumedBy: new cdk.ServicePrincipal('codedeploy.amazonaws.com'),
managedPolicyArns: ['arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole'],
});
this._autoScalingGroups = (props && props.autoScalingGroups) || [];
this.addCodeDeployAgentInstallUserData(props && props.agentInstallationType);

const resource = new cloudformation.DeploymentGroupResource(this, 'Resource', {
applicationName: this.application.applicationName,
deploymentGroupName: props && props.deploymentGroupName,
serviceRoleArn: this.role.roleArn,
deploymentConfigName: props && props.deploymentConfig &&
props.deploymentConfig.deploymentConfigName,
autoScalingGroups: this._autoScalingGroups.map(asg => asg.autoScalingGroupName()),
});

this.deploymentGroupName = resource.ref;
this.deploymentGroupArn = deploymentGroupName2Arn(this.application.applicationName,
this.deploymentGroupName);
}

public get autoScalingGroups(): autoscaling.AutoScalingGroup[] {
return this._autoScalingGroups.slice();
}

private addCodeDeployAgentInstallUserData(agentInstallationType?: AgentInstallationType): void {
if (!agentInstallationType) {
return;
}

const stack = cdk.Stack.find(this);
const region = stack.requireRegion('Could not determine the region to download the CodeDeploy agent from');

for (const asg of this._autoScalingGroups) {
switch (agentInstallationType) {
case AgentInstallationType.UBUNTU_14_04:
asg.addUserData(`
apt-get update -y
apt-get install -y ruby2.0 wget
TMP_DIR=\`mktemp -d\`
cd $TMP_DIR
wget https://aws-codedeploy-${region}.s3.amazonaws.com/latest/install
chmod +x ./install
./install auto
rm -fr $TMP_DIR
`);
break;
case AgentInstallationType.UBUNTU_16_04:
asg.addUserData(`
apt-get update -y
apt-get install -y ruby wget
TMP_DIR=\`mktemp -d\`
cd $TMP_DIR
wget https://aws-codedeploy-${region}.s3.amazonaws.com/latest/install
chmod +x ./install
./install auto
rm -fr $TMP_DIR
`);
break;
case AgentInstallationType.AMAZON_LINUX_RHEL:
asg.addUserData(`
yum update -y
yum install ruby wget -y
TMP_DIR=\`mktemp -d\`
cd $TMP_DIR
wget https://aws-codedeploy-${region}.s3.amazonaws.com/latest/install
chmod +x ./install
./install auto
rm -fr $TMP_DIR
`);
break;
case AgentInstallationType.WINDOWS_SERVER:
asg.addUserData(`
Set-Variable -Name TEMPDIR -Value (New-TemporaryFile).DirectoryName
aws s3 cp s3://aws-codedeploy-${region}/latest/codedeploy-agent.msi $TEMPDIR\\codedeploy-agent.msi
$TEMPDIR\\codedeploy-agent.msi /quiet /l c:\\temp\\host-agent-install-log.txt
`);
break;
}
}
}
}

function deploymentGroupName2Arn(applicationName: ApplicationName,
Expand Down
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-codedeploy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
},
"nyc": {
"lines": 50,
"branches": 40
"branches": 30
},
"keywords": [
"aws",
Expand All @@ -57,11 +57,13 @@
"license": "Apache-2.0",
"devDependencies": {
"@aws-cdk/assert": "^0.9.1",
"@aws-cdk/aws-ec2": "^0.9.1",
"cdk-build-tools": "^0.9.1",
"cfn2ts": "^0.9.1",
"pkglint": "^0.9.1"
},
"dependencies": {
"@aws-cdk/aws-autoscaling": "^0.9.1",
"@aws-cdk/aws-codepipeline-api": "^0.9.1",
"@aws-cdk/cdk": "^0.9.1"
},
Expand Down
36 changes: 36 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/test/test.deployment-group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { expect, haveResource } from '@aws-cdk/assert';
import autoscaling = require('@aws-cdk/aws-autoscaling');
import ec2 = require('@aws-cdk/aws-ec2');
import cdk = require('@aws-cdk/cdk');
import { Test } from 'nodeunit';
import codedeploy = require('../lib');

// tslint:disable:object-literal-key-quotes

export = {
'CodeDeploy Deployment Group': {
"created with ASGs contains the ASG names"(test: Test) {
const stack = new cdk.Stack();

const asg = new autoscaling.AutoScalingGroup(stack, 'ASG', {
instanceType: new ec2.InstanceTypePair(ec2.InstanceClass.Standard3, ec2.InstanceSize.Small),
machineImage: new ec2.AmazonLinuxImage(),
vpc: new ec2.VpcNetwork(stack, 'VPC'),
});

new codedeploy.ServerDeploymentGroup(stack, 'DeploymentGroup', {
autoScalingGroups: [asg],
});

expect(stack).to(haveResource('AWS::CodeDeploy::DeploymentGroup', {
"AutoScalingGroups": [
{
"Ref": "ASG46ED3070",
},
]
}));

test.done();
},
},
};

0 comments on commit 5859b54

Please sign in to comment.