konokenj.cdk-api-mcp-server 0.26.0__py3-none-any.whl → 0.27.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.

Potentially problematic release.


This version of konokenj.cdk-api-mcp-server might be problematic. Click here for more details.

Files changed (43) hide show
  1. cdk_api_mcp_server/__about__.py +1 -1
  2. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-amplify-alpha/README.md +14 -0
  3. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-bedrock-alpha/README.md +608 -0
  4. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigateway/integ.model-schema-additional-items.ts +72 -0
  5. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudfront/README.md +8 -0
  6. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudfront/integ.distribution-basic.ts +1 -1
  7. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codedeploy/integ.deployment-config.ts +15 -4
  8. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codedeploy/integ.deployment-group.ts +40 -218
  9. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codepipeline-actions/README.md +34 -0
  10. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codepipeline-actions/integ.pipeline-ec2-deploy-ssm-managed.ts +140 -0
  11. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codepipeline-actions/integ.pipeline-ec2-deploy.ts +140 -0
  12. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ec2/README.md +55 -1
  13. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ec2/integ.machine-image-cached.ts +53 -0
  14. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ec2/integ.volume-initialization-rate.ts +21 -0
  15. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/README.md +16 -0
  16. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.availability-zone-rebalancing.ts +4 -14
  17. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.enable-execute-command.ts +29 -35
  18. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.exec-command.ts +22 -16
  19. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.lb-awsvpc-nw.ts +16 -26
  20. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.pseudo-terminal.ts +8 -18
  21. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-eks/README.md +6 -0
  22. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-eks/integ.custom-addons.ts +48 -0
  23. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-logs/README.md +1 -0
  24. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-logs/integ.expose-metric-with-dimensions.ts +47 -0
  25. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-opensearchservice/integ.opensearch.gp3.ts +16 -1
  26. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-opensearchservice/integ.opensearch.https.ts +54 -0
  27. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/README.md +25 -2
  28. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.cluster-serverless-v2-autopause.ts +27 -0
  29. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.instance-from-cluster-snapshot.ts +23 -0
  30. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ssm/README.md +16 -0
  31. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions/README.md +21 -0
  32. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions/integ.map-jsonata-itemselector.ts +36 -0
  33. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke-jsonata.ts +80 -87
  34. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke.ts +69 -87
  35. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.start-job-run.ts +104 -102
  36. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/README.md +23 -0
  37. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary-dryrun-update.ts +32 -0
  38. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary.ts +2 -0
  39. {konokenj_cdk_api_mcp_server-0.26.0.dist-info → konokenj_cdk_api_mcp_server-0.27.0.dist-info}/METADATA +1 -1
  40. {konokenj_cdk_api_mcp_server-0.26.0.dist-info → konokenj_cdk_api_mcp_server-0.27.0.dist-info}/RECORD +43 -30
  41. {konokenj_cdk_api_mcp_server-0.26.0.dist-info → konokenj_cdk_api_mcp_server-0.27.0.dist-info}/WHEEL +0 -0
  42. {konokenj_cdk_api_mcp_server-0.26.0.dist-info → konokenj_cdk_api_mcp_server-0.27.0.dist-info}/entry_points.txt +0 -0
  43. {konokenj_cdk_api_mcp_server-0.26.0.dist-info → konokenj_cdk_api_mcp_server-0.27.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,72 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
3
+ import * as apigateway from 'aws-cdk-lib/aws-apigateway';
4
+
5
+ class TestStack extends cdk.Stack {
6
+ constructor(scope: cdk.App, id: string) {
7
+ super(scope, id);
8
+
9
+ const api = new apigateway.RestApi(this, 'model-schema-api', {
10
+ restApiName: 'Model Schema Test API',
11
+ });
12
+
13
+ // Create a minimal schema that uses additionalItems
14
+ const schema: apigateway.JsonSchema = {
15
+ type: apigateway.JsonSchemaType.OBJECT,
16
+ required: ['tags'],
17
+ properties: {
18
+ tags: {
19
+ type: apigateway.JsonSchemaType.ARRAY,
20
+ items: [
21
+ { type: apigateway.JsonSchemaType.STRING, enum: ['primary'] },
22
+ { type: apigateway.JsonSchemaType.STRING, enum: ['secondary'] },
23
+ ],
24
+ additionalItems: {
25
+ type: apigateway.JsonSchemaType.STRING,
26
+ pattern: '^[a-z0-9-]+$',
27
+ },
28
+ minItems: 1,
29
+ maxItems: 5,
30
+ },
31
+ },
32
+ };
33
+
34
+ // Create the model using our schema
35
+ const model = api.addModel('TagsModel', {
36
+ contentType: 'application/json',
37
+ modelName: 'Tags',
38
+ schema: schema,
39
+ });
40
+
41
+ // Add a validator that requires the request body to match our model
42
+ const validator = api.addRequestValidator('TagsValidator', {
43
+ requestValidatorName: 'TagsValidator',
44
+ validateRequestBody: true,
45
+ });
46
+
47
+ // Add a POST method that uses the model and validator
48
+ api.root.addMethod('POST', new apigateway.MockIntegration({
49
+ integrationResponses: [{
50
+ statusCode: '200',
51
+ }],
52
+ requestTemplates: {
53
+ 'application/json': '{ "statusCode": 200 }',
54
+ },
55
+ }), {
56
+ requestValidator: validator,
57
+ requestModels: {
58
+ 'application/json': model,
59
+ },
60
+ methodResponses: [{
61
+ statusCode: '200',
62
+ }],
63
+ });
64
+ }
65
+ }
66
+
67
+ const app = new cdk.App();
68
+ const stack = new TestStack(app, 'model-schema-additional-items-test');
69
+ new IntegTest(app, 'ModelSchemaAdditionalItemsTest', {
70
+ testCases: [stack],
71
+ });
72
+ app.synth();
@@ -1247,6 +1247,14 @@ new cloudfront.KeyGroup(this, 'MyKeyGroup', {
1247
1247
  });
1248
1248
  ```
1249
1249
 
1250
+ When using a CloudFront PublicKey, only the `comment` field can be updated after creation. Fields such as `encodedKey` and `publicKeyName` are immutable, as outlined in the [API Reference](https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_UpdatePublicKey.html). Attempting to modify these fields will result in an error:
1251
+ ```
1252
+ Resource handler returned message: "Invalid request provided: AWS::CloudFront::PublicKey"
1253
+ ```
1254
+
1255
+ To update the `encodedKey`, you must change the logical ID of the public key resource in your template. This causes CloudFormation to create a new `cloudfront.PublicKey` resource and delete the old one during the next deployment.
1256
+
1257
+
1250
1258
  See:
1251
1259
 
1252
1260
  - <https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html>
@@ -18,7 +18,7 @@ const role2 = new iam.Role(stack, 'Role2', {
18
18
  assumedBy: new iam.AccountRootPrincipal(),
19
19
  });
20
20
  distribution.grantCreateInvalidation(role1);
21
- distribution.grant(role2, 'cloudfront:ListInvalidations');
21
+ distribution.grant(role2, 'cloudfront:ListInvalidations', 'cloudfront:ListDistributions');
22
22
 
23
23
  new IntegTest(stack, 'distribution-basic-test', {
24
24
  testCases: [stack],
@@ -2,17 +2,28 @@ import * as cdk from 'aws-cdk-lib';
2
2
  import * as integ from '@aws-cdk/integ-tests-alpha';
3
3
  import * as codedeploy from 'aws-cdk-lib/aws-codedeploy';
4
4
 
5
- const app = new cdk.App();
6
- const stack = new cdk.Stack(app, 'aws-cdk-codedeploy-ecs-config');
5
+ const app = new cdk.App({
6
+ postCliContext: {
7
+ '@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
8
+ },
9
+ });
10
+ const stack = new cdk.Stack(app, 'aws-cdk-codedeploy-lambda-config');
7
11
 
8
- new codedeploy.EcsDeploymentConfig(stack, 'LinearConfig', {
12
+ new codedeploy.LambdaDeploymentConfig(stack, 'LinearConfig', {
9
13
  trafficRouting: codedeploy.TrafficRouting.timeBasedLinear({
10
14
  interval: cdk.Duration.minutes(1),
11
15
  percentage: 5,
12
16
  }),
13
17
  });
14
18
 
15
- new integ.IntegTest(app, 'EcsDeploymentConfigTest', {
19
+ new codedeploy.CustomLambdaDeploymentConfig(stack, 'CustomConfig', {
20
+ interval: cdk.Duration.minutes(1),
21
+ percentage: 5,
22
+ type: cdk.aws_codedeploy.CustomLambdaDeploymentConfigType.LINEAR,
23
+ deploymentConfigName: 'hello',
24
+ });
25
+
26
+ new integ.IntegTest(app, 'LambdaDeploymentConfigTest', {
16
27
  testCases: [stack],
17
28
  });
18
29
 
@@ -1,240 +1,62 @@
1
+ import * as path from 'path';
1
2
  import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
2
- import * as ec2 from 'aws-cdk-lib/aws-ec2';
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
- * Follow these instructions to manually test running a CodeDeploy deployment with the resources provisioned in this stack:
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
- // A second task definition for testing a CodeDeploy deployment of the ECS service to a new task definition
96
- const taskDefinition2 = new ecs.FargateTaskDefinition(stack, 'TaskDef2');
97
- taskDefinition2.addContainer('Container', {
98
- image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'),
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
- service.node.addDependency(taskDefinition2);
102
-
103
- // Load balancer
104
- const loadBalancer = new elbv2.ApplicationLoadBalancer(stack, 'ServiceLB', {
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
- // Listeners
110
- const prodListener = loadBalancer.addListener('ProdListener', {
111
- port: 80, // port for production traffic
112
- protocol: elbv2.ApplicationProtocol.HTTP,
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 testListener = loadBalancer.addListener('TestListener', {
115
- port: 9002, // port for testing
116
- protocol: elbv2.ApplicationProtocol.HTTP,
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
- // Target groups
120
- const blueTG = prodListener.addTargets('BlueTG', {
121
- port: 80,
122
- protocol: elbv2.ApplicationProtocol.HTTP,
123
- targets: [
124
- service.loadBalancerTarget({
125
- containerName: 'Container',
126
- containerPort: 80,
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
- deregistrationDelay: cdk.Duration.seconds(30),
130
- healthCheck: {
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 greenTG = new elbv2.ApplicationTargetGroup(stack, 'GreenTG', {
140
- vpc,
141
- port: 80,
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
- prodListener.node.addDependency(greenTG);
159
- testListener.node.addDependency(blueTG);
160
- service.node.addDependency(testListener);
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();
@@ -927,6 +927,40 @@ Here's an example:
927
927
 
928
928
  [example ECS pipeline for an application in a separate source code repository](test/integ.pipeline-ecs-separate-source.lit.ts)
929
929
 
930
+ ### Amazon EC2
931
+
932
+ To deploy application code to Amazon EC2 Linux instances or Linux SSM-managed nodes:
933
+
934
+ > **Note**
935
+ > This action is only supported for V2 type pipelines.
936
+
937
+ ```ts
938
+ const sourceOutput = new codepipeline.Artifact();
939
+
940
+ const pipeline = new codepipeline.Pipeline(this, 'MyPipeline', {
941
+ pipelineType: codepipeline.PipelineType.V2,
942
+ });
943
+ const deployAction = new codepipeline_actions.Ec2DeployAction({
944
+ actionName: 'Ec2Deploy',
945
+ input: sourceOutput,
946
+ instanceType: codepipeline_actions.Ec2InstanceType.EC2,
947
+ instanceTagKey: 'Name',
948
+ instanceTagValue: 'MyInstance',
949
+ deploySpecifications: codepipeline_actions.Ec2DeploySpecifications.inline({
950
+ targetDirectory: '/home/ec2-user/deploy',
951
+ preScript: 'scripts/pre-deploy.sh',
952
+ postScript: 'scripts/post-deploy.sh',
953
+ }),
954
+ });
955
+ const deployStage = pipeline.addStage({
956
+ stageName: 'Deploy',
957
+ actions: [deployAction],
958
+ });
959
+ ```
960
+
961
+ To learn more about using the EC2 deploy action in your pipeline, visit [tutorial](https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials-ec2-deploy.html) and [documentation](https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-EC2Deploy.html).
962
+
963
+
930
964
  ### AWS S3 Deployment
931
965
 
932
966
  To use an S3 Bucket as a deployment target in CodePipeline:
@@ -0,0 +1,140 @@
1
+ import * as codepipeline from 'aws-cdk-lib/aws-codepipeline';
2
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
3
+ import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
4
+ import * as targets from 'aws-cdk-lib/aws-elasticloadbalancingv2-targets';
5
+ import * as s3 from 'aws-cdk-lib/aws-s3';
6
+ import * as s3deployment from 'aws-cdk-lib/aws-s3-deployment';
7
+ import * as cdk from 'aws-cdk-lib';
8
+ import * as cpactions from 'aws-cdk-lib/aws-codepipeline-actions';
9
+ import { ExpectedResult, IntegTest } from '@aws-cdk/integ-tests-alpha';
10
+ import * as path from 'path';
11
+
12
+ const app = new cdk.App();
13
+
14
+ const stack = new cdk.Stack(app, 'aws-cdk-codepipeline-ec2-deploy-ssm-managed-node');
15
+
16
+ const vpc = new ec2.Vpc(stack, 'VPC', {
17
+ maxAzs: 2,
18
+ natGateways: 0,
19
+ restrictDefaultSecurityGroup: false,
20
+ });
21
+
22
+ const instances = Object.fromEntries(Object.entries({ NoLB: [0, 1], LB: [0, 1] }).map(([tagValue, indexs]) => {
23
+ const innerInstances = indexs.map((index) => {
24
+ const userData = ec2.UserData.forLinux();
25
+ userData.addCommands('dnf install httpd -y', 'mkdir -p /var/www/html', 'touch /var/www/html/index.html', 'systemctl start httpd');
26
+ const instance = new ec2.Instance(stack, `Instance-${tagValue}-${index}`, {
27
+ vpc,
28
+ vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
29
+ availabilityZone: vpc.publicSubnets[index].availabilityZone,
30
+ machineImage: ec2.MachineImage.latestAmazonLinux2023({ cpuType: ec2.AmazonLinuxCpuType.ARM_64 }),
31
+ instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE4_GRAVITON, ec2.InstanceSize.MICRO),
32
+ ssmSessionPermissions: true,
33
+ userData,
34
+ });
35
+ instance.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
36
+ instance.connections.allowFromAnyIpv4(ec2.Port.HTTP);
37
+ cdk.Tags.of(instance).add('EC2-Target', tagValue);
38
+ return instance;
39
+ });
40
+ return [tagValue, innerInstances];
41
+ }));
42
+
43
+ const alb = new elbv2.ApplicationLoadBalancer(stack, 'ALB', { vpc, internetFacing: true });
44
+ const albTg = new elbv2.ApplicationTargetGroup(stack, 'ALB-TG', {
45
+ vpc,
46
+ protocol: elbv2.ApplicationProtocol.HTTP,
47
+ deregistrationDelay: cdk.Duration.seconds(0),
48
+ });
49
+ alb.addListener('HTTP', {
50
+ protocol: elbv2.ApplicationProtocol.HTTP,
51
+ defaultTargetGroups: [albTg],
52
+ });
53
+ alb.connections.allowToAnyIpv4(ec2.Port.HTTP);
54
+ albTg.addTarget(...instances.LB.map((instance) => new targets.InstanceTarget(instance)));
55
+
56
+ const bucket = new s3.Bucket(stack, 'ArtifactBucket', {
57
+ versioned: true,
58
+ autoDeleteObjects: true,
59
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
60
+ });
61
+ instances.LB.forEach((instance) => bucket.grantRead(instance));
62
+ instances.NoLB.forEach((instance) => bucket.grantRead(instance));
63
+ const deployment = new s3deployment.BucketDeployment(stack, 'ArtifactDeployment', {
64
+ destinationBucket: bucket,
65
+ sources: [s3deployment.Source.asset(path.join(__dirname, 'ec2-deploy-artifacts', 'inline'))],
66
+ extract: false,
67
+ });
68
+
69
+ const sourceArtifact = new codepipeline.Artifact('SourceArtifact');
70
+ const sourceAction = new cpactions.S3SourceAction({
71
+ actionName: 'Source',
72
+ output: sourceArtifact,
73
+ bucket,
74
+ bucketKey: cdk.Fn.select(0, deployment.objectKeys),
75
+ });
76
+
77
+ const pipeline = new codepipeline.Pipeline(stack, 'MyPipeline', {
78
+ pipelineType: codepipeline.PipelineType.V2,
79
+ artifactBucket: bucket,
80
+ stages: [
81
+ {
82
+ stageName: 'Source',
83
+ actions: [sourceAction],
84
+ },
85
+ {
86
+ stageName: 'Deploy',
87
+ actions: [
88
+ new cpactions.Ec2DeployAction({
89
+ actionName: 'EC2-NoLB',
90
+ input: sourceArtifact,
91
+ instanceType: cpactions.Ec2InstanceType.SSM_MANAGED_NODE,
92
+ instanceTagKey: 'EC2-Target',
93
+ instanceTagValue: 'NoLB',
94
+ deploySpecifications: cpactions.Ec2DeploySpecifications.inline({
95
+ targetDirectory: '/var/www/html/NoLB',
96
+ preScript: 'scripts/pre-deploy.sh',
97
+ postScript: 'scripts/post-deploy.sh',
98
+ }),
99
+ maxBatch: cpactions.Ec2MaxInstances.targets(2),
100
+ }),
101
+ new cpactions.Ec2DeployAction({
102
+ actionName: 'EC2-LB',
103
+ input: sourceArtifact,
104
+ instanceType: cpactions.Ec2InstanceType.SSM_MANAGED_NODE,
105
+ instanceTagKey: 'EC2-Target',
106
+ instanceTagValue: 'LB',
107
+ deploySpecifications: cpactions.Ec2DeploySpecifications.inline({
108
+ targetDirectory: '/var/www/html/LB',
109
+ preScript: 'scripts/pre-deploy.sh',
110
+ postScript: 'scripts/post-deploy.sh',
111
+ }),
112
+ targetGroups: [albTg],
113
+ maxBatch: cpactions.Ec2MaxInstances.targets(1),
114
+ }),
115
+ ],
116
+ },
117
+ ],
118
+ });
119
+
120
+ const integ = new IntegTest(app, 'ec2-deploy-action-ssm-managed-node-integ', {
121
+ testCases: [stack],
122
+ });
123
+
124
+ const pipelineExecutionId = integ.assertions
125
+ .awsApiCall('codepipeline', 'StartPipelineExecution', { name: pipeline.pipelineName })
126
+ .getAttString('pipelineExecutionId');
127
+ const waitPipelieneSuccess = integ.assertions
128
+ .awsApiCall('codepipeline', 'GetPipelineExecution', { pipelineName: pipeline.pipelineName, pipelineExecutionId })
129
+ .waitForAssertions({ interval: cdk.Duration.seconds(30) })
130
+ .expect(ExpectedResult.objectLike({ pipelineExecution: { status: 'Succeeded' } }));
131
+ waitPipelieneSuccess.next(
132
+ integ.assertions
133
+ .httpApiCall(`http://${alb.loadBalancerDnsName}/LB/index.html`)
134
+ .expect(ExpectedResult.objectLike({ status: 200 })),
135
+ );
136
+ instances.NoLB.forEach((instance) => waitPipelieneSuccess.next(
137
+ integ.assertions
138
+ .httpApiCall(`http://${instance.instancePublicDnsName}/NoLB/index.html`)
139
+ .expect(ExpectedResult.objectLike({ status: 200 })),
140
+ ));