konokenj.cdk-api-mcp-server 0.31.0__py3-none-any.whl → 0.33.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 (40) hide show
  1. cdk_api_mcp_server/__about__.py +1 -1
  2. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api-dualstack.ts +3 -4
  3. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api.ts +2 -4
  4. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.stage.ts +7 -20
  5. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-authorizers/integ.iam.ts +34 -38
  6. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.sqs.ts +58 -71
  7. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudfront/README.md +292 -1
  8. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/README.md +71 -0
  9. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/integ.alarm-and-dashboard.ts +12 -0
  10. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/integ.dashboard-with-metric-id-and-visible.ts +70 -0
  11. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codebuild/README.md +67 -3
  12. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codebuild/integ.project-s3-cache.ts +71 -0
  13. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecr-assets/integ.assets-docker.ts +6 -0
  14. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.availability-zone-rebalancing.ts +14 -4
  15. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.enable-execute-command.ts +35 -29
  16. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.exec-command.ts +16 -22
  17. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.lb-awsvpc-nw.ts +26 -16
  18. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.pseudo-terminal.ts +18 -8
  19. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events/integ.api-destination.ts +42 -0
  20. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events-targets/README.md +7 -2
  21. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-iam/integ.custom-permissions-boundary-aspect.ts +50 -0
  22. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/README.md +3 -0
  23. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/integ.s3-bucket.lit.ts +1 -0
  24. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.lambda-policy-with-token-resolution.ts +46 -0
  25. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/README.md +19 -0
  26. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.cluster-lookup.ts +100 -0
  27. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-route53-targets/integ.elastic-beanstalk-hostedzoneid.ts +1 -1
  28. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke-jsonata.ts +87 -80
  29. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke.ts +87 -69
  30. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.start-job-run.ts +96 -43
  31. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/README.md +40 -0
  32. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary-resources-to-replicate-tags.ts +36 -0
  33. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary-retry.ts +32 -0
  34. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +29 -0
  35. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/pipelines/integ.pipeline-with-customsynthesizer.ts +105 -0
  36. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/METADATA +2 -2
  37. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/RECORD +40 -31
  38. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/WHEEL +0 -0
  39. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/entry_points.txt +0 -0
  40. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,101 +1,119 @@
1
- import * as path from 'path';
2
- import { IntegTest, ExpectedResult } from '@aws-cdk/integ-tests-alpha';
3
- import * as cdk from 'aws-cdk-lib';
4
- import * as apigateway from 'aws-cdk-lib/aws-apigateway';
5
- import * as events from 'aws-cdk-lib/aws-events';
1
+ import { Code, Function } from 'aws-cdk-lib/aws-lambda';
6
2
  import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
7
- import * as lambda from 'aws-cdk-lib/aws-lambda-nodejs';
8
- import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
9
- import { password, username } from './my-lambda-handler';
3
+ import * as cdk from 'aws-cdk-lib';
4
+ import { LambdaInvoke } from 'aws-cdk-lib/aws-stepfunctions-tasks';
5
+ import { IntegTest, ExpectedResult } from '@aws-cdk/integ-tests-alpha';
6
+ import { STANDARD_NODEJS_RUNTIME } from '../../../config';
10
7
 
11
8
  /*
12
- * Creates an API Gateway instance with a GET method and mock integration,
13
- * secured with basic auth. It then creates a matching Connection and uses it
14
- * in a state machine with a task state to invoke the endpoint.
9
+ * Creates a state machine with a task state to invoke a Lambda function
10
+ * The state machine creates a couple of Lambdas that pass results forward
11
+ * and into a Choice state that validates the output.
12
+ *
13
+ * Stack verification steps:
14
+ * The generated State Machine can be executed from the CLI (or Step Functions console)
15
+ * and runs with an execution status of `Succeeded`.
15
16
  *
16
- * Stack verification steps :
17
- * * aws stepfunctions start-execution --state-machine-arn <deployed state machine arn> : should return execution arn
18
- * * aws stepfunctions describe-execution --execution-arn <execution-arn generated before> : should return status as SUCCEEDED
17
+ * -- aws stepfunctions start-execution --state-machine-arn <state-machine-arn-from-output> provides execution arn
18
+ * -- aws stepfunctions describe-execution --execution-arn <state-machine-arn-from-output> returns a status of `Succeeded`
19
19
  */
20
20
  const app = new cdk.App({
21
21
  postCliContext: {
22
22
  '@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
23
23
  },
24
24
  });
25
- const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-http-invoke-integ');
25
+ const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-lambda-invoke-integ');
26
26
 
27
- const authorizerHandler = new lambda.NodejsFunction(stack, 'AuthorizerHandler', {
28
- entry: path.resolve(__dirname, 'my-lambda-handler', 'index.ts'),
29
- handler: 'handler',
27
+ const submitJobLambda = new Function(stack, 'submitJobLambda', {
28
+ code: Code.fromInline(`exports.handler = async (event, context) => {
29
+ return {
30
+ statusCode: '200',
31
+ body: 'hello, world!',
32
+ ...event,
33
+ };
34
+ };`),
35
+ runtime: STANDARD_NODEJS_RUNTIME,
36
+ handler: 'index.handler',
30
37
  });
31
38
 
32
- const authorizer = new apigateway.TokenAuthorizer(stack, 'Authorizer', {
33
- handler: authorizerHandler,
34
- identitySource: 'method.request.header.Authorization',
35
- resultsCacheTtl: cdk.Duration.seconds(0),
39
+ const submitJob = new LambdaInvoke(stack, 'Invoke Handler', {
40
+ lambdaFunction: submitJobLambda,
41
+ payload: sfn.TaskInput.fromObject({
42
+ execId: sfn.JsonPath.executionId,
43
+ execInput: sfn.JsonPath.executionInput,
44
+ execName: sfn.JsonPath.executionName,
45
+ execRoleArn: sfn.JsonPath.executionRoleArn,
46
+ execStartTime: sfn.JsonPath.executionStartTime,
47
+ stateEnteredTime: sfn.JsonPath.stateEnteredTime,
48
+ stateName: sfn.JsonPath.stateName,
49
+ stateRetryCount: sfn.JsonPath.stateRetryCount,
50
+ stateMachineId: sfn.JsonPath.stateMachineId,
51
+ stateMachineName: sfn.JsonPath.stateMachineName,
52
+ }),
53
+ outputPath: '$.Payload',
36
54
  });
37
55
 
38
- const api = new apigateway.RestApi(stack, 'IntegRestApi');
56
+ const checkJobStateLambda = new Function(stack, 'checkJobStateLambda', {
57
+ code: Code.fromInline(`exports.handler = async function(event, context) {
58
+ const expectedFields = [
59
+ 'execId', 'execInput', 'execName', 'execRoleArn',
60
+ 'execStartTime', 'stateEnteredTime', 'stateName',
61
+ 'stateRetryCount', 'stateMachineId', 'stateMachineName',
62
+ ];
63
+ const fieldsAreSet = expectedFields.every(field => event[field] !== undefined);
64
+ return {
65
+ status: event.statusCode === '200' && fieldsAreSet ? 'SUCCEEDED' : 'FAILED'
66
+ };
67
+ };`),
68
+ runtime: STANDARD_NODEJS_RUNTIME,
69
+ handler: 'index.handler',
70
+ });
39
71
 
40
- api.root.addResource('test').addMethod(
41
- 'GET',
42
- new apigateway.MockIntegration({
43
- integrationResponses: [
44
- {
45
- statusCode: '200',
46
- responseTemplates: {
47
- 'application/json': JSON.stringify({ message: 'Hello, tester!' }),
48
- },
49
- },
50
- ],
51
- passthroughBehavior: apigateway.PassthroughBehavior.NEVER,
52
- requestTemplates: {
53
- 'application/json': '{ "statusCode": 200 }',
54
- },
55
- }),
56
- {
57
- authorizer,
58
- methodResponses: [
59
- {
60
- statusCode: '200',
61
- },
62
- ],
72
+ const checkJobState = new LambdaInvoke(stack, 'Check the job state', {
73
+ lambdaFunction: checkJobStateLambda,
74
+ resultSelector: {
75
+ status: sfn.JsonPath.stringAt('$.Payload.status'),
63
76
  },
64
- );
65
-
66
- const connection = new events.Connection(stack, 'Connection', {
67
- authorization: events.Authorization.basic(username, cdk.SecretValue.unsafePlainText(password)),
68
77
  });
69
78
 
70
- const httpInvokeTask = new tasks.HttpInvoke(stack, 'Invoke HTTP Endpoint', {
71
- apiRoot: api.urlForPath('/'),
72
- apiEndpoint: sfn.TaskInput.fromText('/test'),
73
- connection,
74
- method: sfn.TaskInput.fromText('GET'),
79
+ const isComplete = new sfn.Choice(stack, 'Job Complete?');
80
+ const jobFailed = new sfn.Fail(stack, 'Job Failed', {
81
+ cause: 'Job Failed',
82
+ error: 'Received a status that was not 200',
75
83
  });
84
+ const finalStatus = new sfn.Pass(stack, 'Final step');
85
+
86
+ const chain = sfn.Chain.start(submitJob)
87
+ .next(checkJobState)
88
+ .next(
89
+ isComplete
90
+ .when(sfn.Condition.stringEquals('$.status', 'FAILED'), jobFailed)
91
+ .when(sfn.Condition.stringEquals('$.status', 'SUCCEEDED'), finalStatus),
92
+ );
76
93
 
77
94
  const sm = new sfn.StateMachine(stack, 'StateMachine', {
78
- definition: httpInvokeTask,
95
+ definition: chain,
79
96
  timeout: cdk.Duration.seconds(30),
80
97
  });
81
98
 
82
- const testCase = new IntegTest(app, 'HttpInvokeTest', {
83
- testCases: [stack],
99
+ new cdk.CfnOutput(stack, 'stateMachineArn', {
100
+ value: sm.stateMachineArn,
84
101
  });
85
102
 
86
- // Start an execution
87
- const start = testCase.assertions.awsApiCall('StepFunctions', 'startExecution', {
88
- stateMachineArn: sm.stateMachineArn,
103
+ const integ = new IntegTest(app, 'IntegTest', {
104
+ testCases: [stack],
89
105
  });
90
-
91
- // describe the results of the execution
92
- const describe = testCase.assertions.awsApiCall('StepFunctions', 'describeExecution', {
93
- executionArn: start.getAttString('executionArn'),
106
+ const res = integ.assertions.awsApiCall('StepFunctions', 'startExecution', {
107
+ stateMachineArn: sm.stateMachineArn,
94
108
  });
95
-
96
- // assert the results
97
- describe.expect(ExpectedResult.objectLike({
109
+ const executionArn = res.getAttString('executionArn');
110
+ integ.assertions.awsApiCall('StepFunctions', 'describeExecution', {
111
+ executionArn,
112
+ }).expect(ExpectedResult.objectLike({
98
113
  status: 'SUCCEEDED',
99
- }));
114
+ })).waitForAssertions({
115
+ totalTimeout: cdk.Duration.seconds(10),
116
+ interval: cdk.Duration.seconds(3),
117
+ });
100
118
 
101
119
  app.synth();
@@ -1,69 +1,122 @@
1
- import * as path from 'path';
2
- import * as glue from 'aws-cdk-lib/aws-glue';
1
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
2
+ import * as eks from 'aws-cdk-lib/aws-eks';
3
+ import { AwsAuthMapping } from 'aws-cdk-lib/aws-eks';
3
4
  import * as iam from 'aws-cdk-lib/aws-iam';
4
- import * as assets from 'aws-cdk-lib/aws-s3-assets';
5
5
  import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
6
6
  import * as cdk from 'aws-cdk-lib';
7
- import { GlueStartJobRun } from 'aws-cdk-lib/aws-stepfunctions-tasks';
8
- import { IntegTest } from '@aws-cdk/integ-tests-alpha';
7
+ import { Aws } from 'aws-cdk-lib';
8
+ import * as integ from '@aws-cdk/integ-tests-alpha';
9
+ import { KubectlV31Layer } from '@aws-cdk/lambda-layer-kubectl-v31';
10
+ import { EmrContainersStartJobRun, ReleaseLabel, VirtualClusterInput } from 'aws-cdk-lib/aws-stepfunctions-tasks';
11
+ import { EC2_RESTRICT_DEFAULT_SECURITY_GROUP } from 'aws-cdk-lib/cx-api';
9
12
 
10
- /*
13
+ /**
11
14
  * Stack verification steps:
12
- * * aws stepfunctions start-execution --state-machine-arn <deployed state machine arn>
13
- * * aws stepfunctions describe-execution --execution-arn <execution arn created above>
14
- * The "describe-execution" call should eventually return status "SUCCEEDED".
15
- * NOTE: It will take up to 15 minutes for the step function to complete due to the cold start time
16
- * for AWS Glue, which as of 02/2020, is around 10-15 minutes.
15
+ * Everything in the link below must be setup before running the state machine.
16
+ * @see https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/setting-up-enable-IAM.html
17
+ * aws stepfunctions start-execution --state-machine-arn <deployed state machine arn> : should return execution arn
18
+ * aws stepfunctions describe-execution --execution-arn <exection-arn generated before> : should return status as SUCCEEDED
17
19
  */
18
20
 
19
- const app = new cdk.App();
20
- const stack = new cdk.Stack(app, 'aws-stepfunctions-integ');
21
+ const app = new cdk.App({
22
+ postCliContext: {
23
+ '@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
24
+ '@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy': false,
25
+ },
26
+ });
27
+ const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-emr-containers-start-job-run');
28
+ stack.node.setContext(EC2_RESTRICT_DEFAULT_SECURITY_GROUP, false);
29
+
30
+ const eksCluster = new eks.Cluster(stack, 'integration-test-eks-cluster', {
31
+ version: eks.KubernetesVersion.V1_30,
32
+ defaultCapacity: 3,
33
+ defaultCapacityInstance: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE),
34
+ kubectlLayer: new KubectlV31Layer(stack, 'KubectlLayer'),
35
+ });
21
36
 
22
- const codeAsset = new assets.Asset(stack, 'Glue Job Script', {
23
- path: path.join(__dirname, 'my-glue-script/job.py'),
37
+ const virtualCluster = new cdk.CfnResource(stack, 'Virtual Cluster', {
38
+ type: 'AWS::EMRContainers::VirtualCluster',
39
+ properties: {
40
+ ContainerProvider: {
41
+ Id: eksCluster.clusterName,
42
+ Info: {
43
+ EksInfo: {
44
+ Namespace: 'default',
45
+ },
46
+ },
47
+ Type: 'EKS',
48
+ },
49
+ Name: 'Virtual-Cluster-Name',
50
+ },
24
51
  });
25
52
 
26
- const jobRole = new iam.Role(stack, 'Glue Job Role', {
27
- assumedBy: new iam.ServicePrincipal('glue'),
28
- managedPolicies: [
29
- iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole'),
53
+ const emrRole = eksCluster.addManifest('emrRole', {
54
+ apiVersion: 'rbac.authorization.k8s.io/v1',
55
+ kind: 'Role',
56
+ metadata: { name: 'emr-containers', namespace: 'default' },
57
+ rules: [
58
+ { apiGroups: [''], resources: ['namespaces'], verbs: ['get'] },
59
+ { apiGroups: [''], resources: ['serviceaccounts', 'services', 'configmaps', 'events', 'pods', 'pods/log'], verbs: ['get', 'list', 'watch', 'describe', 'create', 'edit', 'delete', 'deletecollection', 'annotate', 'patch', 'label'] },
60
+ { apiGroups: [''], resources: ['secrets'], verbs: ['create', 'patch', 'delete', 'watch'] },
61
+ { apiGroups: ['apps'], resources: ['statefulsets', 'deployments'], verbs: ['get', 'list', 'watch', 'describe', 'create', 'edit', 'delete', 'annotate', 'patch', 'label'] },
62
+ { apiGroups: ['batch'], resources: ['jobs'], verbs: ['get', 'list', 'watch', 'describe', 'create', 'edit', 'delete', 'annotate', 'patch', 'label'] },
63
+ { apiGroups: ['extensions'], resources: ['ingresses'], verbs: ['get', 'list', 'watch', 'describe', 'create', 'edit', 'delete', 'annotate', 'patch', 'label'] },
64
+ { apiGroups: ['rbac.authorization.k8s.io'], resources: ['roles', 'rolebindings'], verbs: ['get', 'list', 'watch', 'describe', 'create', 'edit', 'delete', 'deletecollection', 'annotate', 'patch', 'label'] },
30
65
  ],
31
66
  });
32
- codeAsset.grantRead(jobRole);
33
67
 
34
- const job = new glue.CfnJob(stack, 'Glue Job', {
35
- name: 'My Glue Job',
36
- glueVersion: '1.0',
37
- command: {
38
- name: 'glueetl',
39
- pythonVersion: '3',
40
- scriptLocation: `s3://${codeAsset.s3BucketName}/${codeAsset.s3ObjectKey}`,
41
- },
42
- role: jobRole.roleArn,
68
+ const emrRoleBind = eksCluster.addManifest('emrRoleBind', {
69
+ apiVersion: 'rbac.authorization.k8s.io/v1',
70
+ kind: 'RoleBinding',
71
+ metadata: { name: 'emr-containers', namespace: 'default' },
72
+ subjects: [{ kind: 'User', name: 'emr-containers', apiGroup: 'rbac.authorization.k8s.io' }],
73
+ roleRef: { kind: 'Role', name: 'emr-containers', apiGroup: 'rbac.authorization.k8s.io' },
43
74
  });
44
75
 
45
- const jobTask = new GlueStartJobRun(stack, 'Glue Job Task', {
46
- glueJobName: job.name!,
47
- integrationPattern: sfn.IntegrationPattern.RUN_JOB,
48
- arguments: sfn.TaskInput.fromObject({
49
- '--enable-metrics': 'true',
50
- }),
76
+ emrRoleBind.node.addDependency(emrRole);
77
+
78
+ const emrServiceRole = iam.Role.fromRoleArn(stack, 'emrServiceRole', 'arn:aws:iam::'+Aws.ACCOUNT_ID+':role/AWSServiceRoleForAmazonEMRContainers');
79
+ const authMapping: AwsAuthMapping = { groups: [], username: 'emr-containers' };
80
+ eksCluster.awsAuth.addRoleMapping(emrServiceRole, authMapping);
81
+
82
+ virtualCluster.node.addDependency(emrRoleBind);
83
+ virtualCluster.node.addDependency(eksCluster.awsAuth);
84
+
85
+ const startJobRunJob = new EmrContainersStartJobRun(stack, 'Start a Job Run', {
86
+ virtualCluster: VirtualClusterInput.fromVirtualClusterId(virtualCluster.getAtt('Id').toString()),
87
+ releaseLabel: ReleaseLabel.EMR_6_2_0,
88
+ jobName: 'EMR-Containers-Job',
89
+ jobDriver: {
90
+ sparkSubmitJobDriver: {
91
+ entryPoint: sfn.TaskInput.fromText('local:///usr/lib/spark/examples/src/main/python/pi.py'),
92
+ entryPointArguments: sfn.TaskInput.fromObject(['2']),
93
+ sparkSubmitParameters: '--conf spark.driver.memory=512M --conf spark.kubernetes.driver.request.cores=0.2 --conf spark.kubernetes.executor.request.cores=0.2 --conf spark.sql.shuffle.partitions=60 --conf spark.dynamicAllocation.enabled=false',
94
+ },
95
+ },
51
96
  });
52
97
 
53
- const startTask = new sfn.Pass(stack, 'Start Task');
54
- const endTask = new sfn.Pass(stack, 'End Task');
98
+ const chain = sfn.Chain.start(startJobRunJob);
55
99
 
56
- const stateMachine = new sfn.StateMachine(stack, 'State Machine', {
57
- definition: sfn.Chain.start(startTask).next(jobTask).next(endTask),
100
+ const sm = new sfn.StateMachine(stack, 'StateMachine', {
101
+ definition: chain,
102
+ timeout: cdk.Duration.seconds(1000),
58
103
  });
59
104
 
60
- new cdk.CfnOutput(stack, 'State Machine ARN Output', {
61
- value: stateMachine.stateMachineArn,
105
+ new cdk.CfnOutput(stack, 'stateMachineArn', {
106
+ value: sm.stateMachineArn,
62
107
  });
63
108
 
64
- new IntegTest(app, 'AwsSfnIntegTest', {
109
+ new integ.IntegTest(app, 'aws-stepfunctions-tasks-emr-containers-start-job-run-integ', {
65
110
  testCases: [stack],
66
- diffAssets: true,
111
+ // Test includes assets that are updated weekly. If not disabled, the upgrade PR will fail.
112
+ diffAssets: false,
113
+ cdkCommandOptions: {
114
+ deploy: {
115
+ args: {
116
+ rollback: true,
117
+ },
118
+ },
119
+ },
67
120
  });
68
121
 
69
122
  app.synth();
@@ -87,6 +87,28 @@ const schedule = synthetics.Schedule.cron({
87
87
 
88
88
  If you want the canary to run just once upon deployment, you can use `Schedule.once()`.
89
89
 
90
+ ### Automatic Retries
91
+
92
+ You can configure the canary to automatically retry failed runs by using the `maxRetries` property.
93
+
94
+ This is only supported on the following runtimes or newer: `Runtime.SYNTHETICS_NODEJS_PUPPETEER_10_0`, `Runtime.SYNTHETICS_NODEJS_PLAYWRIGHT_2_0`, `Runtime.SYNTHETICS_PYTHON_SELENIUM_5_1`.
95
+
96
+ Max retries can be set between 0 and 2. Canaries which time out after 10 minutes are automatically limited to one retry.
97
+
98
+ For more information, see [Configuring your canary to retry automatically](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_autoretry.html).
99
+
100
+ ```ts
101
+ const canary = new synthetics.Canary(this, 'MyCanary', {
102
+ schedule: synthetics.Schedule.rate(Duration.minutes(5)),
103
+ test: synthetics.Test.custom({
104
+ handler: 'canary.handler',
105
+ code: synthetics.Code.fromAsset(path.join(__dirname, 'canaries')),
106
+ }),
107
+ runtime: synthetics.Runtime.SYNTHETICS_PYTHON_SELENIUM_5_1,
108
+ maxRetries: 2, // The canary run will retry up to 2 times on a failure
109
+ });
110
+ ```
111
+
90
112
  ### Active Tracing
91
113
 
92
114
  You can choose to enable active AWS X-Ray tracing on canaries that use the `syn-nodejs-2.0` or later runtime by setting `activeTracing` to `true`.
@@ -368,3 +390,21 @@ const canary = new synthetics.Canary(this, 'MyCanary', {
368
390
  });
369
391
  ```
370
392
 
393
+ ### Tag replication
394
+
395
+ You can configure a canary to replicate its tags to the underlying Lambda function. This is useful when you want the same tags that are applied to the canary to also be applied to the Lambda function that the canary uses.
396
+
397
+ ```ts
398
+ const canary = new synthetics.Canary(this, 'MyCanary', {
399
+ schedule: synthetics.Schedule.rate(Duration.minutes(5)),
400
+ test: synthetics.Test.custom({
401
+ code: synthetics.Code.fromAsset(path.join(__dirname, 'canary')),
402
+ handler: 'index.handler',
403
+ }),
404
+ runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_7_0,
405
+ resourcesToReplicateTags: [synthetics.ResourceToReplicateTags.LAMBDA_FUNCTION],
406
+ });
407
+ ```
408
+
409
+ When you specify `ResourceToReplicateTags.LAMBDA_FUNCTION` in the `resourcesToReplicateTags` property, CloudWatch Synthetics will keep the tags of the canary and the Lambda function synchronized. Any future changes you make to the canary's tags will also be applied to the function.
410
+
@@ -0,0 +1,36 @@
1
+ import * as path from 'node:path';
2
+ import { App, Duration, Size, Stack, StackProps, Tags } from 'aws-cdk-lib/core';
3
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
4
+ import { Construct } from 'constructs';
5
+ import * as synthetics from 'aws-cdk-lib/aws-synthetics';
6
+
7
+ class TestStack extends Stack {
8
+ public canary: synthetics.Canary;
9
+
10
+ constructor(scope: Construct, id: string, props?: StackProps) {
11
+ super(scope, id, props);
12
+
13
+ this.canary = new synthetics.Canary(this, 'TagReplicationCanary', {
14
+ canaryName: 'tag-replication',
15
+ runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_7_0,
16
+ test: synthetics.Test.custom({
17
+ handler: 'canary.handler',
18
+ code: synthetics.Code.fromAsset(path.join(__dirname, 'canaries')),
19
+ }),
20
+ memory: Size.mebibytes(1024),
21
+ timeout: Duration.minutes(3),
22
+ resourcesToReplicateTags: [synthetics.ResourceToReplicateTags.LAMBDA_FUNCTION],
23
+ });
24
+
25
+ Tags.of(this.canary).add('Environment', 'test');
26
+ Tags.of(this.canary).add('Owner', 'cdk-team');
27
+ Tags.of(this.canary).add('Project', 'synthetics-tag-replication');
28
+ }
29
+ }
30
+
31
+ const app = new App();
32
+ const testStack = new TestStack(app, 'SyntheticsCanaryResourcesToReplicateTagsStack');
33
+
34
+ new IntegTest(app, 'SyntheticsCanaryResourcesToReplicateTags', {
35
+ testCases: [testStack],
36
+ });
@@ -0,0 +1,32 @@
1
+ import * as path from 'node:path';
2
+ import { App, Duration, Size, Stack, StackProps } from 'aws-cdk-lib/core';
3
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
4
+ import { Construct } from 'constructs';
5
+ import * as synthetics from 'aws-cdk-lib/aws-synthetics';
6
+
7
+ class TestStack extends Stack {
8
+ public canary: synthetics.Canary;
9
+
10
+ constructor(scope: Construct, id: string, props?: StackProps) {
11
+ super(scope, id, props);
12
+
13
+ this.canary = new synthetics.Canary(this, 'RetryCanary', {
14
+ canaryName: 'retry',
15
+ runtime: synthetics.Runtime.SYNTHETICS_PYTHON_SELENIUM_5_1,
16
+ test: synthetics.Test.custom({
17
+ handler: 'canary.handler',
18
+ code: synthetics.Code.fromAsset(path.join(__dirname, 'canaries')),
19
+ }),
20
+ memory: Size.mebibytes(2048),
21
+ timeout: Duration.minutes(4),
22
+ maxRetries: 2,
23
+ });
24
+ }
25
+ }
26
+
27
+ const app = new App();
28
+ const testStack = new TestStack(app, 'SyntheticsCanaryRetryStack');
29
+
30
+ new IntegTest(app, 'SyntheticsCanaryRetry', {
31
+ testCases: [testStack],
32
+ });
@@ -104,6 +104,7 @@ Flags come in three types:
104
104
  | [@aws-cdk/aws-s3:publicAccessBlockedByDefault](#aws-cdkaws-s3publicaccessblockedbydefault) | When enabled, setting any combination of options for BlockPublicAccess will automatically set true for any options not defined. | 2.196.0 | fix |
105
105
  | [@aws-cdk/aws-lambda:useCdkManagedLogGroup](#aws-cdkaws-lambdausecdkmanagedloggroup) | When enabled, CDK creates and manages loggroup for the lambda function | 2.200.0 | new default |
106
106
  | [@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal](#aws-cdkaws-kmsapplyimportedaliaspermissionstoprincipal) | Enable grant methods on Aliases imported by name to use kms:ResourceAliases condition | 2.202.0 | fix |
107
+ | [@aws-cdk/core:explicitStackTags](#aws-cdkcoreexplicitstacktags) | When enabled, stack tags need to be assigned explicitly on a Stack. | V2NEXT | new default |
107
108
 
108
109
  <!-- END table -->
109
110
 
@@ -167,6 +168,7 @@ The following json shows the current recommended set of flags, as `cdk init` wou
167
168
  "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
168
169
  "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
169
170
  "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
171
+ "@aws-cdk/core:explicitStackTags": true,
170
172
  "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false,
171
173
  "@aws-cdk/aws-ecs:disableEcsImdsBlocking": true,
172
174
  "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
@@ -2196,4 +2198,31 @@ When disabled, grant calls on imported aliases will be dropped (no-op) to mainta
2196
2198
  **Compatibility with old behavior:** Remove calls to the grant* methods on the aliases referenced by name
2197
2199
 
2198
2200
 
2201
+ ### @aws-cdk/core:explicitStackTags
2202
+
2203
+ *When enabled, stack tags need to be assigned explicitly on a Stack.*
2204
+
2205
+ Flag type: New default behavior
2206
+
2207
+ Without this feature flag enabled, if tags are added to a Stack using
2208
+ `Tags.of(scope).add(...)`, they will be added to both the stack and all resources
2209
+ in the stack template.
2210
+
2211
+ That leads to the tags being applied twice: once in the template, and once
2212
+ again automatically by CloudFormation, which will apply all stack tags to
2213
+ all resources in the stack. This leads to loss of control, as the
2214
+ `excludeResourceTypes` option of the Tags API will not have any effect.
2215
+
2216
+ With this flag enabled, tags added to a stack using `Tags.of(...)` are ignored,
2217
+ and Stack tags must be configured explicitly on the Stack object.
2218
+
2219
+
2220
+ | Since | Unset behaves like | Recommended value |
2221
+ | ----- | ----- | ----- |
2222
+ | (not in v1) | | |
2223
+ | V2NEXT | `false` | `true` |
2224
+
2225
+ **Compatibility with old behavior:** Configure stack-level tags using `new Stack(..., { tags: { ... } })`.
2226
+
2227
+
2199
2228
  <!-- END details -->
@@ -0,0 +1,105 @@
1
+ import { App, Stack, StackProps, DefaultStackSynthesizer, Stage, StageProps, RemovalPolicy } from 'aws-cdk-lib';
2
+ import { Construct } from 'constructs';
3
+ import * as path from 'path';
4
+ import * as s3 from 'aws-cdk-lib/aws-s3';
5
+ import * as pipelines from 'aws-cdk-lib/pipelines';
6
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
7
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
8
+
9
+ /**
10
+ * Notes on how to run this integ test
11
+ * Replace 123456789012 with your own account number
12
+ * Your account should be bootstrapped for us-east-1 with a custom qualifier 'dev'
13
+ * cdk bootstrap aws://123456789012/us-east-1 --qualifier dev --toolkit-stack-name CDKToolkitDev
14
+ **/
15
+
16
+ export class PipelineStack extends Stack {
17
+ constructor(scope: Construct, id: string, props: StackProps) {
18
+ super(scope, id, props);
19
+
20
+ const bucket = new s3.Bucket(this, 'assetsBucket', {
21
+ removalPolicy: RemovalPolicy.DESTROY,
22
+ autoDeleteObjects: true,
23
+ });
24
+
25
+ const pipeline = new pipelines.CodePipeline(
26
+ this,
27
+ 'Pipeline', {
28
+ synth: new pipelines.ShellStep('Synth', {
29
+ input: pipelines.CodePipelineSource.s3(
30
+ bucket,
31
+ 'cdk-sample.zip',
32
+ ),
33
+ commands: ['npm ci', 'npm run build', 'npx cdk synth'],
34
+ }),
35
+ crossAccountKeys: true,
36
+ });
37
+
38
+ const stagingStage = new DeploymentStage(
39
+ this, 'Staging', {
40
+ environmentAbbreviation: 'dev',
41
+ region: 'us-east-1',
42
+ });
43
+ pipeline.addStage(stagingStage);
44
+
45
+ const productionStage = new DeploymentStage(
46
+ this, 'Production', {
47
+ environmentAbbreviation: 'prd',
48
+ region: 'us-east-1',
49
+ });
50
+ pipeline.addStage(productionStage);
51
+ }
52
+ }
53
+
54
+ export class LambdaStack extends Stack {
55
+ constructor(scope: Construct, id: string, props?: StackProps) {
56
+ super(scope, id, props);
57
+ new lambda.Function(this, 'LambdaFN', {
58
+ runtime: lambda.Runtime.PYTHON_3_10,
59
+ handler: 'index.handler',
60
+ code: lambda.Code.fromAsset(path.join(__dirname, 'testhelpers', 'assets')),
61
+ });
62
+ }
63
+ }
64
+
65
+ export interface DeploymentStageProps extends StageProps {
66
+ environmentAbbreviation: string;
67
+ region: string;
68
+ }
69
+
70
+ export class DeploymentStage extends Stage {
71
+ constructor(scope: Construct, id: string, props: DeploymentStageProps) {
72
+ super(scope, id, props);
73
+
74
+ var synth = new DefaultStackSynthesizer();
75
+ if (props.environmentAbbreviation == 'dev') {
76
+ synth = new DefaultStackSynthesizer({
77
+ qualifier: 'dev',
78
+ });
79
+ }
80
+ new LambdaStack(
81
+ this, `${props.environmentAbbreviation}-lambda-stack`, {
82
+ env: {
83
+ region: props.region,
84
+ },
85
+ synthesizer: synth,
86
+ },
87
+ );
88
+ }
89
+ }
90
+
91
+ const app = new App({
92
+ postCliContext: {
93
+ '@aws-cdk/core:newStyleStackSynthesis': '1',
94
+ '@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2': true,
95
+ '@aws-cdk/pipelines:reduceStageRoleTrustScope': true,
96
+ },
97
+ });
98
+ const env = { region: 'us-east-1' };
99
+ const stack = new PipelineStack(app, 'pipeline-asset-stack', { env });
100
+ new IntegTest(app, 'PipelineAssetsTest', {
101
+ testCases: [stack],
102
+ diffAssets: true,
103
+ });
104
+
105
+ app.synth();
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: konokenj.cdk-api-mcp-server
3
- Version: 0.31.0
3
+ Version: 0.33.0
4
4
  Summary: An MCP server provides AWS CDK API Reference
5
5
  Project-URL: Documentation, https://github.com/konokenj/cdk-api-mcp-server#readme
6
6
  Project-URL: Issues, https://github.com/konokenj/cdk-api-mcp-server/issues
@@ -26,7 +26,7 @@ Description-Content-Type: text/markdown
26
26
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/konokenj.cdk-api-mcp-server.svg)](https://pypi.org/project/konokenj.cdk-api-mcp-server)
27
27
 
28
28
  <!-- DEP-VERSIONS-START -->
29
- [![aws-cdk](https://img.shields.io/badge/aws%20cdk-v2.203.0-blue.svg)](https://github.com/konokenj/cdk-api-mcp-server/blob/main/current-versions/aws-cdk.txt)
29
+ [![aws-cdk](https://img.shields.io/badge/aws%20cdk-v2.204.0-blue.svg)](https://github.com/konokenj/cdk-api-mcp-server/blob/main/current-versions/aws-cdk.txt)
30
30
  <!-- DEP-VERSIONS-END -->
31
31
 
32
32
  ---