Skip to content

Commit 9fad013

Browse files
authored
Merge pull request #129 from cloudcomponents/patch_128
fix: Support multiple pipeline in one stack
2 parents 0ff07cb + e18441d commit 9fad013

File tree

13 files changed

+347
-235
lines changed

13 files changed

+347
-235
lines changed

examples/blue-green-container-deployment-example/src/blue-green-container-deployment-stack.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CodeBuildAction, CodeCommitSourceAction, CodeDeployEcsDeployAction } fr
44
import { Vpc, Port } from '@aws-cdk/aws-ec2';
55
import { Cluster } from '@aws-cdk/aws-ecs';
66
import { ApplicationLoadBalancer, ApplicationTargetGroup, TargetType } from '@aws-cdk/aws-elasticloadbalancingv2';
7-
import { Construct, Stack, StackProps } from '@aws-cdk/core';
7+
import { Construct, Duration, Stack, StackProps } from '@aws-cdk/core';
88

99
import { EcsService, DummyTaskDefinition, EcsDeploymentGroup, PushImageProject } from '@cloudcomponents/cdk-blue-green-container-deployment';
1010
import { ImageRepository } from '@cloudcomponents/cdk-container-registry';
@@ -67,6 +67,7 @@ export class BlueGreenContainerDeploymentStack extends Stack {
6767
desiredCount: 2,
6868
taskDefinition,
6969
prodTargetGroup,
70+
testTargetGroup,
7071
});
7172

7273
ecsService.connections.allowFrom(loadBalancer, Port.tcp(80));
@@ -76,10 +77,10 @@ export class BlueGreenContainerDeploymentStack extends Stack {
7677
applicationName: 'blue-green-application',
7778
deploymentGroupName: 'blue-green-deployment-group',
7879
ecsServices: [ecsService],
79-
targetGroupNames: [prodTargetGroup.targetGroupName, testTargetGroup.targetGroupName],
80+
targetGroups: [prodTargetGroup, testTargetGroup],
8081
prodTrafficListener: prodListener,
8182
testTrafficListener: testListener,
82-
terminationWaitTimeInMinutes: 100,
83+
terminationWaitTime: Duration.minutes(100),
8384
});
8485

8586
// @see files: ./blue-green-repository for example content

packages/cdk-blue-green-container-deployment/API.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,12 @@ new EcsDeploymentGroup(scope: Construct, id: string, props: EcsDeploymentGroupPr
177177
* **deploymentGroupName** (<code>string</code>) *No description*
178178
* **ecsServices** (<code>Array<[IEcsService](#cloudcomponents-cdk-blue-green-container-deployment-iecsservice)></code>) *No description*
179179
* **prodTrafficListener** (<code>[TrafficListener](#cloudcomponents-cdk-blue-green-container-deployment-trafficlistener)</code>) *No description*
180-
* **targetGroupNames** (<code>Array<string></code>) *No description*
180+
* **targetGroups** (<code>Array<[ApplicationTargetGroup](#aws-cdk-aws-elasticloadbalancingv2-applicationtargetgroup)></code>) *No description*
181181
* **testTrafficListener** (<code>[TrafficListener](#cloudcomponents-cdk-blue-green-container-deployment-trafficlistener)</code>) *No description*
182182
* **applicationName** (<code>string</code>) *No description* __*Optional*__
183183
* **autoRollbackOnEvents** (<code>Array<[RollbackEvent](#cloudcomponents-cdk-blue-green-container-deployment-rollbackevent)></code>) The event type or types that trigger a rollback. __*Optional*__
184184
* **deploymentConfig** (<code>[IEcsDeploymentConfig](#cloudcomponents-cdk-blue-green-container-deployment-iecsdeploymentconfig)</code>) *No description* __*Optional*__
185-
* **terminationWaitTimeInMinutes** (<code>number</code>) the number of minutes before deleting the original (blue) task set. __*Default*__: 60
185+
* **terminationWaitTime** (<code>[Duration](#aws-cdk-core-duration)</code>) the number of minutes before deleting the original (blue) task set. __*Default*__: 60 minutes
186186

187187

188188

@@ -221,6 +221,7 @@ new EcsService(scope: Construct, id: string, props: EcsServiceProps)
221221
* **prodTargetGroup** (<code>[ITargetGroup](#aws-cdk-aws-elasticloadbalancingv2-itargetgroup)</code>) *No description*
222222
* **serviceName** (<code>string</code>) *No description*
223223
* **taskDefinition** (<code>[DummyTaskDefinition](#cloudcomponents-cdk-blue-green-container-deployment-dummytaskdefinition)</code>) *No description*
224+
* **testTargetGroup** (<code>[ITargetGroup](#aws-cdk-aws-elasticloadbalancingv2-itargetgroup)</code>) *No description*
224225
* **circuitBreaker** (<code>[DeploymentCircuitBreaker](#aws-cdk-aws-ecs-deploymentcircuitbreaker)</code>) Whether to enable the deployment circuit breaker. __*Default*__: disabled
225226
* **containerPort** (<code>number</code>) *No description* __*Optional*__
226227
* **desiredCount** (<code>number</code>) *No description* __*Optional*__
@@ -317,12 +318,12 @@ Name | Type | Description
317318
**deploymentGroupName** | <code>string</code> | <span></span>
318319
**ecsServices** | <code>Array<[IEcsService](#cloudcomponents-cdk-blue-green-container-deployment-iecsservice)></code> | <span></span>
319320
**prodTrafficListener** | <code>[TrafficListener](#cloudcomponents-cdk-blue-green-container-deployment-trafficlistener)</code> | <span></span>
320-
**targetGroupNames** | <code>Array<string></code> | <span></span>
321+
**targetGroups** | <code>Array<[ApplicationTargetGroup](#aws-cdk-aws-elasticloadbalancingv2-applicationtargetgroup)></code> | <span></span>
321322
**testTrafficListener** | <code>[TrafficListener](#cloudcomponents-cdk-blue-green-container-deployment-trafficlistener)</code> | <span></span>
322323
**applicationName**? | <code>string</code> | __*Optional*__
323324
**autoRollbackOnEvents**? | <code>Array<[RollbackEvent](#cloudcomponents-cdk-blue-green-container-deployment-rollbackevent)></code> | The event type or types that trigger a rollback.<br/>__*Optional*__
324325
**deploymentConfig**? | <code>[IEcsDeploymentConfig](#cloudcomponents-cdk-blue-green-container-deployment-iecsdeploymentconfig)</code> | __*Optional*__
325-
**terminationWaitTimeInMinutes**? | <code>number</code> | the number of minutes before deleting the original (blue) task set.<br/>__*Default*__: 60
326+
**terminationWaitTime**? | <code>[Duration](#aws-cdk-core-duration)</code> | the number of minutes before deleting the original (blue) task set.<br/>__*Default*__: 60 minutes
326327

327328

328329

@@ -339,6 +340,7 @@ Name | Type | Description
339340
**prodTargetGroup** | <code>[ITargetGroup](#aws-cdk-aws-elasticloadbalancingv2-itargetgroup)</code> | <span></span>
340341
**serviceName** | <code>string</code> | <span></span>
341342
**taskDefinition** | <code>[DummyTaskDefinition](#cloudcomponents-cdk-blue-green-container-deployment-dummytaskdefinition)</code> | <span></span>
343+
**testTargetGroup** | <code>[ITargetGroup](#aws-cdk-aws-elasticloadbalancingv2-itargetgroup)</code> | <span></span>
342344
**circuitBreaker**? | <code>[DeploymentCircuitBreaker](#aws-cdk-aws-ecs-deploymentcircuitbreaker)</code> | Whether to enable the deployment circuit breaker.<br/>__*Default*__: disabled
343345
**containerPort**? | <code>number</code> | __*Optional*__
344346
**desiredCount**? | <code>number</code> | __*Optional*__
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"timestamp":1631683651094,"files":[{"filename":"dummy-task-definition/index.js","previous":1728,"size":1728,"diff":0},{"filename":"ecs-deployment-group/index.js","previous":2182,"size":2182,"diff":0},{"filename":"ecs-service/index.js","previous":2152,"size":2138,"diff":-14}]},{"timestamp":1629825530770,"files":[{"filename":"dummy-task-definition/index.js","previous":1728,"size":1728,"diff":0},{"filename":"ecs-deployment-group/index.js","previous":2171,"size":2182,"diff":11},{"filename":"ecs-service/index.js","previous":2152,"size":2152,"diff":0}]},{"timestamp":1629823812165,"files":[{"filename":"dummy-task-definition/index.js","previous":1728,"size":1728,"diff":0},{"filename":"ecs-deployment-group/index.js","previous":2123,"size":2171,"diff":48},{"filename":"ecs-service/index.js","previous":2152,"size":2152,"diff":0}]},{"timestamp":1627652613714,"files":[{"filename":"dummy-task-definition/index.js","previous":1726,"size":1728,"diff":2},{"filename":"ecs-deployment-group/index.js","previous":2123,"size":2123,"diff":0},{"filename":"ecs-service/index.js","previous":2081,"size":2152,"diff":71}]},{"timestamp":1609276390870,"files":[{"filename":"dummy-task-definition/index.js","previous":1712,"size":1726,"diff":14},{"filename":"ecs-deployment-group/index.js","previous":2123,"size":2123,"diff":0},{"filename":"ecs-service/index.js","previous":2081,"size":2081,"diff":0}]},{"timestamp":1606329521054,"files":[{"filename":"dummy-task-definition/index.js","previous":1706,"size":1712,"diff":6},{"filename":"ecs-deployment-group/index.js","previous":2116,"size":2123,"diff":7},{"filename":"ecs-service/index.js","previous":2073,"size":2081,"diff":8}]},{"timestamp":1596457247342,"files":[{"filename":"dummy-task-definition/index.js","previous":1756,"size":1706,"diff":-50},{"filename":"ecs-deployment-group/index.js","previous":2116,"size":2116,"diff":0},{"filename":"ecs-service/index.js","previous":2073,"size":2073,"diff":0}]},{"timestamp":1596454924871,"files":[{"filename":"dummy-task-definition/index.js","previous":4964,"size":1756,"diff":-3208},{"filename":"ecs-deployment-group/index.js","previous":6103,"size":2116,"diff":-3987},{"filename":"ecs-service/index.js","previous":6141,"size":2073,"diff":-4068}]},{"timestamp":1596407637937,"files":[{"filename":"blue-green-service/__entrypoint__.js","previous":6760,"size":0,"diff":-6760},{"filename":"blue-green-service/index.js","previous":3368,"size":0,"diff":-3368},{"filename":"dummy-task-definition/__entrypoint__.js","previous":6760,"size":0,"diff":-6760},{"filename":"dummy-task-definition/index.js","previous":1963,"size":4964,"diff":3001},{"filename":"ecs-deployment-group/__entrypoint__.js","previous":6760,"size":0,"diff":-6760},{"filename":"ecs-deployment-group/index.js","previous":2292,"size":6103,"diff":3811},{"filename":"ecs-service/__entrypoint__.js","previous":6760,"size":0,"diff":-6760},{"filename":"ecs-service/index.js","previous":2312,"size":6141,"diff":3829}]}]
1+
[{"timestamp":1634467601943,"files":[{"filename":"ecs-deployment-group/index.js","previous":144792,"size":144825,"diff":33},{"filename":"ecs-service/index.js","previous":2133,"size":144797,"diff":142664}]},{"timestamp":1634411334117,"files":[{"filename":"dummy-task-definition/index.js","previous":1728,"size":0,"diff":-1728},{"filename":"ecs-deployment-group/index.js","previous":2182,"size":144792,"diff":142610},{"filename":"ecs-service/index.js","previous":2138,"size":2133,"diff":-5}]},{"timestamp":1631683651094,"files":[{"filename":"dummy-task-definition/index.js","previous":1728,"size":1728,"diff":0},{"filename":"ecs-deployment-group/index.js","previous":2182,"size":2182,"diff":0},{"filename":"ecs-service/index.js","previous":2152,"size":2138,"diff":-14}]},{"timestamp":1629825530770,"files":[{"filename":"dummy-task-definition/index.js","previous":1728,"size":1728,"diff":0},{"filename":"ecs-deployment-group/index.js","previous":2171,"size":2182,"diff":11},{"filename":"ecs-service/index.js","previous":2152,"size":2152,"diff":0}]},{"timestamp":1629823812165,"files":[{"filename":"dummy-task-definition/index.js","previous":1728,"size":1728,"diff":0},{"filename":"ecs-deployment-group/index.js","previous":2123,"size":2171,"diff":48},{"filename":"ecs-service/index.js","previous":2152,"size":2152,"diff":0}]},{"timestamp":1627652613714,"files":[{"filename":"dummy-task-definition/index.js","previous":1726,"size":1728,"diff":2},{"filename":"ecs-deployment-group/index.js","previous":2123,"size":2123,"diff":0},{"filename":"ecs-service/index.js","previous":2081,"size":2152,"diff":71}]},{"timestamp":1609276390870,"files":[{"filename":"dummy-task-definition/index.js","previous":1712,"size":1726,"diff":14},{"filename":"ecs-deployment-group/index.js","previous":2123,"size":2123,"diff":0},{"filename":"ecs-service/index.js","previous":2081,"size":2081,"diff":0}]},{"timestamp":1606329521054,"files":[{"filename":"dummy-task-definition/index.js","previous":1706,"size":1712,"diff":6},{"filename":"ecs-deployment-group/index.js","previous":2116,"size":2123,"diff":7},{"filename":"ecs-service/index.js","previous":2073,"size":2081,"diff":8}]},{"timestamp":1596457247342,"files":[{"filename":"dummy-task-definition/index.js","previous":1756,"size":1706,"diff":-50},{"filename":"ecs-deployment-group/index.js","previous":2116,"size":2116,"diff":0},{"filename":"ecs-service/index.js","previous":2073,"size":2073,"diff":0}]},{"timestamp":1596454924871,"files":[{"filename":"dummy-task-definition/index.js","previous":4964,"size":1756,"diff":-3208},{"filename":"ecs-deployment-group/index.js","previous":6103,"size":2116,"diff":-3987},{"filename":"ecs-service/index.js","previous":6141,"size":2073,"diff":-4068}]},{"timestamp":1596407637937,"files":[{"filename":"blue-green-service/__entrypoint__.js","previous":6760,"size":0,"diff":-6760},{"filename":"blue-green-service/index.js","previous":3368,"size":0,"diff":-3368},{"filename":"dummy-task-definition/__entrypoint__.js","previous":6760,"size":0,"diff":-6760},{"filename":"dummy-task-definition/index.js","previous":1963,"size":4964,"diff":3001},{"filename":"ecs-deployment-group/__entrypoint__.js","previous":6760,"size":0,"diff":-6760},{"filename":"ecs-deployment-group/index.js","previous":2292,"size":6103,"diff":3811},{"filename":"ecs-service/__entrypoint__.js","previous":6760,"size":0,"diff":-6760},{"filename":"ecs-service/index.js","previous":2312,"size":6141,"diff":3829}]}]

packages/cdk-blue-green-container-deployment/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,27 +63,32 @@
6363
"peerDependencies": {
6464
"@aws-cdk/aws-codebuild": "^1.127.0",
6565
"@aws-cdk/aws-codedeploy": "^1.127.0",
66+
"@aws-cdk/custom-resources": "^1.127.0",
6667
"@aws-cdk/aws-ec2": "^1.127.0",
6768
"@aws-cdk/aws-ecr": "^1.127.0",
6869
"@aws-cdk/aws-ecs": "^1.127.0",
6970
"@aws-cdk/aws-elasticloadbalancingv2": "^1.127.0",
7071
"@aws-cdk/aws-iam": "^1.127.0",
72+
"@aws-cdk/aws-lambda": "^1.127.0",
7173
"@aws-cdk/core": "^1.127.0",
7274
"constructs": "^3.2.0"
7375
},
7476
"dependencies": {
7577
"@aws-cdk/aws-codebuild": "^1.127.0",
7678
"@aws-cdk/aws-codedeploy": "^1.127.0",
79+
"@aws-cdk/custom-resources": "^1.127.0",
7780
"@aws-cdk/aws-ec2": "^1.127.0",
7881
"@aws-cdk/aws-ecr": "^1.127.0",
7982
"@aws-cdk/aws-ecs": "^1.127.0",
8083
"@aws-cdk/aws-elasticloadbalancingv2": "^1.127.0",
8184
"@aws-cdk/aws-iam": "^1.127.0",
85+
"@aws-cdk/aws-lambda": "^1.127.0",
8286
"@aws-cdk/core": "^1.127.0"
8387
},
8488
"devDependencies": {
8589
"@aws-cdk/assert": "^1.127.0",
8690
"aws-sdk": "^2.1004.0",
91+
"custom-resource-helper": "^1.0.15",
8792
"jest-cdk-snapshot": "^1.4.2"
8893
},
8994
"externals": [
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`default setup 1`] = `
4+
Object {
5+
"Parameters": Any<Object>,
6+
"Resources": Object {
7+
"AWS679f53fac002430cb0da5b7982bd22872D164C4C": Object {
8+
"DependsOn": Array [
9+
"AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2",
10+
],
11+
"Properties": Object {
12+
"Code": Any<Object>,
13+
"Handler": "index.handler",
14+
"Role": Object {
15+
"Fn::GetAtt": Array [
16+
"AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2",
17+
"Arn",
18+
],
19+
},
20+
"Runtime": "nodejs12.x",
21+
"Timeout": 120,
22+
},
23+
"Type": "AWS::Lambda::Function",
24+
},
25+
"AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2": Object {
26+
"Properties": Object {
27+
"AssumeRolePolicyDocument": Object {
28+
"Statement": Array [
29+
Object {
30+
"Action": "sts:AssumeRole",
31+
"Effect": "Allow",
32+
"Principal": Object {
33+
"Service": "lambda.amazonaws.com",
34+
},
35+
},
36+
],
37+
"Version": "2012-10-17",
38+
},
39+
"ManagedPolicyArns": Array [
40+
Object {
41+
"Fn::Join": Array [
42+
"",
43+
Array [
44+
"arn:",
45+
Object {
46+
"Ref": "AWS::Partition",
47+
},
48+
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
49+
],
50+
],
51+
},
52+
],
53+
},
54+
"Type": "AWS::IAM::Role",
55+
},
56+
"DummyTaskDefinitionCustomResourcePolicyB5660701": Object {
57+
"Properties": Object {
58+
"PolicyDocument": Object {
59+
"Statement": Array [
60+
Object {
61+
"Action": Array [
62+
"ecs:RegisterTaskDefinition",
63+
"ecs:DeregisterTaskDefinition",
64+
],
65+
"Effect": "Allow",
66+
"Resource": "*",
67+
},
68+
Object {
69+
"Action": "iam:PassRole",
70+
"Effect": "Allow",
71+
"Resource": Object {
72+
"Fn::GetAtt": Array [
73+
"DummyTaskDefinitionExecutionRole715DBD43",
74+
"Arn",
75+
],
76+
},
77+
},
78+
],
79+
"Version": "2012-10-17",
80+
},
81+
"PolicyName": "DummyTaskDefinitionCustomResourcePolicyB5660701",
82+
"Roles": Array [
83+
Object {
84+
"Ref": "AWS679f53fac002430cb0da5b7982bd2287ServiceRoleC1EA0FF2",
85+
},
86+
],
87+
},
88+
"Type": "AWS::IAM::Policy",
89+
},
90+
"DummyTaskDefinitionE3D9D432": Object {
91+
"DeletionPolicy": "Delete",
92+
"DependsOn": Array [
93+
"DummyTaskDefinitionCustomResourcePolicyB5660701",
94+
],
95+
"Properties": Object {
96+
"Create": Object {
97+
"Fn::Join": Array [
98+
"",
99+
Array [
100+
"{\\"service\\":\\"ECS\\",\\"action\\":\\"registerTaskDefinition\\",\\"parameters\\":{\\"requiresCompatibilities\\":[\\"FARGATE\\"],\\"family\\":\\"c86e1e5d419d3c124c7e40411b7e7805f91621e162\\",\\"executionRoleArn\\":\\"",
101+
Object {
102+
"Fn::GetAtt": Array [
103+
"DummyTaskDefinitionExecutionRole715DBD43",
104+
"Arn",
105+
],
106+
},
107+
"\\",\\"networkMode\\":\\"awsvpc\\",\\"cpu\\":\\"256\\",\\"memory\\":\\"512\\",\\"containerDefinitions\\":[{\\"name\\":\\"sample-website\\",\\"image\\":\\"image\\",\\"portMappings\\":[{\\"hostPort\\":80,\\"protocol\\":\\"tcp\\",\\"containerPort\\":80}]}]},\\"physicalResourceId\\":{\\"responsePath\\":\\"taskDefinition.taskDefinitionArn\\"}}",
108+
],
109+
],
110+
},
111+
"Delete": "{\\"service\\":\\"ECS\\",\\"action\\":\\"deregisterTaskDefinition\\",\\"parameters\\":{\\"taskDefinition\\":\\"PHYSICAL:RESOURCEID:\\"}}",
112+
"InstallLatestAwsSdk": true,
113+
"ServiceToken": Object {
114+
"Fn::GetAtt": Array [
115+
"AWS679f53fac002430cb0da5b7982bd22872D164C4C",
116+
"Arn",
117+
],
118+
},
119+
},
120+
"Type": "Custom::DummyTaskDefinition",
121+
"UpdateReplacePolicy": "Delete",
122+
},
123+
"DummyTaskDefinitionExecutionRole715DBD43": Object {
124+
"Properties": Object {
125+
"AssumeRolePolicyDocument": Object {
126+
"Statement": Array [
127+
Object {
128+
"Action": "sts:AssumeRole",
129+
"Effect": "Allow",
130+
"Principal": Object {
131+
"Service": "ecs-tasks.amazonaws.com",
132+
},
133+
},
134+
],
135+
"Version": "2012-10-17",
136+
},
137+
"ManagedPolicyArns": Array [
138+
Object {
139+
"Fn::Join": Array [
140+
"",
141+
Array [
142+
"arn:",
143+
Object {
144+
"Ref": "AWS::Partition",
145+
},
146+
":iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
147+
],
148+
],
149+
},
150+
],
151+
},
152+
"Type": "AWS::IAM::Role",
153+
},
154+
},
155+
}
156+
`;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Stack } from '@aws-cdk/core';
2+
import 'jest-cdk-snapshot';
3+
4+
import { DummyTaskDefinition } from '../dummy-task-definition';
5+
6+
test('default setup', (): void => {
7+
const stack = new Stack();
8+
9+
new DummyTaskDefinition(stack, 'DummyTaskDefinition', {
10+
image: 'image',
11+
});
12+
13+
expect(stack).toMatchCdkSnapshot({
14+
ignoreAssets: true,
15+
});
16+
});

0 commit comments

Comments
 (0)