konokenj.cdk-api-mcp-server 0.39.0__py3-none-any.whl → 0.41.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cdk_api_mcp_server/__about__.py +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/custom-resource-handlers/README.md +78 -15
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/README.md/README.md +364 -16
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/README.md +144 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api-dualstack.ts +4 -3
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api.ts +4 -2
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.stage.ts +20 -7
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.usage-plan.ts +80 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-authorizers/integ.iam.ts +38 -34
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.sqs.ts +71 -58
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-autoscaling/README.md +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codedeploy/integ.deployment-config.ts +15 -4
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codedeploy/integ.deployment-group.ts +40 -218
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/README.md +21 -68
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.availability-zone-rebalancing.ts +4 -14
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.blue-green-deployment-strategy.ts +13 -71
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.enable-execute-command.ts +29 -35
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.exec-command.ts +22 -16
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.lb-awsvpc-nw.ts +16 -26
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.pseudo-terminal.ts +8 -18
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/README.md +2 -2
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-route53/integ.delete-existing-record-set.ts +0 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-cross-stack-ssm-source.ts +91 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-notifications/integ.bucket-notifications.ts +80 -42
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-signer/integ.signing-profile.ts +5 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/README.md +9 -3
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke-jsonata.ts +80 -87
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke.ts +69 -87
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.start-job-run.ts +104 -102
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/core/README.md +2 -1893
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +25 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/README.md +24 -1
- {konokenj_cdk_api_mcp_server-0.39.0.dist-info → konokenj_cdk_api_mcp_server-0.41.0.dist-info}/METADATA +2 -2
- {konokenj_cdk_api_mcp_server-0.39.0.dist-info → konokenj_cdk_api_mcp_server-0.41.0.dist-info}/RECORD +37 -35
- {konokenj_cdk_api_mcp_server-0.39.0.dist-info → konokenj_cdk_api_mcp_server-0.41.0.dist-info}/WHEEL +0 -0
- {konokenj_cdk_api_mcp_server-0.39.0.dist-info → konokenj_cdk_api_mcp_server-0.41.0.dist-info}/entry_points.txt +0 -0
- {konokenj_cdk_api_mcp_server-0.39.0.dist-info → konokenj_cdk_api_mcp_server-0.41.0.dist-info}/licenses/LICENSE.txt +0 -0
cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codedeploy/integ.deployment-group.ts
CHANGED
|
@@ -1,240 +1,62 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
1
2
|
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
|
|
2
|
-
import * as
|
|
3
|
-
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
4
|
-
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
|
|
3
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
5
4
|
import * as cdk from 'aws-cdk-lib';
|
|
6
|
-
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
7
5
|
import * as codedeploy from 'aws-cdk-lib/aws-codedeploy';
|
|
6
|
+
import { STANDARD_NODEJS_RUNTIME } from '../../../config';
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* 1. Deploy the stack:
|
|
13
|
-
```
|
|
14
|
-
$ cdk deploy --app 'node integ.deployment-group.js' aws-cdk-codedeploy-ecs-dg
|
|
15
|
-
```
|
|
16
|
-
*
|
|
17
|
-
* 2. Create a file called `appspec.json` with the following contents, replacing the placeholders with output values from the deployed stack:
|
|
18
|
-
```
|
|
19
|
-
{
|
|
20
|
-
"version": 0.0,
|
|
21
|
-
"Resources": [
|
|
22
|
-
{
|
|
23
|
-
"TargetService": {
|
|
24
|
-
"Type": "AWS::ECS::Service",
|
|
25
|
-
"Properties": {
|
|
26
|
-
"TaskDefinition": "<PLACEHOLDER - NEW TASK DEFINITION>",
|
|
27
|
-
"LoadBalancerInfo": {
|
|
28
|
-
"ContainerName": "Container",
|
|
29
|
-
"ContainerPort": 80
|
|
30
|
-
},
|
|
31
|
-
"PlatformVersion": "LATEST",
|
|
32
|
-
"NetworkConfiguration": {
|
|
33
|
-
"awsvpcConfiguration": {
|
|
34
|
-
"subnets": [
|
|
35
|
-
"<PLACEHOLDER - SUBNET 1 ID>",
|
|
36
|
-
"<PLACEHOLDER - SUBNET 2 ID>",
|
|
37
|
-
],
|
|
38
|
-
"securityGroups": [
|
|
39
|
-
"<PLACEHOLDER - SECURITY GROUP ID>"
|
|
40
|
-
],
|
|
41
|
-
"assignPublicIp": "DISABLED"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
*
|
|
51
|
-
* 3. Start the deployment:
|
|
52
|
-
```
|
|
53
|
-
$ appspec=$(jq -R -s '.' < appspec.json | sed 's/\\n//g')
|
|
54
|
-
$ aws deploy create-deployment \
|
|
55
|
-
--application-name <PLACEHOLDER - CODEDEPLOY APPLICATION NAME> \
|
|
56
|
-
--deployment-group-name <PLACEHOLDER - CODEDEPLOY DEPLOYMENT GROUP NAME> \
|
|
57
|
-
--description "AWS CDK integ test" \
|
|
58
|
-
--revision revisionType=AppSpecContent,appSpecContent={content="$appspec"}
|
|
59
|
-
```
|
|
60
|
-
*
|
|
61
|
-
* 4. Wait for the deployment to complete successfully, providing the deployment ID from the previous step:
|
|
62
|
-
```
|
|
63
|
-
$ aws deploy wait deployment-successful --deployment-id <PLACEHOLDER - DEPLOYMENT ID>
|
|
64
|
-
```
|
|
65
|
-
*
|
|
66
|
-
* 5. Destroy the stack:
|
|
67
|
-
```
|
|
68
|
-
$ cdk destroy --app 'node integ.deployment-group.js' aws-cdk-codedeploy-ecs-dg
|
|
69
|
-
```
|
|
70
|
-
*/
|
|
71
|
-
|
|
72
|
-
const app = new cdk.App();
|
|
73
|
-
const stack = new cdk.Stack(app, 'aws-cdk-codedeploy-ecs-dg');
|
|
74
|
-
|
|
75
|
-
// Network infrastructure
|
|
76
|
-
const vpc = new ec2.Vpc(stack, 'VPC', { maxAzs: 2, restrictDefaultSecurityGroup: false });
|
|
77
|
-
|
|
78
|
-
// ECS service
|
|
79
|
-
const cluster = new ecs.Cluster(stack, 'EcsCluster', {
|
|
80
|
-
vpc,
|
|
81
|
-
});
|
|
82
|
-
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef');
|
|
83
|
-
taskDefinition.addContainer('Container', {
|
|
84
|
-
image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'),
|
|
85
|
-
portMappings: [{ containerPort: 80 }],
|
|
86
|
-
});
|
|
87
|
-
const service = new ecs.FargateService(stack, 'FargateService', {
|
|
88
|
-
cluster,
|
|
89
|
-
taskDefinition,
|
|
90
|
-
deploymentController: {
|
|
91
|
-
type: ecs.DeploymentControllerType.CODE_DEPLOY,
|
|
8
|
+
const app = new cdk.App({
|
|
9
|
+
postCliContext: {
|
|
10
|
+
'@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
|
|
92
11
|
},
|
|
93
12
|
});
|
|
13
|
+
const stack = new cdk.Stack(app, 'aws-cdk-codedeploy-lambda');
|
|
94
14
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
portMappings: [{ containerPort: 80 }],
|
|
15
|
+
const handler = new lambda.Function(stack, 'Handler', {
|
|
16
|
+
code: lambda.Code.fromAsset(path.join(__dirname, 'handler')),
|
|
17
|
+
handler: 'index.handler',
|
|
18
|
+
runtime: STANDARD_NODEJS_RUNTIME,
|
|
100
19
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
vpc,
|
|
106
|
-
internetFacing: false,
|
|
20
|
+
const version = handler.currentVersion;
|
|
21
|
+
const blueGreenAlias = new lambda.Alias(stack, 'Alias', {
|
|
22
|
+
aliasName: 'alias',
|
|
23
|
+
version,
|
|
107
24
|
});
|
|
108
25
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
26
|
+
const preHook = new lambda.Function(stack, 'PreHook', {
|
|
27
|
+
code: lambda.Code.fromAsset(path.join(__dirname, 'preHook')),
|
|
28
|
+
handler: 'index.handler',
|
|
29
|
+
runtime: STANDARD_NODEJS_RUNTIME,
|
|
113
30
|
});
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
31
|
+
const postHook = new lambda.Function(stack, 'PostHook', {
|
|
32
|
+
code: lambda.Code.fromAsset(path.join(__dirname, 'postHook')),
|
|
33
|
+
handler: 'index.handler',
|
|
34
|
+
runtime: STANDARD_NODEJS_RUNTIME,
|
|
117
35
|
});
|
|
118
36
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
37
|
+
new codedeploy.LambdaDeploymentGroup(stack, 'BlueGreenDeployment', {
|
|
38
|
+
alias: blueGreenAlias,
|
|
39
|
+
deploymentConfig: codedeploy.LambdaDeploymentConfig.LINEAR_10PERCENT_EVERY_1MINUTE,
|
|
40
|
+
alarms: [
|
|
41
|
+
new cloudwatch.Alarm(stack, 'BlueGreenErrors', {
|
|
42
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
43
|
+
threshold: 1,
|
|
44
|
+
evaluationPeriods: 1,
|
|
45
|
+
metric: blueGreenAlias.metricErrors(),
|
|
127
46
|
}),
|
|
128
47
|
],
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
interval: cdk.Duration.seconds(5),
|
|
132
|
-
healthyHttpCodes: '200',
|
|
133
|
-
healthyThresholdCount: 2,
|
|
134
|
-
unhealthyThresholdCount: 3,
|
|
135
|
-
timeout: cdk.Duration.seconds(4),
|
|
136
|
-
},
|
|
48
|
+
preHook,
|
|
49
|
+
postHook,
|
|
137
50
|
});
|
|
138
51
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
protocol: elbv2.ApplicationProtocol.HTTP,
|
|
143
|
-
targetType: elbv2.TargetType.IP,
|
|
144
|
-
deregistrationDelay: cdk.Duration.seconds(30),
|
|
145
|
-
healthCheck: {
|
|
146
|
-
interval: cdk.Duration.seconds(5),
|
|
147
|
-
healthyHttpCodes: '200',
|
|
148
|
-
healthyThresholdCount: 2,
|
|
149
|
-
unhealthyThresholdCount: 3,
|
|
150
|
-
timeout: cdk.Duration.seconds(4),
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
testListener.addTargetGroups('GreenTGTest', {
|
|
155
|
-
targetGroups: [greenTG],
|
|
52
|
+
const secondAlias = new lambda.Alias(stack, 'SecondAlias', {
|
|
53
|
+
aliasName: 'secondAlias',
|
|
54
|
+
version,
|
|
156
55
|
});
|
|
157
56
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
service.node.addDependency(greenTG);
|
|
162
|
-
|
|
163
|
-
// Alarms: monitor 500s and unhealthy hosts on target groups
|
|
164
|
-
const blueUnhealthyHosts = new cloudwatch.Alarm(stack, 'BlueUnhealthyHosts', {
|
|
165
|
-
alarmName: stack.stackName + '-Unhealthy-Hosts-Blue',
|
|
166
|
-
metric: blueTG.metricUnhealthyHostCount(),
|
|
167
|
-
threshold: 1,
|
|
168
|
-
evaluationPeriods: 2,
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
const blueApiFailure = new cloudwatch.Alarm(stack, 'Blue5xx', {
|
|
172
|
-
alarmName: stack.stackName + '-Http-500-Blue',
|
|
173
|
-
metric: blueTG.metricHttpCodeTarget(
|
|
174
|
-
elbv2.HttpCodeTarget.TARGET_5XX_COUNT,
|
|
175
|
-
{ period: cdk.Duration.minutes(1) },
|
|
176
|
-
),
|
|
177
|
-
threshold: 1,
|
|
178
|
-
evaluationPeriods: 1,
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
const greenUnhealthyHosts = new cloudwatch.Alarm(stack, 'GreenUnhealthyHosts', {
|
|
182
|
-
alarmName: stack.stackName + '-Unhealthy-Hosts-Green',
|
|
183
|
-
metric: greenTG.metricUnhealthyHostCount(),
|
|
184
|
-
threshold: 1,
|
|
185
|
-
evaluationPeriods: 2,
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
const greenApiFailure = new cloudwatch.Alarm(stack, 'Green5xx', {
|
|
189
|
-
alarmName: stack.stackName + '-Http-500-Green',
|
|
190
|
-
metric: greenTG.metricHttpCodeTarget(
|
|
191
|
-
elbv2.HttpCodeTarget.TARGET_5XX_COUNT,
|
|
192
|
-
{ period: cdk.Duration.minutes(1) },
|
|
193
|
-
),
|
|
194
|
-
threshold: 1,
|
|
195
|
-
evaluationPeriods: 1,
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// Deployment group
|
|
199
|
-
const deploymentConfig = new codedeploy.EcsDeploymentConfig(stack, 'CanaryConfig', {
|
|
200
|
-
trafficRouting: codedeploy.TrafficRouting.timeBasedCanary({
|
|
201
|
-
interval: cdk.Duration.minutes(1),
|
|
202
|
-
percentage: 20,
|
|
203
|
-
}),
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
const dg = new codedeploy.EcsDeploymentGroup(stack, 'BlueGreenDG', {
|
|
207
|
-
alarms: [
|
|
208
|
-
blueUnhealthyHosts,
|
|
209
|
-
blueApiFailure,
|
|
210
|
-
greenUnhealthyHosts,
|
|
211
|
-
greenApiFailure,
|
|
212
|
-
],
|
|
213
|
-
service,
|
|
214
|
-
blueGreenDeploymentConfig: {
|
|
215
|
-
blueTargetGroup: blueTG,
|
|
216
|
-
greenTargetGroup: greenTG,
|
|
217
|
-
listener: prodListener,
|
|
218
|
-
testListener,
|
|
219
|
-
terminationWaitTime: cdk.Duration.minutes(1),
|
|
220
|
-
},
|
|
221
|
-
deploymentConfig,
|
|
222
|
-
autoRollback: {
|
|
223
|
-
stoppedDeployment: true,
|
|
224
|
-
},
|
|
225
|
-
ignoreAlarmConfiguration: true,
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
// Outputs to use for manual testing
|
|
229
|
-
new cdk.CfnOutput(stack, 'NewTaskDefinition', { value: taskDefinition2.taskDefinitionArn });
|
|
230
|
-
new cdk.CfnOutput(stack, 'Subnet1Id', { value: vpc.privateSubnets[0].subnetId });
|
|
231
|
-
new cdk.CfnOutput(stack, 'Subnet2Id', { value: vpc.privateSubnets[1].subnetId });
|
|
232
|
-
new cdk.CfnOutput(stack, 'SecurityGroupId', { value: service.connections.securityGroups[0].securityGroupId });
|
|
233
|
-
new cdk.CfnOutput(stack, 'CodeDeployApplicationName', { value: dg.application.applicationName });
|
|
234
|
-
new cdk.CfnOutput(stack, 'CodeDeployDeploymentGroupName', { value: dg.deploymentGroupName });
|
|
235
|
-
|
|
236
|
-
new integ.IntegTest(app, 'EcsDeploymentGroupTest', {
|
|
237
|
-
testCases: [stack],
|
|
57
|
+
new codedeploy.LambdaDeploymentGroup(stack, 'SecondDeployment', {
|
|
58
|
+
alias: secondAlias,
|
|
59
|
+
deploymentConfig: codedeploy.LambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES,
|
|
238
60
|
});
|
|
239
61
|
|
|
240
62
|
app.synth();
|
|
@@ -2076,84 +2076,37 @@ Amazon ECS supports native blue/green deployments that allow you to deploy new v
|
|
|
2076
2076
|
|
|
2077
2077
|
[Amazon ECS blue/green deployments](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-type-blue-green.html)
|
|
2078
2078
|
|
|
2079
|
-
### Using Escape Hatches for Blue/Green Features
|
|
2080
|
-
|
|
2081
|
-
The new blue/green deployment features are added to CloudFormation but not yet available in the CDK L2 constructs, you can use escape hatches to access them through the L1 (CfnService) construct.
|
|
2082
|
-
|
|
2083
|
-
#### Load Balancer Advanced Configuration
|
|
2084
|
-
|
|
2085
|
-
Configure advanced load balancer settings for blue/green deployments with alternate target groups and listener rules:
|
|
2086
|
-
|
|
2087
2079
|
```ts
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
const cfnService = service.node.defaultChild as ecs.CfnService;
|
|
2091
|
-
cfnService.loadBalancers = [{
|
|
2092
|
-
containerName: 'web',
|
|
2093
|
-
containerPort: 80,
|
|
2094
|
-
targetGroupArn: 'arn:aws:elasticloadbalancing:region:account:targetgroup/production',
|
|
2095
|
-
advancedConfiguration: {
|
|
2096
|
-
alternateTargetGroupArn: 'arn:aws:elasticloadbalancing:region:account:targetgroup/test',
|
|
2097
|
-
productionListenerRule: 'arn:aws:elasticloadbalancing:region:account:listener-rule/production-rule',
|
|
2098
|
-
testListenerRule: 'arn:aws:elasticloadbalancing:region:account:listener-rule/test-rule',
|
|
2099
|
-
roleArn: 'arn:aws:iam::account:role/ecs-blue-green-role'
|
|
2100
|
-
}
|
|
2101
|
-
}];
|
|
2102
|
-
```
|
|
2103
|
-
|
|
2104
|
-
#### Blue/Green Deployment Configuration
|
|
2105
|
-
|
|
2106
|
-
Configure deployment strategy with bake time and lifecycle hooks:
|
|
2107
|
-
|
|
2108
|
-
```ts
|
|
2109
|
-
declare const service: ecs.FargateService;
|
|
2110
|
-
|
|
2111
|
-
const cfnService = service.node.defaultChild as ecs.CfnService;
|
|
2112
|
-
cfnService.deploymentConfiguration = {
|
|
2113
|
-
maximumPercent: 200,
|
|
2114
|
-
minimumHealthyPercent: 100,
|
|
2115
|
-
strategy: 'BLUE_GREEN',
|
|
2116
|
-
bakeTimeInMinutes: 15,
|
|
2117
|
-
lifecycleHooks: [{
|
|
2118
|
-
hookTargetArn: 'arn:aws:lambda:region:account:function:pre-deployment-hook',
|
|
2119
|
-
roleArn: 'arn:aws:iam::account:role/deployment-hook-role',
|
|
2120
|
-
lifecycleStages: ['PRE_STOP', 'POST_START']
|
|
2121
|
-
}]
|
|
2122
|
-
};
|
|
2123
|
-
```
|
|
2124
|
-
|
|
2125
|
-
#### Service Connect Test Traffic Rules
|
|
2126
|
-
|
|
2127
|
-
Configure test traffic routing for Service Connect during blue/green deployments:
|
|
2080
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
2128
2081
|
|
|
2129
|
-
```ts
|
|
2130
2082
|
declare const cluster: ecs.Cluster;
|
|
2131
2083
|
declare const taskDefinition: ecs.TaskDefinition;
|
|
2084
|
+
declare const lambdaHook: lambda.Function;
|
|
2085
|
+
declare const blueTargetGroup: elbv2.ApplicationTargetGroup;
|
|
2086
|
+
declare const greenTargetGroup: elbv2.ApplicationTargetGroup;
|
|
2087
|
+
declare const prodListenerRule: elbv2.ApplicationListenerRule;
|
|
2132
2088
|
|
|
2133
2089
|
const service = new ecs.FargateService(this, 'Service', {
|
|
2134
2090
|
cluster,
|
|
2135
2091
|
taskDefinition,
|
|
2092
|
+
deploymentStrategy: ecs.DeploymentStrategy.BLUE_GREEN,
|
|
2136
2093
|
});
|
|
2137
2094
|
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
}
|
|
2154
|
-
}]
|
|
2155
|
-
}]
|
|
2156
|
-
};
|
|
2095
|
+
service.addLifecycleHook(new ecs.DeploymentLifecycleLambdaTarget(lambdaHook, 'PreScaleHook', {
|
|
2096
|
+
lifecycleStages: [ecs.DeploymentLifecycleStage.PRE_SCALE_UP],
|
|
2097
|
+
}));
|
|
2098
|
+
|
|
2099
|
+
const target = service.loadBalancerTarget({
|
|
2100
|
+
containerName: 'nginx',
|
|
2101
|
+
containerPort: 80,
|
|
2102
|
+
protocol: ecs.Protocol.TCP,
|
|
2103
|
+
alternateTarget: new ecs.AlternateTarget('AlternateTarget', {
|
|
2104
|
+
alternateTargetGroup: greenTargetGroup,
|
|
2105
|
+
productionListener: ecs.ListenerRuleConfiguration.applicationListenerRule(prodListenerRule),
|
|
2106
|
+
}),
|
|
2107
|
+
});
|
|
2108
|
+
|
|
2109
|
+
target.attachToApplicationTargetGroup(blueTargetGroup);
|
|
2157
2110
|
```
|
|
2158
2111
|
|
|
2159
2112
|
## Daemon Scheduling Strategy
|
|
@@ -3,30 +3,20 @@ import * as cdk from 'aws-cdk-lib';
|
|
|
3
3
|
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
4
4
|
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
5
5
|
|
|
6
|
-
const app = new cdk.App(
|
|
7
|
-
postCliContext: {
|
|
8
|
-
'@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
|
|
9
|
-
'@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy': false,
|
|
10
|
-
},
|
|
11
|
-
});
|
|
6
|
+
const app = new cdk.App();
|
|
12
7
|
const stack = new cdk.Stack(app, 'aws-ecs-integ-availability-zone-rebalancing');
|
|
13
8
|
|
|
14
9
|
const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2, restrictDefaultSecurityGroup: false });
|
|
15
10
|
|
|
16
|
-
const cluster = new ecs.Cluster(stack, '
|
|
17
|
-
|
|
18
|
-
cluster.addCapacity('DefaultAutoScalingGroup', {
|
|
19
|
-
instanceType: new ec2.InstanceType('t2.micro'),
|
|
20
|
-
});
|
|
11
|
+
const cluster = new ecs.Cluster(stack, 'Cluster', { vpc });
|
|
21
12
|
|
|
22
|
-
const taskDefinition = new ecs.
|
|
13
|
+
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef');
|
|
23
14
|
|
|
24
15
|
taskDefinition.addContainer('web', {
|
|
25
16
|
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
|
|
26
|
-
memoryLimitMiB: 256,
|
|
27
17
|
});
|
|
28
18
|
|
|
29
|
-
new ecs.
|
|
19
|
+
new ecs.FargateService(stack, 'FargateService', {
|
|
30
20
|
cluster,
|
|
31
21
|
taskDefinition,
|
|
32
22
|
availabilityZoneRebalancing: ecs.AvailabilityZoneRebalancing.ENABLED,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
2
2
|
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
|
|
3
|
-
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
4
3
|
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
5
4
|
import * as cdk from 'aws-cdk-lib';
|
|
6
5
|
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
@@ -89,45 +88,6 @@ const prodListenerRule = new elbv2.ApplicationListenerRule(stack, 'ALBProduction
|
|
|
89
88
|
]),
|
|
90
89
|
});
|
|
91
90
|
|
|
92
|
-
// Create granular IAM roles
|
|
93
|
-
const ecsTaskExecutionRole = new iam.Role(stack, 'EcsTaskExecutionRole', {
|
|
94
|
-
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
|
|
95
|
-
managedPolicies: [
|
|
96
|
-
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonECSTaskExecutionRolePolicy'),
|
|
97
|
-
],
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Create Blue/Green deployment service role
|
|
101
|
-
const ecsServiceRole = new iam.Role(stack, 'ServiceRole', {
|
|
102
|
-
assumedBy: new iam.CompositePrincipal(
|
|
103
|
-
new iam.ServicePrincipal('ecs.amazonaws.com'),
|
|
104
|
-
),
|
|
105
|
-
managedPolicies: [
|
|
106
|
-
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2ContainerServiceRole'),
|
|
107
|
-
],
|
|
108
|
-
inlinePolicies: {
|
|
109
|
-
LambdaInvokePolicy: new iam.PolicyDocument({
|
|
110
|
-
statements: [
|
|
111
|
-
new iam.PolicyStatement({
|
|
112
|
-
actions: ['lambda:InvokeFunction'],
|
|
113
|
-
resources: ['*'],
|
|
114
|
-
}),
|
|
115
|
-
],
|
|
116
|
-
}),
|
|
117
|
-
ELBPolicy: new iam.PolicyDocument({
|
|
118
|
-
statements: [
|
|
119
|
-
new iam.PolicyStatement({
|
|
120
|
-
actions: [
|
|
121
|
-
'elasticloadbalancing:ModifyRule',
|
|
122
|
-
'elasticloadbalancing:ModifyListener',
|
|
123
|
-
],
|
|
124
|
-
resources: [prodListenerRule.listenerRuleArn],
|
|
125
|
-
}),
|
|
126
|
-
],
|
|
127
|
-
}),
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
|
|
131
91
|
// Create Lambda hook
|
|
132
92
|
const lambdaHook = new lambda.Function(stack, 'LambdaHook', {
|
|
133
93
|
handler: 'index.handler',
|
|
@@ -138,13 +98,10 @@ const lambdaHook = new lambda.Function(stack, 'LambdaHook', {
|
|
|
138
98
|
};`),
|
|
139
99
|
});
|
|
140
100
|
|
|
141
|
-
lambdaHook.grantInvoke(ecsServiceRole);
|
|
142
|
-
|
|
143
101
|
// Create task definition
|
|
144
102
|
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef', {
|
|
145
103
|
memoryLimitMiB: 512,
|
|
146
104
|
cpu: 256,
|
|
147
|
-
executionRole: ecsTaskExecutionRole,
|
|
148
105
|
});
|
|
149
106
|
|
|
150
107
|
// Add container to task definition
|
|
@@ -163,39 +120,24 @@ const service = new ecs.FargateService(stack, 'Service', {
|
|
|
163
120
|
cluster,
|
|
164
121
|
taskDefinition,
|
|
165
122
|
securityGroups: [ecsSecurityGroup],
|
|
123
|
+
deploymentStrategy: ecs.DeploymentStrategy.BLUE_GREEN,
|
|
166
124
|
});
|
|
167
125
|
|
|
168
|
-
service.
|
|
126
|
+
service.addLifecycleHook(new ecs.DeploymentLifecycleLambdaTarget(lambdaHook, 'PreScaleUp', {
|
|
127
|
+
lifecycleStages: [ecs.DeploymentLifecycleStage.PRE_SCALE_UP],
|
|
128
|
+
}));
|
|
169
129
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
Enable: false,
|
|
179
|
-
Rollback: false,
|
|
180
|
-
},
|
|
181
|
-
MaximumPercent: 200,
|
|
182
|
-
MinimumHealthyPercent: 100,
|
|
183
|
-
Strategy: 'BLUE_GREEN',
|
|
184
|
-
BakeTimeInMinutes: 0,
|
|
185
|
-
LifecycleHooks: [{
|
|
186
|
-
HookTargetArn: lambdaHook.functionArn,
|
|
187
|
-
RoleArn: ecsServiceRole.roleArn,
|
|
188
|
-
LifecycleStages: ['POST_TEST_TRAFFIC_SHIFT'],
|
|
189
|
-
}],
|
|
130
|
+
const target = service.loadBalancerTarget({
|
|
131
|
+
containerName: 'nginx',
|
|
132
|
+
containerPort: 80,
|
|
133
|
+
protocol: ecs.Protocol.TCP,
|
|
134
|
+
alternateTarget: new ecs.AlternateTarget('LBAlternateOptions', {
|
|
135
|
+
alternateTargetGroup: greenTargetGroup,
|
|
136
|
+
productionListener: ecs.ListenerRuleConfiguration.applicationListenerRule(prodListenerRule),
|
|
137
|
+
}),
|
|
190
138
|
});
|
|
191
139
|
|
|
192
|
-
|
|
193
|
-
AdvancedConfiguration: {
|
|
194
|
-
AlternateTargetGroupArn: greenTargetGroup.targetGroupArn,
|
|
195
|
-
RoleArn: ecsServiceRole.roleArn,
|
|
196
|
-
ProductionListenerRule: prodListenerRule.listenerRuleArn,
|
|
197
|
-
},
|
|
198
|
-
});
|
|
140
|
+
target.attachToApplicationTargetGroup(blueTargetGroup);
|
|
199
141
|
|
|
200
142
|
// Create integration test
|
|
201
143
|
new integ.IntegTest(app, 'aws-ecs-blue-green', {
|
cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.enable-execute-command.ts
CHANGED
|
@@ -1,53 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
import * as autoscaling from 'aws-cdk-lib/aws-autoscaling';
|
|
3
|
-
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
4
1
|
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
2
|
+
import * as kms from 'aws-cdk-lib/aws-kms';
|
|
3
|
+
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
5
4
|
import * as cdk from 'aws-cdk-lib';
|
|
5
|
+
import { Duration } from 'aws-cdk-lib';
|
|
6
6
|
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
7
7
|
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
8
8
|
|
|
9
9
|
const app = new cdk.App({
|
|
10
10
|
postCliContext: {
|
|
11
|
-
'@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
|
|
12
11
|
'@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions': true,
|
|
13
|
-
'@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature': false,
|
|
14
|
-
'@aws-cdk/aws-ecs:disableEcsImdsBlocking': false,
|
|
15
|
-
'@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy': false,
|
|
16
12
|
},
|
|
17
13
|
});
|
|
18
14
|
const stack = new cdk.Stack(app, 'aws-ecs-integ-enable-execute-command');
|
|
19
15
|
|
|
20
|
-
const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2 });
|
|
21
|
-
|
|
22
|
-
const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef');
|
|
23
|
-
|
|
24
|
-
taskDefinition.addContainer('web', {
|
|
25
|
-
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
|
|
26
|
-
memoryReservationMiB: 256,
|
|
27
|
-
portMappings: [
|
|
28
|
-
{
|
|
29
|
-
containerPort: 80,
|
|
30
|
-
hostPort: 8080,
|
|
31
|
-
protocol: ecs.Protocol.TCP,
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
});
|
|
16
|
+
const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2, restrictDefaultSecurityGroup: false });
|
|
35
17
|
|
|
36
|
-
const
|
|
18
|
+
const kmsKey = new kms.Key(stack, 'KmsKey');
|
|
37
19
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
vpc,
|
|
41
|
-
instanceType: new ec2.InstanceType('t2.micro'),
|
|
42
|
-
machineImage: ecs.EcsOptimizedImage.amazonLinux2(),
|
|
43
|
-
}),
|
|
44
|
-
// This is to allow cdk destroy to work; otherwise deletion will hang bc ASG cannot be deleted
|
|
45
|
-
enableManagedTerminationProtection: false,
|
|
20
|
+
const execBucket = new s3.Bucket(stack, 'EcsExecBucket', {
|
|
21
|
+
encryptionKey: kmsKey,
|
|
46
22
|
});
|
|
47
23
|
|
|
48
|
-
const cluster = new ecs.Cluster(stack, '
|
|
24
|
+
const cluster = new ecs.Cluster(stack, 'FargateCluster', {
|
|
49
25
|
vpc,
|
|
50
26
|
executeCommandConfiguration: {
|
|
27
|
+
kmsKey,
|
|
51
28
|
logConfiguration: {
|
|
52
29
|
s3Bucket: execBucket,
|
|
53
30
|
s3EncryptionEnabled: true,
|
|
@@ -56,9 +33,19 @@ const cluster = new ecs.Cluster(stack, 'EC2CPCluster', {
|
|
|
56
33
|
logging: ecs.ExecuteCommandLogging.OVERRIDE,
|
|
57
34
|
},
|
|
58
35
|
});
|
|
59
|
-
cluster.addAsgCapacityProvider(cp);
|
|
60
36
|
|
|
61
|
-
new ecs.
|
|
37
|
+
const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef');
|
|
38
|
+
|
|
39
|
+
taskDefinition.addContainer('web', {
|
|
40
|
+
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
|
|
41
|
+
healthCheck: {
|
|
42
|
+
command: ['CMD-SHELL', 'curl localhost:8000'],
|
|
43
|
+
interval: Duration.seconds(60),
|
|
44
|
+
timeout: Duration.seconds(40),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
new ecs.FargateService(stack, 'FargateService', {
|
|
62
49
|
cluster,
|
|
63
50
|
taskDefinition,
|
|
64
51
|
enableExecuteCommand: true,
|
|
@@ -66,5 +53,12 @@ new ecs.Ec2Service(stack, 'EC2Service', {
|
|
|
66
53
|
|
|
67
54
|
new integ.IntegTest(app, 'enable-execute-command-test', {
|
|
68
55
|
testCases: [stack],
|
|
56
|
+
diffAssets: true,
|
|
57
|
+
cdkCommandOptions: {
|
|
58
|
+
deploy: {
|
|
59
|
+
args: {
|
|
60
|
+
rollback: true,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
69
64
|
});
|
|
70
|
-
app.synth();
|