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.
- cdk_api_mcp_server/__about__.py +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api-dualstack.ts +3 -4
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api.ts +2 -4
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.stage.ts +7 -20
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-authorizers/integ.iam.ts +34 -38
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.sqs.ts +58 -71
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudfront/README.md +292 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/README.md +71 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/integ.alarm-and-dashboard.ts +12 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/integ.dashboard-with-metric-id-and-visible.ts +70 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codebuild/README.md +67 -3
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codebuild/integ.project-s3-cache.ts +71 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecr-assets/integ.assets-docker.ts +6 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.availability-zone-rebalancing.ts +14 -4
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.enable-execute-command.ts +35 -29
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.exec-command.ts +16 -22
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.lb-awsvpc-nw.ts +26 -16
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.pseudo-terminal.ts +18 -8
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events/integ.api-destination.ts +42 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events-targets/README.md +7 -2
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-iam/integ.custom-permissions-boundary-aspect.ts +50 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/README.md +3 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/integ.s3-bucket.lit.ts +1 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.lambda-policy-with-token-resolution.ts +46 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/README.md +19 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.cluster-lookup.ts +100 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-route53-targets/integ.elastic-beanstalk-hostedzoneid.ts +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke-jsonata.ts +87 -80
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke.ts +87 -69
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.start-job-run.ts +96 -43
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/README.md +40 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary-resources-to-replicate-tags.ts +36 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary-retry.ts +32 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +29 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/pipelines/integ.pipeline-with-customsynthesizer.ts +105 -0
- {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/METADATA +2 -2
- {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/RECORD +40 -31
- {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/WHEEL +0 -0
- {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
- {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
cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events/integ.api-destination.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { App, CfnOutput, SecretValue, Stack } from 'aws-cdk-lib';
|
|
2
|
+
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
3
|
+
import * as events from 'aws-cdk-lib/aws-events';
|
|
4
|
+
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
|
|
5
|
+
|
|
6
|
+
const app = new App();
|
|
7
|
+
|
|
8
|
+
const stack = new Stack(app, 'events-api-destination-stack');
|
|
9
|
+
|
|
10
|
+
const secret = new secretsmanager.Secret(stack, 'Secret', {
|
|
11
|
+
secretStringValue: SecretValue.unsafePlainText('abc123'),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const connection = new events.Connection(stack, 'Connection', {
|
|
15
|
+
authorization: events.Authorization.apiKey('x-api-key', secret.secretValue),
|
|
16
|
+
description: 'Connection with API Key x-api-key',
|
|
17
|
+
connectionName: 'MyConnection',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const destination = new events.ApiDestination(stack, 'Destination', {
|
|
21
|
+
connection,
|
|
22
|
+
endpoint: 'https://httpbin.org/headers',
|
|
23
|
+
httpMethod: events.HttpMethod.GET,
|
|
24
|
+
apiDestinationName: 'MyDestination',
|
|
25
|
+
rateLimitPerSecond: 1,
|
|
26
|
+
description: 'Calling example.com with API key x-api-key',
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// arn:aws:events:{region}:{account}:api-destination/{destination-name}/11111111-1111-1111-1111-111111111111
|
|
30
|
+
new CfnOutput(stack, 'DestinationArn', {
|
|
31
|
+
value: destination.apiDestinationArn,
|
|
32
|
+
description: 'The ARN of the API destination',
|
|
33
|
+
});
|
|
34
|
+
// arn:aws:events:{region}:{account}:api-destination/{destination-name}
|
|
35
|
+
new CfnOutput(stack, 'DestinationArnForPolicy', {
|
|
36
|
+
value: destination.apiDestinationArnForPolicy || '',
|
|
37
|
+
description: 'The ARN of the API destination in resource format',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
new IntegTest(app, 'events-api-destination-integ', {
|
|
41
|
+
testCases: [stack],
|
|
42
|
+
});
|
|
@@ -369,11 +369,16 @@ const connection = events.Connection.fromEventBusArn(
|
|
|
369
369
|
'arn:aws:secretsmanager:us-east-1:123456789012:secret:SecretName-f3gDy9',
|
|
370
370
|
);
|
|
371
371
|
|
|
372
|
-
const apiDestinationArn = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName';
|
|
372
|
+
const apiDestinationArn = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName/11111111-1111-1111-1111-111111111111';
|
|
373
|
+
const apiDestinationArnForPolicy = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName';
|
|
373
374
|
const destination = events.ApiDestination.fromApiDestinationAttributes(
|
|
374
375
|
this,
|
|
375
376
|
'Destination',
|
|
376
|
-
{
|
|
377
|
+
{
|
|
378
|
+
apiDestinationArn,
|
|
379
|
+
connection,
|
|
380
|
+
apiDestinationArnForPolicy // optional
|
|
381
|
+
},
|
|
377
382
|
);
|
|
378
383
|
|
|
379
384
|
const rule = new events.Rule(this, 'OtherRule', {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This integration test tests the case of a customer setting a permissions boundary using a custom aspect,
|
|
3
|
+
* then trying to override at a more specific level using the PermissionsBoundary.of() API.
|
|
4
|
+
*
|
|
5
|
+
* Overriding should work.
|
|
6
|
+
*/
|
|
7
|
+
import { App, Stack, IAspect, Aspects } from 'aws-cdk-lib';
|
|
8
|
+
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
9
|
+
import { CfnRole, ManagedPolicy, PermissionsBoundary, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
|
|
10
|
+
import { IConstruct } from 'constructs';
|
|
11
|
+
|
|
12
|
+
class CustomAspect implements IAspect {
|
|
13
|
+
public visit(node: IConstruct): void {
|
|
14
|
+
if (node instanceof CfnRole) {
|
|
15
|
+
node.addPropertyOverride('PermissionsBoundary', 'arn:aws:iam::aws:policy/ReadOnlyAccess');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const app = new App({
|
|
21
|
+
postCliContext: {
|
|
22
|
+
// Force the intended behavior, from before we found this bug
|
|
23
|
+
'@aws-cdk/core:aspectPrioritiesMutating': false,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const stack = new Stack(app, 'integ-permissions-boundary', {
|
|
28
|
+
env: {
|
|
29
|
+
account: process.env.CDK_INTEG_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT,
|
|
30
|
+
region: process.env.CDK_INTEG_REGION ?? process.env.CDK_DEFAULT_REGION,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
Aspects.of(stack).add(new CustomAspect());
|
|
35
|
+
|
|
36
|
+
new Role(stack, 'NormalRole', {
|
|
37
|
+
assumedBy: new ServicePrincipal('sqs.amazonaws.com'),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const powerRole = new Role(stack, 'PowerRole', {
|
|
41
|
+
assumedBy: new ServicePrincipal('sqs.amazonaws.com'),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
PermissionsBoundary.of(powerRole).apply(ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'));
|
|
45
|
+
|
|
46
|
+
new IntegTest(app, 'integ-test', {
|
|
47
|
+
testCases: [stack],
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
app.synth();
|
|
@@ -102,10 +102,13 @@ will be used for files successfully delivered to S3. `errorOutputPrefix` will be
|
|
|
102
102
|
failed records before writing them to S3.
|
|
103
103
|
|
|
104
104
|
```ts
|
|
105
|
+
import { TimeZone } from 'aws-cdk-lib';
|
|
105
106
|
declare const bucket: s3.Bucket;
|
|
106
107
|
const s3Destination = new firehose.S3Bucket(bucket, {
|
|
107
108
|
dataOutputPrefix: 'myFirehose/DeliveredYear=!{timestamp:yyyy}/anyMonth/rand=!{firehose:random-string}',
|
|
108
109
|
errorOutputPrefix: 'myFirehoseFailures/!{firehose:error-output-type}/!{timestamp:yyyy}/anyMonth/!{timestamp:dd}',
|
|
110
|
+
// The time zone of timestamps (default UTC)
|
|
111
|
+
timeZone: TimeZone.ASIA_TOKYO,
|
|
109
112
|
});
|
|
110
113
|
```
|
|
111
114
|
|
|
@@ -56,6 +56,7 @@ const deliveryStream = new firehose.DeliveryStream(stack, 'DeliveryStream', {
|
|
|
56
56
|
dataOutputPrefix: 'regularPrefix',
|
|
57
57
|
errorOutputPrefix: 'errorPrefix',
|
|
58
58
|
fileExtension: '.log.gz',
|
|
59
|
+
timeZone: cdk.TimeZone.ASIA_TOKYO,
|
|
59
60
|
bufferingInterval: cdk.Duration.seconds(60),
|
|
60
61
|
bufferingSize: cdk.Size.mebibytes(1),
|
|
61
62
|
encryptionKey: key,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as cdk from 'aws-cdk-lib';
|
|
2
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
3
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
4
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
5
|
+
|
|
6
|
+
const app = new cdk.App({
|
|
7
|
+
postCliContext: {
|
|
8
|
+
'@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
const stack = new cdk.Stack(app, 'stack');
|
|
12
|
+
|
|
13
|
+
const mappingName = 'testmapping';
|
|
14
|
+
const mapping = new cdk.CfnMapping(stack, 'testmapping', {
|
|
15
|
+
mapping: {
|
|
16
|
+
us: {
|
|
17
|
+
regionalModels:
|
|
18
|
+
'arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-lite-v1:0',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
mapping.overrideLogicalId(mappingName);
|
|
23
|
+
|
|
24
|
+
const func = new lambda.Function(stack, 'test-function', {
|
|
25
|
+
code: new lambda.InlineCode('exports.handler = async (event) => { console.log(event); return {\'statusCode\': 200, \'body\': \'\'}; }'),
|
|
26
|
+
runtime: lambda.Runtime.NODEJS_20_X,
|
|
27
|
+
handler: 'index.handler',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Literal resources in statement
|
|
31
|
+
func.addToRolePolicy(new iam.PolicyStatement({
|
|
32
|
+
actions: ['bedrock:Invoke*'],
|
|
33
|
+
resources: [
|
|
34
|
+
'*',
|
|
35
|
+
],
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
// Array token resources in statement
|
|
39
|
+
func.addToRolePolicy(new iam.PolicyStatement({
|
|
40
|
+
actions: ['bedrock:Invoke*'],
|
|
41
|
+
resources: cdk.Fn.split(',', cdk.Fn.findInMap(mappingName, 'us', 'regionalModels')),
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
new integ.IntegTest(app, 'lambda-policy-with-token-resolution', {
|
|
45
|
+
testCases: [stack],
|
|
46
|
+
});
|
|
@@ -1605,6 +1605,25 @@ const dbFromLookup = rds.DatabaseInstance.fromLookup(this, 'dbFromLookup', {
|
|
|
1605
1605
|
dbFromLookup.grantConnect(myUserRole, 'my-user-id');
|
|
1606
1606
|
```
|
|
1607
1607
|
|
|
1608
|
+
## Importing existing DatabaseCluster
|
|
1609
|
+
|
|
1610
|
+
### Lookup DatabaseCluster by clusterIdentifier
|
|
1611
|
+
|
|
1612
|
+
You can lookup an existing DatabaseCluster by its clusterIdentifier using `DatabaseCluster.fromLookup()`. This method returns an `IDatabaseCluster`.
|
|
1613
|
+
|
|
1614
|
+
Here's how `DatabaseCluster.fromLookup()` can be used:
|
|
1615
|
+
|
|
1616
|
+
```ts
|
|
1617
|
+
declare const myUserRole: iam.Role;
|
|
1618
|
+
|
|
1619
|
+
const clusterFromLookup = rds.DatabaseCluster.fromLookup(this, 'ClusterFromLookup', {
|
|
1620
|
+
clusterIdentifier: 'my-cluster-id',
|
|
1621
|
+
});
|
|
1622
|
+
|
|
1623
|
+
// Grant a connection
|
|
1624
|
+
clusterFromLookup.grantConnect(myUserRole, 'my-user-id');
|
|
1625
|
+
```
|
|
1626
|
+
|
|
1608
1627
|
## Limitless Database Cluster
|
|
1609
1628
|
|
|
1610
1629
|
Amazon Aurora [PostgreSQL Limitless Database](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/limitless.html) provides automated horizontal scaling to process millions of write transactions per second and manages petabytes of data while maintaining the simplicity of operating inside a single database.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
2
|
+
import { App, CfnOutput, Stack } from 'aws-cdk-lib';
|
|
3
|
+
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
|
|
4
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
5
|
+
import * as rds from 'aws-cdk-lib/aws-rds';
|
|
6
|
+
|
|
7
|
+
const app = new App();
|
|
8
|
+
const clusterIdentifier = 'test-cluster-lookup';
|
|
9
|
+
|
|
10
|
+
const stackLookup = new Stack(app, 'aws-cdk-rds-cluster-lookup', {
|
|
11
|
+
env: {
|
|
12
|
+
account: process.env.CDK_INTEG_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT,
|
|
13
|
+
region: process.env.CDK_INTEG_REGION ?? process.env.CDK_DEFAULT_REGION,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Lookup the existing cluster created by the preDeploy hook
|
|
18
|
+
const lookedUpCluster = rds.DatabaseCluster.fromLookup(stackLookup, 'LookedUpCluster', {
|
|
19
|
+
clusterIdentifier,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
new CfnOutput(stackLookup, 'LookedUpClusterEndpoint', {
|
|
23
|
+
value: lookedUpCluster.clusterEndpoint.socketAddress,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
new CfnOutput(stackLookup, 'LookedUpClusterReadEndpoint', {
|
|
27
|
+
value: lookedUpCluster.clusterReadEndpoint.socketAddress,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
new CfnOutput(stackLookup, 'LookedUpClusterIdentifier', {
|
|
31
|
+
value: lookedUpCluster.clusterIdentifier,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
new CfnOutput(stackLookup, 'LookedUpClusterResourceIdentifier', {
|
|
35
|
+
value: lookedUpCluster.clusterResourceIdentifier,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
new CfnOutput(stackLookup, 'LookedUpClusterArn', {
|
|
39
|
+
value: lookedUpCluster.clusterArn,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
new CfnOutput(stackLookup, 'SecurityGroupIds', {
|
|
43
|
+
value: lookedUpCluster.connections.securityGroups.map(sg => sg.securityGroupId).join(','),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// test grant
|
|
47
|
+
const dbAccessRole = new iam.Role(stackLookup, 'DbAccessRole', {
|
|
48
|
+
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
|
|
49
|
+
description: 'Role for accessing the Aurora cluster via IAM authentication',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
lookedUpCluster.grantConnect(dbAccessRole, 'admin');
|
|
53
|
+
lookedUpCluster.grantDataApiAccess(dbAccessRole);
|
|
54
|
+
|
|
55
|
+
// test metric
|
|
56
|
+
lookedUpCluster.metricDatabaseConnections().createAlarm(stackLookup, 'HighConnectionsAlarm', {
|
|
57
|
+
threshold: 100,
|
|
58
|
+
evaluationPeriods: 3,
|
|
59
|
+
alarmDescription: 'Database has high number of connections',
|
|
60
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
lookedUpCluster.metricCPUUtilization().createAlarm(stackLookup, 'HighCPUAlarm', {
|
|
64
|
+
threshold: 90,
|
|
65
|
+
evaluationPeriods: 3,
|
|
66
|
+
alarmDescription: 'Database CPU utilization is high',
|
|
67
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
lookedUpCluster.metricFreeableMemory().createAlarm(stackLookup, 'LowMemoryAlarm', {
|
|
71
|
+
threshold: 100 * 1024 * 1024,
|
|
72
|
+
evaluationPeriods: 3,
|
|
73
|
+
alarmDescription: 'Database is running low on memory',
|
|
74
|
+
comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
lookedUpCluster.metricDeadlocks().createAlarm(stackLookup, 'DeadlockAlarm', {
|
|
78
|
+
threshold: 5,
|
|
79
|
+
evaluationPeriods: 2,
|
|
80
|
+
alarmDescription: 'Database has deadlocks',
|
|
81
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
new IntegTest(app, 'integ-rds-cluster-from-lookup', {
|
|
85
|
+
testCases: [stackLookup],
|
|
86
|
+
enableLookups: true,
|
|
87
|
+
stackUpdateWorkflow: false,
|
|
88
|
+
// Create Aurora cluster before the test and delete it after
|
|
89
|
+
hooks: {
|
|
90
|
+
preDeploy: [
|
|
91
|
+
`aws rds create-db-cluster --db-cluster-identifier ${clusterIdentifier} --engine aurora-mysql --engine-version 8.0.mysql_aurora.3.09.0 --master-username admin --master-user-password Admin1234 --enable-http-endpoint --enable-iam-database-authentication --region us-east-1`,
|
|
92
|
+
`aws rds create-db-instance --db-instance-identifier ${clusterIdentifier}-instance --db-cluster-identifier ${clusterIdentifier} --engine aurora-mysql --db-instance-class db.r5.large --region us-east-1`,
|
|
93
|
+
`aws rds wait db-instance-available --db-instance-identifier ${clusterIdentifier}-instance --region us-east-1`,
|
|
94
|
+
],
|
|
95
|
+
postDeploy: [
|
|
96
|
+
`aws rds delete-db-instance --db-instance-identifier ${clusterIdentifier}-instance --skip-final-snapshot --region us-east-1`,
|
|
97
|
+
`aws rds delete-db-cluster --db-cluster-identifier ${clusterIdentifier} --skip-final-snapshot --region us-east-1`,
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
});
|
|
@@ -6,7 +6,7 @@ import * as targets from 'aws-cdk-lib/aws-route53-targets';
|
|
|
6
6
|
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
7
7
|
import * as elasticbeanstalk from 'aws-cdk-lib/aws-elasticbeanstalk';
|
|
8
8
|
import * as custom from 'aws-cdk-lib/custom-resources';
|
|
9
|
-
import { RegionInfo } from 'aws-cdk
|
|
9
|
+
import { RegionInfo } from '@aws-cdk/region-info';
|
|
10
10
|
|
|
11
11
|
const app = new App({
|
|
12
12
|
postCliContext: {
|
|
@@ -1,112 +1,119 @@
|
|
|
1
|
-
import
|
|
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
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
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
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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
|
-
*
|
|
17
|
-
*
|
|
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-
|
|
25
|
+
const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-lambda-invoke-jsonata-integ');
|
|
26
26
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
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
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
},
|
|
39
|
+
const submitJob = LambdaInvoke.jsonata(stack, 'Invoke Handler', {
|
|
40
|
+
lambdaFunction: submitJobLambda,
|
|
41
|
+
payload: sfn.TaskInput.fromObject({
|
|
42
|
+
execId: '{% $states.context.Execution.Id %}',
|
|
43
|
+
execInput: '{% $states.context.Execution.Input %}',
|
|
44
|
+
execName: '{% $states.context.Execution.Name %}',
|
|
45
|
+
execRoleArn: '{% $states.context.Execution.RoleArn %}',
|
|
46
|
+
execStartTime: '{% $states.context.Execution.StartTime %}',
|
|
47
|
+
stateEnteredTime: '{% $states.context.State.EnteredTime %}',
|
|
48
|
+
stateName: '{% $states.context.State.Name %}',
|
|
49
|
+
stateRetryCount: '{% $states.context.State.RetryCount %}',
|
|
50
|
+
stateMachineId: '{% $states.context.StateMachine.Id %}',
|
|
51
|
+
stateMachineName: '{% $states.context.StateMachine.Name %}',
|
|
55
52
|
}),
|
|
56
|
-
{
|
|
57
|
-
|
|
58
|
-
methodResponses: [
|
|
59
|
-
{
|
|
60
|
-
statusCode: '200',
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
},
|
|
64
|
-
);
|
|
53
|
+
outputs: '{% $states.result.Payload %}',
|
|
54
|
+
});
|
|
65
55
|
|
|
66
|
-
const
|
|
67
|
-
|
|
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',
|
|
68
70
|
});
|
|
69
71
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
apiEndpoint: sfn.TaskInput.fromText('{% $states.input.apiEndpoint %}'),
|
|
73
|
-
connection,
|
|
74
|
-
method: sfn.TaskInput.fromText('GET'),
|
|
72
|
+
const checkJobState = LambdaInvoke.jsonata(stack, 'Check the job state', {
|
|
73
|
+
lambdaFunction: checkJobStateLambda,
|
|
75
74
|
outputs: {
|
|
76
|
-
|
|
75
|
+
status: '{% $states.result.Payload.status %}',
|
|
77
76
|
},
|
|
78
77
|
});
|
|
79
78
|
|
|
79
|
+
const isComplete = sfn.Choice.jsonata(stack, 'Job Complete?');
|
|
80
|
+
const jobFailed = sfn.Fail.jsonata(stack, 'Job Failed', {
|
|
81
|
+
cause: 'Job Failed',
|
|
82
|
+
error: 'Received a status that was not 200',
|
|
83
|
+
});
|
|
84
|
+
const finalStatus = sfn.Pass.jsonata(stack, 'Final step');
|
|
85
|
+
|
|
86
|
+
const chain = sfn.Chain.start(submitJob)
|
|
87
|
+
.next(checkJobState)
|
|
88
|
+
.next(
|
|
89
|
+
isComplete
|
|
90
|
+
.when(sfn.Condition.jsonata("{% $states.input.status = 'FAILED' %}"), jobFailed)
|
|
91
|
+
.when(sfn.Condition.jsonata("{% $states.input.status = 'SUCCEEDED' %}"), finalStatus),
|
|
92
|
+
);
|
|
93
|
+
|
|
80
94
|
const sm = new sfn.StateMachine(stack, 'StateMachine', {
|
|
81
|
-
definition:
|
|
95
|
+
definition: chain,
|
|
82
96
|
timeout: cdk.Duration.seconds(30),
|
|
83
97
|
});
|
|
84
98
|
|
|
85
|
-
|
|
86
|
-
|
|
99
|
+
new cdk.CfnOutput(stack, 'stateMachineArn', {
|
|
100
|
+
value: sm.stateMachineArn,
|
|
87
101
|
});
|
|
88
102
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
stateMachineArn: sm.stateMachineArn,
|
|
92
|
-
input: JSON.stringify({
|
|
93
|
-
apiEndpoint: '/test',
|
|
94
|
-
}),
|
|
103
|
+
const integ = new IntegTest(app, 'IntegTest', {
|
|
104
|
+
testCases: [stack],
|
|
95
105
|
});
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const describe = testCase.assertions.awsApiCall('@aws-sdk/client-sfn', 'DescribeExecution', {
|
|
99
|
-
executionArn: start.getAttString('executionArn'),
|
|
106
|
+
const res = integ.assertions.awsApiCall('@aws-sdk/client-sfn', 'StartExecution', {
|
|
107
|
+
stateMachineArn: sm.stateMachineArn,
|
|
100
108
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
const executionArn = res.getAttString('executionArn');
|
|
110
|
+
integ.assertions.awsApiCall('@aws-sdk/client-sfn', 'DescribeExecution', {
|
|
111
|
+
executionArn,
|
|
112
|
+
}).expect(ExpectedResult.objectLike({
|
|
104
113
|
status: 'SUCCEEDED',
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}),
|
|
110
|
-
}));
|
|
114
|
+
})).waitForAssertions({
|
|
115
|
+
totalTimeout: cdk.Duration.seconds(10),
|
|
116
|
+
interval: cdk.Duration.seconds(3),
|
|
117
|
+
});
|
|
111
118
|
|
|
112
119
|
app.synth();
|