1
+ import autoscaling = require( "@aws-cdk/aws-autoscaling" ) ;
2
+ import ec2 = require( "@aws-cdk/aws-ec2" ) ;
3
+ import s3 = require( "@aws-cdk/aws-s3" ) ;
1
4
import cdk = require( "@aws-cdk/cdk" ) ;
2
5
import iam = require( "../../aws-iam/lib/role" ) ;
3
6
import { ServerApplication , ServerApplicationRef } from "./application" ;
@@ -56,9 +59,11 @@ export abstract class ServerDeploymentGroupRef extends cdk.Construct {
56
59
}
57
60
58
61
public abstract readonly application : ServerApplicationRef ;
62
+ public abstract readonly role ?: iam . Role ;
59
63
public abstract readonly deploymentGroupName : string ;
60
64
public abstract readonly deploymentGroupArn : string ;
61
65
public readonly deploymentConfig : IServerDeploymentConfig ;
66
+ public abstract readonly autoScalingGroups ?: autoscaling . AutoScalingGroup [ ] ;
62
67
63
68
constructor ( parent : cdk . Construct , id : string , deploymentConfig ?: IServerDeploymentConfig ) {
64
69
super ( parent , id ) ;
@@ -71,14 +76,17 @@ export abstract class ServerDeploymentGroupRef extends cdk.Construct {
71
76
deploymentGroupName : new cdk . Output ( this , 'DeploymentGroupName' , {
72
77
value : this . deploymentGroupName
73
78
} ) . makeImportValue ( ) . toString ( ) ,
79
+ deploymentConfig : this . deploymentConfig ,
74
80
} ;
75
81
}
76
82
}
77
83
78
84
class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef {
79
85
public readonly application : ServerApplicationRef ;
86
+ public readonly role ?: iam . Role = undefined ;
80
87
public readonly deploymentGroupName : string ;
81
88
public readonly deploymentGroupArn : string ;
89
+ public readonly autoScalingGroups ?: autoscaling . AutoScalingGroup [ ] = undefined ;
82
90
83
91
constructor ( parent : cdk . Construct , id : string , props : ServerDeploymentGroupRefProps ) {
84
92
super ( parent , id , props . deploymentConfig ) ;
@@ -119,19 +127,39 @@ export interface ServerDeploymentGroupProps {
119
127
* @default ServerDeploymentConfig#OneAtATime
120
128
*/
121
129
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 ;
122
146
}
123
147
124
148
/**
125
149
* A CodeDeploy Deployment Group that deploys to EC2/on-premise instances.
126
150
*/
127
151
export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
128
152
public readonly application : ServerApplicationRef ;
129
- public readonly role : iam . Role ;
153
+ public readonly role ? : iam . Role ;
130
154
public readonly deploymentGroupArn : string ;
131
155
public readonly deploymentGroupName : string ;
132
156
157
+ private readonly _autoScalingGroups : autoscaling . AutoScalingGroup [ ] ;
158
+ private readonly installAgent : boolean ;
159
+ private readonly codeDeployBucket : s3 . BucketRef ;
160
+
133
161
constructor ( parent : cdk . Construct , id : string , props : ServerDeploymentGroupProps = { } ) {
134
- super ( parent , id , props && props . deploymentConfig ) ;
162
+ super ( parent , id , props . deploymentConfig ) ;
135
163
136
164
this . application = props . application || new ServerApplication ( this , 'Application' ) ;
137
165
@@ -140,18 +168,82 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
140
168
managedPolicyArns : [ 'arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole' ] ,
141
169
} ) ;
142
170
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
+
143
181
const resource = new cloudformation . DeploymentGroupResource ( this , 'Resource' , {
144
182
applicationName : this . application . applicationName ,
145
183
deploymentGroupName : props . deploymentGroupName ,
146
184
serviceRoleArn : this . role . roleArn ,
147
185
deploymentConfigName : props . deploymentConfig &&
148
186
props . deploymentConfig . deploymentConfigName ,
187
+ autoScalingGroups : new cdk . Token ( ( ) =>
188
+ this . _autoScalingGroups . length === 0
189
+ ? undefined
190
+ : this . _autoScalingGroups . map ( asg => asg . autoScalingGroupName ( ) ) ) ,
149
191
} ) ;
150
192
151
193
this . deploymentGroupName = resource . deploymentGroupName ;
152
194
this . deploymentGroupArn = deploymentGroupName2Arn ( this . application . applicationName ,
153
195
this . deploymentGroupName ) ;
154
196
}
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
+ }
155
247
}
156
248
157
249
function deploymentGroupName2Arn ( applicationName : string , deploymentGroupName : string ) : string {
0 commit comments