1+ import autoscaling = require( "@aws-cdk/aws-autoscaling" ) ;
2+ import ec2 = require( "@aws-cdk/aws-ec2" ) ;
3+ import s3 = require( "@aws-cdk/aws-s3" ) ;
14import cdk = require( "@aws-cdk/cdk" ) ;
25import iam = require( "../../aws-iam/lib/role" ) ;
36import { ServerApplication , ServerApplicationRef } from "./application" ;
@@ -56,9 +59,11 @@ export abstract class ServerDeploymentGroupRef extends cdk.Construct {
5659 }
5760
5861 public abstract readonly application : ServerApplicationRef ;
62+ public abstract readonly role ?: iam . Role ;
5963 public abstract readonly deploymentGroupName : string ;
6064 public abstract readonly deploymentGroupArn : string ;
6165 public readonly deploymentConfig : IServerDeploymentConfig ;
66+ public abstract readonly autoScalingGroups ?: autoscaling . AutoScalingGroup [ ] ;
6267
6368 constructor ( parent : cdk . Construct , id : string , deploymentConfig ?: IServerDeploymentConfig ) {
6469 super ( parent , id ) ;
@@ -71,14 +76,17 @@ export abstract class ServerDeploymentGroupRef extends cdk.Construct {
7176 deploymentGroupName : new cdk . Output ( this , 'DeploymentGroupName' , {
7277 value : this . deploymentGroupName
7378 } ) . makeImportValue ( ) . toString ( ) ,
79+ deploymentConfig : this . deploymentConfig ,
7480 } ;
7581 }
7682}
7783
7884class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef {
7985 public readonly application : ServerApplicationRef ;
86+ public readonly role ?: iam . Role = undefined ;
8087 public readonly deploymentGroupName : string ;
8188 public readonly deploymentGroupArn : string ;
89+ public readonly autoScalingGroups ?: autoscaling . AutoScalingGroup [ ] = undefined ;
8290
8391 constructor ( parent : cdk . Construct , id : string , props : ServerDeploymentGroupRefProps ) {
8492 super ( parent , id , props . deploymentConfig ) ;
@@ -119,19 +127,39 @@ export interface ServerDeploymentGroupProps {
119127 * @default ServerDeploymentConfig#OneAtATime
120128 */
121129 deploymentConfig ?: IServerDeploymentConfig ;
130+
131+ /**
132+ * The auto-scaling groups belonging to this Deployment Group.
133+ *
134+ * @default []
135+ */
136+ autoScalingGroups ?: autoscaling . AutoScalingGroup [ ] ;
137+
138+ /**
139+ * If you've provided any auto-scaling groups with the {@link #autoScalingGroups} property,
140+ * you can set this property to add User Data that installs the CodeDeploy agent on the instances.
141+ *
142+ * @default true
143+ * @see https://docs.aws.amazon.com/codedeploy/latest/userguide/codedeploy-agent-operations-install.html
144+ */
145+ installAgent ?: boolean ;
122146}
123147
124148/**
125149 * A CodeDeploy Deployment Group that deploys to EC2/on-premise instances.
126150 */
127151export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
128152 public readonly application : ServerApplicationRef ;
129- public readonly role : iam . Role ;
153+ public readonly role ? : iam . Role ;
130154 public readonly deploymentGroupArn : string ;
131155 public readonly deploymentGroupName : string ;
132156
157+ private readonly _autoScalingGroups : autoscaling . AutoScalingGroup [ ] ;
158+ private readonly installAgent : boolean ;
159+ private readonly codeDeployBucket : s3 . BucketRef ;
160+
133161 constructor ( parent : cdk . Construct , id : string , props : ServerDeploymentGroupProps = { } ) {
134- super ( parent , id , props && props . deploymentConfig ) ;
162+ super ( parent , id , props . deploymentConfig ) ;
135163
136164 this . application = props . application || new ServerApplication ( this , 'Application' ) ;
137165
@@ -140,18 +168,82 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
140168 managedPolicyArns : [ 'arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole' ] ,
141169 } ) ;
142170
171+ this . _autoScalingGroups = props . autoScalingGroups || [ ] ;
172+ this . installAgent = props . installAgent === undefined ? true : props . installAgent ;
173+ const region = ( new cdk . AwsRegion ( ) ) . toString ( ) ;
174+ this . codeDeployBucket = s3 . BucketRef . import ( this , 'CodeDeployBucket' , {
175+ bucketName : `aws-codedeploy-${ region } ` ,
176+ } ) ;
177+ for ( const asg of this . _autoScalingGroups ) {
178+ this . addCodeDeployAgentInstallUserData ( asg ) ;
179+ }
180+
143181 const resource = new cloudformation . DeploymentGroupResource ( this , 'Resource' , {
144182 applicationName : this . application . applicationName ,
145183 deploymentGroupName : props . deploymentGroupName ,
146184 serviceRoleArn : this . role . roleArn ,
147185 deploymentConfigName : props . deploymentConfig &&
148186 props . deploymentConfig . deploymentConfigName ,
187+ autoScalingGroups : new cdk . Token ( ( ) =>
188+ this . _autoScalingGroups . length === 0
189+ ? undefined
190+ : this . _autoScalingGroups . map ( asg => asg . autoScalingGroupName ( ) ) ) ,
149191 } ) ;
150192
151193 this . deploymentGroupName = resource . deploymentGroupName ;
152194 this . deploymentGroupArn = deploymentGroupName2Arn ( this . application . applicationName ,
153195 this . deploymentGroupName ) ;
154196 }
197+
198+ public addAutoScalingGroup ( asg : autoscaling . AutoScalingGroup ) : void {
199+ this . _autoScalingGroups . push ( asg ) ;
200+ this . addCodeDeployAgentInstallUserData ( asg ) ;
201+ }
202+
203+ public get autoScalingGroups ( ) : autoscaling . AutoScalingGroup [ ] | undefined {
204+ return this . _autoScalingGroups . slice ( ) ;
205+ }
206+
207+ private addCodeDeployAgentInstallUserData ( asg : autoscaling . AutoScalingGroup ) : void {
208+ if ( ! this . installAgent ) {
209+ return ;
210+ }
211+
212+ this . codeDeployBucket . grantRead ( asg . role , 'latest/*' ) ;
213+
214+ const region = ( new cdk . AwsRegion ( ) ) . toString ( ) ;
215+ switch ( asg . osType ) {
216+ case ec2 . OperatingSystemType . Linux :
217+ asg . addUserData (
218+ 'PKG_CMD=`which yum 2>/dev/null`' ,
219+ 'if [ -z "$PKG_CMD" ]; then' ,
220+ 'PKG_CMD=apt-get' ,
221+ 'else' ,
222+ 'PKG=CMD=yum' ,
223+ 'fi' ,
224+ '$PKG_CMD update -y' ,
225+ '$PKG_CMD install -y ruby2.0' ,
226+ 'if [ $? -ne 0 ]; then' ,
227+ '$PKG_CMD install -y ruby' ,
228+ 'fi' ,
229+ '$PKG_CMD install -y awscli' ,
230+ 'TMP_DIR=`mktemp -d`' ,
231+ 'cd $TMP_DIR' ,
232+ `aws s3 cp s3://aws-codedeploy-${ region } /latest/install . --region ${ region } ` ,
233+ 'chmod +x ./install' ,
234+ './install auto' ,
235+ 'rm -fr $TMP_DIR' ,
236+ ) ;
237+ break ;
238+ case ec2 . OperatingSystemType . Windows :
239+ asg . addUserData (
240+ 'Set-Variable -Name TEMPDIR -Value (New-TemporaryFile).DirectoryName' ,
241+ `aws s3 cp s3://aws-codedeploy-${ region } /latest/codedeploy-agent.msi $TEMPDIR\\codedeploy-agent.msi` ,
242+ '$TEMPDIR\\codedeploy-agent.msi /quiet /l c:\\temp\\host-agent-install-log.txt' ,
243+ ) ;
244+ break ;
245+ }
246+ }
155247}
156248
157249function deploymentGroupName2Arn ( applicationName : string , deploymentGroupName : string ) : string {
0 commit comments