1
1
[ ![ cloudcomponents Logo] ( https://raw.githubusercontent.com/cloudcomponents/cdk-constructs/master/logo.png )] ( https://github.com/cloudcomponents/cdk-constructs )
2
2
3
- # @cloudcomponents/cdk-blue-green-container-deployment
3
+ # @cloudcomponents/cdk-blue-green-container-deployment
4
4
5
5
[ ![ Build Status] ( https://github.com/cloudcomponents/cdk-constructs/workflows/Build/badge.svg )] ( https://github.com/cloudcomponents/cdk-constructs/actions?query=workflow=Build )
6
6
[ ![ cdkdx] ( https://img.shields.io/badge/buildtool-cdkdx-blue.svg )] ( https://github.com/hupe1980/cdkdx )
11
11
> Blue green container deployment with CodeDeploy
12
12
13
13
## Install
14
+
14
15
TypeScript/JavaScript:
15
16
16
17
``` bash
@@ -26,97 +27,97 @@ pip install cloudcomponents.cdk-blue-green-container-deployment
26
27
## How to use
27
28
28
29
``` typescript
29
- import { Construct , Stack , StackProps } from ' @aws-cdk/core' ;
30
- import { Repository } from ' @aws-cdk/aws-codecommit' ;
31
- import { Pipeline , Artifact } from ' @aws-cdk/aws-codepipeline' ;
32
- import { Vpc , Port } from ' @aws-cdk/aws-ec2' ;
33
- import { Cluster } from ' @aws-cdk/aws-ecs' ;
30
+ import { Construct , Stack , StackProps } from " @aws-cdk/core" ;
31
+ import { Repository } from " @aws-cdk/aws-codecommit" ;
32
+ import { Pipeline , Artifact } from " @aws-cdk/aws-codepipeline" ;
33
+ import { Vpc , Port } from " @aws-cdk/aws-ec2" ;
34
+ import { Cluster } from " @aws-cdk/aws-ecs" ;
34
35
import {
35
36
ApplicationLoadBalancer ,
36
37
ApplicationTargetGroup ,
37
38
TargetType ,
38
- } from ' @aws-cdk/aws-elasticloadbalancingv2' ;
39
+ } from " @aws-cdk/aws-elasticloadbalancingv2" ;
39
40
import {
40
41
CodeBuildAction ,
41
42
CodeCommitSourceAction ,
42
43
CodeDeployEcsDeployAction ,
43
- } from ' @aws-cdk/aws-codepipeline-actions' ;
44
+ } from " @aws-cdk/aws-codepipeline-actions" ;
44
45
45
- import { ImageRepository } from ' @cloudcomponents/cdk-container-registry' ;
46
+ import { ImageRepository } from " @cloudcomponents/cdk-container-registry" ;
46
47
import {
47
48
EcsService ,
48
49
DummyTaskDefinition ,
49
50
EcsDeploymentGroup ,
50
51
PushImageProject ,
51
- } from ' @cloudcomponents/cdk-blue-green-container-deployment' ;
52
+ } from " @cloudcomponents/cdk-blue-green-container-deployment" ;
52
53
53
54
export class BlueGreenContainerDeploymentStack extends Stack {
54
55
constructor (scope : Construct , id : string , props ? : StackProps ) {
55
56
super (scope , id , props );
56
57
57
- const vpc = new Vpc (this , ' Vpc' , {
58
+ const vpc = new Vpc (this , " Vpc" , {
58
59
maxAzs: 2 ,
59
60
});
60
61
61
- const cluster = new Cluster (this , ' Cluster' , {
62
+ const cluster = new Cluster (this , " Cluster" , {
62
63
vpc ,
63
- clusterName: ' blue-green-cluster' ,
64
+ clusterName: " blue-green-cluster" ,
64
65
});
65
66
66
- const loadBalancer = new ApplicationLoadBalancer (this , ' LoadBalancer' , {
67
+ const loadBalancer = new ApplicationLoadBalancer (this , " LoadBalancer" , {
67
68
vpc ,
68
69
internetFacing: true ,
69
70
});
70
71
71
- const prodListener = loadBalancer .addListener (' ProfListener' , {
72
+ const prodListener = loadBalancer .addListener (" ProfListener" , {
72
73
port: 80 ,
73
74
});
74
75
75
- const testListener = loadBalancer .addListener (' TestListener' , {
76
+ const testListener = loadBalancer .addListener (" TestListener" , {
76
77
port: 8080 ,
77
78
});
78
79
79
80
const prodTargetGroup = new ApplicationTargetGroup (
80
81
this ,
81
- ' ProdTargetGroup' ,
82
+ " ProdTargetGroup" ,
82
83
{
83
84
port: 80 ,
84
85
targetType: TargetType .IP ,
85
86
vpc ,
86
- },
87
+ }
87
88
);
88
89
89
- prodListener .addTargetGroups (' AddProdTg' , {
90
+ prodListener .addTargetGroups (" AddProdTg" , {
90
91
targetGroups: [prodTargetGroup ],
91
92
});
92
93
93
94
const testTargetGroup = new ApplicationTargetGroup (
94
95
this ,
95
- ' TestTargetGroup' ,
96
+ " TestTargetGroup" ,
96
97
{
97
98
port: 8080 ,
98
99
targetType: TargetType .IP ,
99
100
vpc ,
100
- },
101
+ }
101
102
);
102
103
103
- testListener .addTargetGroups (' AddTestTg' , {
104
+ testListener .addTargetGroups (" AddTestTg" , {
104
105
targetGroups: [testTargetGroup ],
105
106
});
106
107
107
108
// Will be replaced by CodeDeploy in CodePipeline
108
109
const taskDefinition = new DummyTaskDefinition (
109
110
this ,
110
- ' DummyTaskDefinition' ,
111
+ " DummyTaskDefinition" ,
111
112
{
112
- image: ' nginx' ,
113
- family: ' blue-green' ,
114
- },
113
+ image: " nginx" ,
114
+ family: " blue-green" ,
115
+ }
115
116
);
116
117
117
- const ecsService = new EcsService (this , ' EcsService' , {
118
+ const ecsService = new EcsService (this , " EcsService" , {
118
119
cluster ,
119
- serviceName: ' blue-green-service' ,
120
+ serviceName: " blue-green-service" ,
120
121
desiredCount: 2 ,
121
122
taskDefinition ,
122
123
prodTargetGroup ,
@@ -125,9 +126,9 @@ export class BlueGreenContainerDeploymentStack extends Stack {
125
126
ecsService .connections .allowFrom (loadBalancer , Port .tcp (80 ));
126
127
ecsService .connections .allowFrom (loadBalancer , Port .tcp (8080 ));
127
128
128
- const deploymentGroup = new EcsDeploymentGroup (this , ' DeploymentGroup' , {
129
- applicationName: ' blue-green-application' ,
130
- deploymentGroupName: ' blue-green-deployment-group' ,
129
+ const deploymentGroup = new EcsDeploymentGroup (this , " DeploymentGroup" , {
130
+ applicationName: " blue-green-application" ,
131
+ deploymentGroupName: " blue-green-deployment-group" ,
131
132
ecsServices: [ecsService ],
132
133
targetGroupNames: [
133
134
prodTargetGroup .targetGroupName ,
@@ -136,66 +137,78 @@ export class BlueGreenContainerDeploymentStack extends Stack {
136
137
prodTrafficListener: prodListener ,
137
138
testTrafficListener: testListener ,
138
139
terminationWaitTimeInMinutes: 100 ,
140
+ autoRollbackOnEvents: [RollbackEvent .DEPLOYMENT_FAILURE ],
141
+ createDeploymentConfigInput: {
142
+ computePlatform: " ECS" ,
143
+ deploymentConfigName: " Canary20Percent5Minute" ,
144
+ trafficRoutingConfig: {
145
+ type: " TimeBasedCanary" ,
146
+ timeBasedCanary: {
147
+ canaryInterval: 5 ,
148
+ canaryPercentage: 20 ,
149
+ },
150
+ },
151
+ },
139
152
});
140
153
141
154
// @see https://github.com/cloudcomponents/cdk-constructs/tree/master/examples/blue-green-container-deployment-example/blue-green-repository
142
- const repository = new Repository (this , ' CodeRepository' , {
143
- repositoryName: ' blue-green-repository' ,
155
+ const repository = new Repository (this , " CodeRepository" , {
156
+ repositoryName: " blue-green-repository" ,
144
157
});
145
158
146
- const imageRepository = new ImageRepository (this , ' ImageRepository' , {
159
+ const imageRepository = new ImageRepository (this , " ImageRepository" , {
147
160
forceDelete: true , // Only for tests
148
161
});
149
162
150
163
const sourceArtifact = new Artifact ();
151
164
152
165
const sourceAction = new CodeCommitSourceAction ({
153
- actionName: ' CodeCommit' ,
166
+ actionName: " CodeCommit" ,
154
167
repository ,
155
168
output: sourceArtifact ,
156
169
});
157
170
158
- const imageArtifact = new Artifact (' ImageArtifact' );
159
- const manifestArtifact = new Artifact (' ManifestArtifact' );
171
+ const imageArtifact = new Artifact (" ImageArtifact" );
172
+ const manifestArtifact = new Artifact (" ManifestArtifact" );
160
173
161
- const pushImageProject = new PushImageProject (this , ' PushImageProject' , {
174
+ const pushImageProject = new PushImageProject (this , " PushImageProject" , {
162
175
imageRepository ,
163
176
taskDefinition ,
164
177
});
165
178
166
179
const buildAction = new CodeBuildAction ({
167
- actionName: ' PushImage' ,
180
+ actionName: " PushImage" ,
168
181
project: pushImageProject ,
169
182
input: sourceArtifact ,
170
183
outputs: [imageArtifact , manifestArtifact ],
171
184
});
172
185
173
186
const deployAction = new CodeDeployEcsDeployAction ({
174
- actionName: ' CodeDeploy' ,
187
+ actionName: " CodeDeploy" ,
175
188
taskDefinitionTemplateInput: manifestArtifact ,
176
189
appSpecTemplateInput: manifestArtifact ,
177
190
containerImageInputs: [
178
191
{
179
192
input: imageArtifact ,
180
- taskDefinitionPlaceholder: ' IMAGE1_NAME' ,
193
+ taskDefinitionPlaceholder: " IMAGE1_NAME" ,
181
194
},
182
195
],
183
196
deploymentGroup ,
184
197
});
185
198
186
- new Pipeline (this , ' Pipeline' , {
187
- pipelineName: ' blue-green-pipeline' ,
199
+ new Pipeline (this , " Pipeline" , {
200
+ pipelineName: " blue-green-pipeline" ,
188
201
stages: [
189
202
{
190
- stageName: ' Source' ,
203
+ stageName: " Source" ,
191
204
actions: [sourceAction ],
192
205
},
193
206
{
194
- stageName: ' Build' ,
207
+ stageName: " Build" ,
195
208
actions: [buildAction ],
196
209
},
197
210
{
198
- stageName: ' Deploy' ,
211
+ stageName: " Deploy" ,
199
212
actions: [deployAction ],
200
213
},
201
214
],
0 commit comments