konokenj.cdk-api-mcp-server 0.41.0__py3-none-any.whl → 0.43.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/aws-bedrock-alpha/README.md +540 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-eks-v2-alpha/README.md +44 -46
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-glue-alpha/README.md +9 -9
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-lambda-python-alpha/README.md +6 -6
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-s3tables-alpha/README.md +28 -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-certificatemanager/README.md +11 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/README.md +13 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/integ.dashboard-with-graphwidget-with-labels-visible.ts +92 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codepipeline-actions/integ.pipeline-elastic-beanstalk-deploy.ts +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cognito/README.md +11 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cognito/integ.user-pool-client-explicit-props.ts +1 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/README.md +38 -13
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb-v2.cci.ts +49 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb.cci.ts +27 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb.contirubtor-insights-for-gsi.ts +6 -2
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.table-v2-global.ts +9 -3
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/README.md +3 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.ebs-volume-initialization-rate.ts +80 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs-patterns/README.md +2 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs-patterns/integ.alb-fargate-service-smart-defaults.ts +143 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events/README.md +25 -3
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events/integ.archive-customer-managed-key.ts +23 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events-targets/README.md +64 -2
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/README.md +18 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.cluster.ts +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-assets/integ.assets.bundling.docker-opts.ts +4 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/README.md +18 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-sns/README.md +2 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-sns-subscriptions/integ.sns-sqs-subscription-filter.ts +75 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-sns-subscriptions/integ.sns-sqs.ts +21 -40
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.evaluate-expression-nodejs22.ts +27 -0
- 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 +102 -104
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +28 -1
- {konokenj_cdk_api_mcp_server-0.41.0.dist-info → konokenj_cdk_api_mcp_server-0.43.0.dist-info}/METADATA +2 -2
- {konokenj_cdk_api_mcp_server-0.41.0.dist-info → konokenj_cdk_api_mcp_server-0.43.0.dist-info}/RECORD +46 -38
- {konokenj_cdk_api_mcp_server-0.41.0.dist-info → konokenj_cdk_api_mcp_server-0.43.0.dist-info}/WHEEL +0 -0
- {konokenj_cdk_api_mcp_server-0.41.0.dist-info → konokenj_cdk_api_mcp_server-0.43.0.dist-info}/entry_points.txt +0 -0
- {konokenj_cdk_api_mcp_server-0.41.0.dist-info → konokenj_cdk_api_mcp_server-0.43.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration test for the conditional openListener behavior in ApplicationLoadBalancedFargateService.
|
|
3
|
+
*
|
|
4
|
+
* This test validates the security feature that automatically sets openListener to false when custom
|
|
5
|
+
* security groups are detected on the load balancer, preventing unintended internet exposure.
|
|
6
|
+
*
|
|
7
|
+
* Test scenarios:
|
|
8
|
+
* 1. DefaultService: No custom security groups provided
|
|
9
|
+
* - Expected: openListener defaults to true, creates 0.0.0.0/0 ingress rules
|
|
10
|
+
* - Validates: Default behavior when CDK manages all security groups
|
|
11
|
+
*
|
|
12
|
+
* 2. ExplicitOpenService: Explicit openListener: true
|
|
13
|
+
* - Expected: Creates 0.0.0.0/0 ingress rules regardless of other settings
|
|
14
|
+
* - Validates: Explicit override functionality works correctly
|
|
15
|
+
*
|
|
16
|
+
* 3. ExplicitClosedService: Explicit openListener: false
|
|
17
|
+
* - Expected: Does NOT create 0.0.0.0/0 ingress rules
|
|
18
|
+
* - Validates: Explicit closed listener prevents internet access
|
|
19
|
+
*
|
|
20
|
+
* 4. ConditionalWithCustomSG: Custom security groups + no explicit openListener
|
|
21
|
+
* - Expected: Conditional behavior kicks in, openListener defaults to false
|
|
22
|
+
* - Validates: Core feature - prevents 0.0.0.0/0 rules when custom SGs detected
|
|
23
|
+
*
|
|
24
|
+
* The test uses AWS SDK calls to verify actual security group configurations in deployed resources,
|
|
25
|
+
* ensuring the feature works correctly in real AWS environments.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { Vpc, SecurityGroup, Port } from 'aws-cdk-lib/aws-ec2';
|
|
29
|
+
import { Cluster, ContainerImage } from 'aws-cdk-lib/aws-ecs';
|
|
30
|
+
import { ApplicationLoadBalancer } from 'aws-cdk-lib/aws-elasticloadbalancingv2';
|
|
31
|
+
import { App, Stack, Duration } from 'aws-cdk-lib';
|
|
32
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
33
|
+
import { ApplicationLoadBalancedFargateService } from 'aws-cdk-lib/aws-ecs-patterns';
|
|
34
|
+
|
|
35
|
+
const app = new App({
|
|
36
|
+
postCliContext: {
|
|
37
|
+
// Enable the feature flag for this test
|
|
38
|
+
'@aws-cdk/aws-ecs-patterns:secGroupsDisablesImplicitOpenListener': true,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const stack = new Stack(app, 'aws-ecs-integ-alb-fg-smart-defaults');
|
|
43
|
+
const vpc = new Vpc(stack, 'Vpc', { maxAzs: 3, natGateways: 1, restrictDefaultSecurityGroup: false });
|
|
44
|
+
const cluster = new Cluster(stack, 'Cluster', { vpc });
|
|
45
|
+
|
|
46
|
+
// Test case 1: Service with conditional default (no openListener specified)
|
|
47
|
+
// CDK creates load balancer, should default to openListener: true (no custom security groups)
|
|
48
|
+
new ApplicationLoadBalancedFargateService(stack, 'SmartDefaultService', {
|
|
49
|
+
cluster,
|
|
50
|
+
memoryLimitMiB: 512,
|
|
51
|
+
taskImageOptions: {
|
|
52
|
+
image: ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
|
|
53
|
+
},
|
|
54
|
+
// No openListener specified - should default to true since no custom security groups
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Test case 2: Service with explicit openListener: true
|
|
58
|
+
new ApplicationLoadBalancedFargateService(stack, 'ExplicitOpenService', {
|
|
59
|
+
cluster,
|
|
60
|
+
memoryLimitMiB: 512,
|
|
61
|
+
taskImageOptions: {
|
|
62
|
+
image: ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
|
|
63
|
+
},
|
|
64
|
+
openListener: true, // Should create 0.0.0.0/0 rules
|
|
65
|
+
listenerPort: 8080,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Test case 3: Service with explicit openListener: false
|
|
69
|
+
new ApplicationLoadBalancedFargateService(stack, 'ExplicitClosedService', {
|
|
70
|
+
cluster,
|
|
71
|
+
memoryLimitMiB: 512,
|
|
72
|
+
taskImageOptions: {
|
|
73
|
+
image: ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
|
|
74
|
+
},
|
|
75
|
+
openListener: false, // Should NOT create 0.0.0.0/0 rules
|
|
76
|
+
listenerPort: 9090,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Test case 4: Service with custom security groups (conditional default should apply)
|
|
80
|
+
const customSecurityGroup = new SecurityGroup(stack, 'CustomSecurityGroup', {
|
|
81
|
+
vpc,
|
|
82
|
+
description: 'Custom security group for load balancer',
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Add a custom rule to the security group
|
|
86
|
+
customSecurityGroup.addIngressRule(
|
|
87
|
+
customSecurityGroup,
|
|
88
|
+
Port.tcp(80),
|
|
89
|
+
'Allow HTTP from custom security group',
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const customLoadBalancer = new ApplicationLoadBalancer(stack, 'CustomLoadBalancer', {
|
|
93
|
+
vpc,
|
|
94
|
+
internetFacing: true,
|
|
95
|
+
securityGroup: customSecurityGroup,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// This should use conditional default (openListener: false) because custom security groups are detected
|
|
99
|
+
new ApplicationLoadBalancedFargateService(stack, 'SmartDefaultWithCustomSG', {
|
|
100
|
+
cluster,
|
|
101
|
+
memoryLimitMiB: 512,
|
|
102
|
+
taskImageOptions: {
|
|
103
|
+
image: ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
|
|
104
|
+
},
|
|
105
|
+
loadBalancer: customLoadBalancer,
|
|
106
|
+
// No openListener specified - should default to false due to custom security groups
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const integTest = new integ.IntegTest(app, 'albFargateServiceSmartDefaultsTest', {
|
|
110
|
+
testCases: [stack],
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Validate the core conditional behavior by checking the custom security group
|
|
114
|
+
// This confirms that when custom security groups are provided, the conditional default prevents
|
|
115
|
+
// creating overly permissive 0.0.0.0/0 ingress rules
|
|
116
|
+
// Assert that the custom security group only contains self-referencing rules (no 0.0.0.0/0)
|
|
117
|
+
// This validates the feature prevents unintended internet exposure
|
|
118
|
+
integTest.assertions.awsApiCall('EC2', 'describeSecurityGroups', {
|
|
119
|
+
GroupIds: [customSecurityGroup.securityGroupId],
|
|
120
|
+
}).expect(integ.ExpectedResult.objectLike({
|
|
121
|
+
SecurityGroups: [
|
|
122
|
+
{
|
|
123
|
+
IpPermissions: integ.Match.arrayWith([
|
|
124
|
+
integ.Match.objectLike({
|
|
125
|
+
FromPort: 80,
|
|
126
|
+
ToPort: 80,
|
|
127
|
+
// Verify only security group references exist, no public internet access (0.0.0.0/0)
|
|
128
|
+
UserIdGroupPairs: integ.Match.arrayWith([
|
|
129
|
+
integ.Match.objectLike({
|
|
130
|
+
GroupId: customSecurityGroup.securityGroupId,
|
|
131
|
+
}),
|
|
132
|
+
]),
|
|
133
|
+
// Ensure no IpRanges with 0.0.0.0/0 are present
|
|
134
|
+
IpRanges: [],
|
|
135
|
+
}),
|
|
136
|
+
]),
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
})).waitForAssertions({
|
|
140
|
+
totalTimeout: Duration.minutes(5),
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
app.synth();
|
|
@@ -332,6 +332,28 @@ new events.EventBus(this, 'Bus', {
|
|
|
332
332
|
});
|
|
333
333
|
```
|
|
334
334
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
335
|
+
To use a customer managed key for an archive, use the `kmsKey` attribute.
|
|
336
|
+
|
|
337
|
+
Note: When you attach a customer managed key to either an EventBus or an Archive, a policy that allows EventBridge to interact with your resource will be added.
|
|
338
|
+
|
|
339
|
+
```ts
|
|
340
|
+
import * as kms from 'aws-cdk-lib/aws-kms';
|
|
341
|
+
import { Archive, EventBus } from 'aws-cdk-lib/aws-events';
|
|
342
|
+
|
|
343
|
+
const stack = new Stack();
|
|
344
|
+
|
|
345
|
+
declare const kmsKey: kms.IKey;
|
|
346
|
+
|
|
347
|
+
const eventBus = new EventBus(stack, 'Bus');
|
|
348
|
+
|
|
349
|
+
const archive = new Archive(stack, 'Archive', {
|
|
350
|
+
kmsKey: kmsKey,
|
|
351
|
+
sourceEventBus: eventBus,
|
|
352
|
+
eventPattern: {
|
|
353
|
+
source: ['aws.ec2']
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
To enable archives or schema discovery on an event bus, customers has the choice of using either an AWS owned key or a customer managed key.
|
|
359
|
+
For more information, see [KMS key options for event bus encryption](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-encryption-at-rest-key-options.html).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as kms from 'aws-cdk-lib/aws-kms';
|
|
2
|
+
import { App, RemovalPolicy, Stack } from 'aws-cdk-lib';
|
|
3
|
+
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
4
|
+
import { Archive, EventBus } from 'aws-cdk-lib/aws-events';
|
|
5
|
+
|
|
6
|
+
const app = new App();
|
|
7
|
+
const stack = new Stack(app, 'archive-customer-managed-key');
|
|
8
|
+
|
|
9
|
+
const kmsKey = new kms.Key(stack, 'KmsKey', {
|
|
10
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
new Archive(stack, 'Archive', {
|
|
14
|
+
kmsKey: kmsKey,
|
|
15
|
+
sourceEventBus: EventBus.fromEventBusName(stack, 'DefaultEventBus', 'default'),
|
|
16
|
+
eventPattern: {
|
|
17
|
+
source: ['test'],
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
new IntegTest(app, 'archive-customer-managed-key-test', {
|
|
22
|
+
testCases: [stack],
|
|
23
|
+
});
|
|
@@ -15,6 +15,7 @@ Currently supported are:
|
|
|
15
15
|
- [Start a StepFunctions state machine](#start-a-stepfunctions-state-machine)
|
|
16
16
|
- [Queue a Batch job](#queue-a-batch-job)
|
|
17
17
|
- [Invoke an API Gateway REST API](#invoke-an-api-gateway-rest-api)
|
|
18
|
+
- [Invoke an AWS API](#invoke-an-aws-api)
|
|
18
19
|
- [Invoke an API Destination](#invoke-an-api-destination)
|
|
19
20
|
- [Invoke an AppSync GraphQL API](#invoke-an-appsync-graphql-api)
|
|
20
21
|
- [Put an event on an EventBridge bus](#put-an-event-on-an-eventbridge-bus)
|
|
@@ -333,6 +334,67 @@ declare const rule: events.Rule;
|
|
|
333
334
|
rule.addTarget(new targets.ApiGatewayV2(httpApi));
|
|
334
335
|
```
|
|
335
336
|
|
|
337
|
+
## Invoke an AWS API
|
|
338
|
+
|
|
339
|
+
Use the `AwsApi` target to make direct AWS API calls from EventBridge rules. This is useful for invoking AWS services that don't have a dedicated EventBridge target.
|
|
340
|
+
|
|
341
|
+
### Basic Usage
|
|
342
|
+
|
|
343
|
+
The following example shows how to update an ECS service when a rule is triggered:
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
const rule = new events.Rule(this, 'Rule', {
|
|
347
|
+
schedule: events.Schedule.rate(Duration.hours(1)),
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
rule.addTarget(new targets.AwsApi({
|
|
351
|
+
service: 'ECS',
|
|
352
|
+
action: 'updateService',
|
|
353
|
+
parameters: {
|
|
354
|
+
service: 'my-service',
|
|
355
|
+
forceNewDeployment: true,
|
|
356
|
+
},
|
|
357
|
+
}));
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### IAM Permissions
|
|
361
|
+
|
|
362
|
+
By default, the AwsApi target automatically creates the necessary IAM permissions based on the service and action you specify. The permission format follows the pattern: `service:Action`.
|
|
363
|
+
|
|
364
|
+
For example:
|
|
365
|
+
|
|
366
|
+
- `ECS` service with `updateService` action → `ecs:UpdateService` permission
|
|
367
|
+
- `RDS` service with `createDBSnapshot` action → `rds:CreateDBSnapshot` permission
|
|
368
|
+
|
|
369
|
+
### Custom IAM Policy
|
|
370
|
+
|
|
371
|
+
In some cases, you may need to provide a custom IAM policy statement, especially when:
|
|
372
|
+
|
|
373
|
+
- You need to restrict permissions to specific resources (instead of `*`)
|
|
374
|
+
- The service requires additional permissions beyond the main action
|
|
375
|
+
- You want more granular control over the permissions
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
379
|
+
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
380
|
+
|
|
381
|
+
declare const rule: events.Rule;
|
|
382
|
+
declare const bucket: s3.Bucket;
|
|
383
|
+
|
|
384
|
+
rule.addTarget(new targets.AwsApi({
|
|
385
|
+
service: 's3',
|
|
386
|
+
action: 'GetBucketEncryption',
|
|
387
|
+
parameters: {
|
|
388
|
+
Bucket: bucket.bucketName,
|
|
389
|
+
},
|
|
390
|
+
policyStatement: new iam.PolicyStatement({
|
|
391
|
+
effect: iam.Effect.ALLOW,
|
|
392
|
+
actions: ['s3:GetEncryptionConfiguration'],
|
|
393
|
+
resources: [bucket.bucketArn],
|
|
394
|
+
}),
|
|
395
|
+
}));
|
|
396
|
+
```
|
|
397
|
+
|
|
336
398
|
## Invoke an API Destination
|
|
337
399
|
|
|
338
400
|
Use the `targets.ApiDestination` target to trigger an external API. You need to
|
|
@@ -636,7 +698,7 @@ rule.addTarget(new targets.RedshiftQuery(workgroup.attrWorkgroupWorkgroupArn, {
|
|
|
636
698
|
|
|
637
699
|
## Publish to an SNS Topic
|
|
638
700
|
|
|
639
|
-
Use the `SnsTopic` target to publish to an SNS Topic.
|
|
701
|
+
Use the `SnsTopic` target to publish to an SNS Topic.
|
|
640
702
|
|
|
641
703
|
The code snippet below creates the scheduled event rule that publishes to an SNS Topic using a resource policy.
|
|
642
704
|
|
|
@@ -664,4 +726,4 @@ const rule = new events.Rule(this, 'Rule', {
|
|
|
664
726
|
});
|
|
665
727
|
|
|
666
728
|
rule.addTarget(new targets.SnsTopic(topic, { authorizeUsingRole: true }));
|
|
667
|
-
```
|
|
729
|
+
```
|
|
@@ -418,6 +418,24 @@ To apply changes of the cluster, such as engine version, in the next scheduled m
|
|
|
418
418
|
|
|
419
419
|
For details, see [Modifying an Amazon Aurora DB cluster](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.Modifying.html).
|
|
420
420
|
|
|
421
|
+
### Retaining Automated Backups
|
|
422
|
+
|
|
423
|
+
By default, when a database cluster is deleted, automated backups are removed immediately unless an AWS Backup policy specifies a point-in-time restore rule. You can control this behavior using the `deleteAutomatedBackups` property:
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
declare const vpc: ec2.IVpc;
|
|
427
|
+
// Retain automated backups after cluster deletion
|
|
428
|
+
new rds.DatabaseCluster(this, 'Database', {
|
|
429
|
+
engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_3_01_0 }),
|
|
430
|
+
writer: rds.ClusterInstance.provisioned('writer'),
|
|
431
|
+
vpc,
|
|
432
|
+
deleteAutomatedBackups: false,
|
|
433
|
+
});
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
When set to `false`, automated backups are retained according to the configured retention period after the cluster is deleted. When set to `true` or not specified (default), automated backups are deleted immediately when the cluster is deleted.
|
|
437
|
+
Detail about this feature can be found in the [AWS documentation](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.Managing.Backups.Retaining.html).
|
|
438
|
+
|
|
421
439
|
### Migrating from instanceProps
|
|
422
440
|
|
|
423
441
|
Creating instances in a `DatabaseCluster` using `instanceProps` & `instances` is
|
|
@@ -63,6 +63,7 @@ class TestStack extends cdk.Stack {
|
|
|
63
63
|
parameterGroup: params,
|
|
64
64
|
storageEncryptionKey: kmsKey,
|
|
65
65
|
autoMinorVersionUpgrade: false,
|
|
66
|
+
deleteAutomatedBackups: false,
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
cluster.connections.allowDefaultPortFromAnyIpv4('Open to the world');
|
|
@@ -100,4 +101,3 @@ const stackWithFeatureFlag = new TestStack(appWithFeatureFlag, 'aws-cdk-rds-inte
|
|
|
100
101
|
new IntegTest(appWithFeatureFlag, 'test-rds-cluster-with-feature-flag', {
|
|
101
102
|
testCases: [stackWithFeatureFlag],
|
|
102
103
|
});
|
|
103
|
-
appWithFeatureFlag.synth();
|
|
@@ -9,7 +9,10 @@ const stack = new Stack(app, 'cdk-integ-assets-bundling-docker-opts');
|
|
|
9
9
|
new assets.Asset(stack, 'BundledAsset', {
|
|
10
10
|
path: path.join(__dirname, 'markdown-asset'), // /asset-input and working directory in the container
|
|
11
11
|
bundling: {
|
|
12
|
-
|
|
12
|
+
// Build an image
|
|
13
|
+
image: DockerImage.fromBuild(path.join(__dirname, 'alpine-markdown'), {
|
|
14
|
+
platform: 'linux/amd64',
|
|
15
|
+
}),
|
|
13
16
|
command: [
|
|
14
17
|
'sh', '-c', `
|
|
15
18
|
markdown index.md > /asset-output/index.html
|
|
@@ -325,6 +325,24 @@ new s3deploy.BucketDeployment(this, 'DeployWithInvalidation', {
|
|
|
325
325
|
});
|
|
326
326
|
```
|
|
327
327
|
|
|
328
|
+
By default, the deployment will wait for invalidation to succeed to complete. This will poll Cloudfront for a maximum of 13 minutes to check for a successful invalidation. The drawback to this is that the deployment will fail if invalidation fails or if it takes longer than 13 minutes. As a workaround, there is the option `waitForDistributionInvalidation`, which can be set to false to skip waiting for the invalidation, but this can be risky as invalidation errors will not be reported.
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
|
|
332
|
+
|
|
333
|
+
declare const bucket: s3.IBucket;
|
|
334
|
+
declare const distribution: cloudfront.IDistribution;
|
|
335
|
+
|
|
336
|
+
new s3deploy.BucketDeployment(this, 'DeployWithInvalidation', {
|
|
337
|
+
sources: [s3deploy.Source.asset('./website-dist')],
|
|
338
|
+
destinationBucket: bucket,
|
|
339
|
+
distribution,
|
|
340
|
+
distributionPaths: ['/images/*.png'],
|
|
341
|
+
// Invalidate cache but don't wait or verify that invalidation has completed successfully.
|
|
342
|
+
waitForDistributionInvalidation: false
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
328
346
|
## Signed Content Payloads
|
|
329
347
|
|
|
330
348
|
By default, deployment uses streaming uploads which set the `x-amz-content-sha256`
|
|
@@ -121,6 +121,7 @@ declare const fn: lambda.Function;
|
|
|
121
121
|
|
|
122
122
|
// Lambda should receive only message matching the following conditions on message body:
|
|
123
123
|
// color: 'red' or 'orange'
|
|
124
|
+
// store: property must not be present
|
|
124
125
|
myTopic.addSubscription(new subscriptions.LambdaSubscription(fn, {
|
|
125
126
|
filterPolicyWithMessageBody: {
|
|
126
127
|
background: sns.FilterOrPolicy.policy({
|
|
@@ -128,6 +129,7 @@ myTopic.addSubscription(new subscriptions.LambdaSubscription(fn, {
|
|
|
128
129
|
allowlist: ['red', 'orange'],
|
|
129
130
|
})),
|
|
130
131
|
}),
|
|
132
|
+
store: sns.FilterOrPolicy.filter(sns.SubscriptionFilter.notExistsFilter()),
|
|
131
133
|
},
|
|
132
134
|
}));
|
|
133
135
|
```
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as sns from 'aws-cdk-lib/aws-sns';
|
|
2
|
+
import * as sqs from 'aws-cdk-lib/aws-sqs';
|
|
3
|
+
import * as cdk from 'aws-cdk-lib';
|
|
4
|
+
import { IntegTest, ExpectedResult } from '@aws-cdk/integ-tests-alpha';
|
|
5
|
+
import * as subs from 'aws-cdk-lib/aws-sns-subscriptions';
|
|
6
|
+
|
|
7
|
+
const app = new cdk.App();
|
|
8
|
+
|
|
9
|
+
const stack = new cdk.Stack(app, 'sns-sqs-subscription-filter');
|
|
10
|
+
|
|
11
|
+
const topic = new sns.Topic(stack, 'MyTopic');
|
|
12
|
+
|
|
13
|
+
const queue1 = new sqs.Queue(stack, 'MyQueue1');
|
|
14
|
+
const queue2 = new sqs.Queue(stack, 'MyQueue2');
|
|
15
|
+
|
|
16
|
+
topic.addSubscription(new subs.SqsSubscription(queue1, {
|
|
17
|
+
filterPolicyWithMessageBody: {
|
|
18
|
+
background: sns.Policy.policy({
|
|
19
|
+
color: sns.Filter.filter(sns.SubscriptionFilter.stringFilter({
|
|
20
|
+
allowlist: ['red', 'green'],
|
|
21
|
+
})),
|
|
22
|
+
}),
|
|
23
|
+
price: sns.Filter.filter(sns.SubscriptionFilter.numericFilter({
|
|
24
|
+
allowlist: [100, 200],
|
|
25
|
+
})),
|
|
26
|
+
store: sns.Filter.filter(sns.SubscriptionFilter.existsFilter()),
|
|
27
|
+
},
|
|
28
|
+
rawMessageDelivery: true,
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
topic.addSubscription(new subs.SqsSubscription(queue2, {
|
|
32
|
+
filterPolicyWithMessageBody: {
|
|
33
|
+
background: sns.Policy.policy({
|
|
34
|
+
color: sns.Filter.filter(sns.SubscriptionFilter.stringFilter({
|
|
35
|
+
denylist: ['red', 'green'],
|
|
36
|
+
})),
|
|
37
|
+
}),
|
|
38
|
+
price: sns.Filter.filter(sns.SubscriptionFilter.numericFilter({
|
|
39
|
+
betweenStrict: { start: 100, stop: 200 },
|
|
40
|
+
})),
|
|
41
|
+
store: sns.Filter.filter(sns.SubscriptionFilter.notExistsFilter()),
|
|
42
|
+
},
|
|
43
|
+
rawMessageDelivery: true,
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
const integTest = new IntegTest(app, 'SNS Subscription filters', {
|
|
47
|
+
testCases: [stack],
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const message1 = JSON.stringify({ background: { color: 'green' }, price: 200, store: 'fans' }); // matches queue1 subscription filter
|
|
51
|
+
const message2 = JSON.stringify({ background: { color: 'blue' }, price: 150 }); // matches queue2 subscription filter
|
|
52
|
+
|
|
53
|
+
// publish messages to SNS topic
|
|
54
|
+
integTest.assertions.awsApiCall('SNS', 'publish', {
|
|
55
|
+
Message: message1,
|
|
56
|
+
TopicArn: topic.topicArn,
|
|
57
|
+
});
|
|
58
|
+
integTest.assertions.awsApiCall('SNS', 'publish', {
|
|
59
|
+
Message: message2,
|
|
60
|
+
TopicArn: topic.topicArn,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// check messages arrived at expected destination queue
|
|
64
|
+
integTest.assertions.awsApiCall('SQS', 'receiveMessage', {
|
|
65
|
+
QueueUrl: queue1.queueUrl,
|
|
66
|
+
WaitTimeSeconds: 20,
|
|
67
|
+
}).expect(ExpectedResult.objectLike({
|
|
68
|
+
Messages: [{ Body: message1 }],
|
|
69
|
+
}));
|
|
70
|
+
integTest.assertions.awsApiCall('SQS', 'receiveMessage', {
|
|
71
|
+
QueueUrl: queue2.queueUrl,
|
|
72
|
+
WaitTimeSeconds: 20,
|
|
73
|
+
}).expect(ExpectedResult.objectLike({
|
|
74
|
+
Messages: [{ Body: message2 }],
|
|
75
|
+
}));
|
cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-sns-subscriptions/integ.sns-sqs.ts
CHANGED
|
@@ -3,50 +3,31 @@ import * as sqs from 'aws-cdk-lib/aws-sqs';
|
|
|
3
3
|
import * as cdk from 'aws-cdk-lib';
|
|
4
4
|
import { IntegTest, ExpectedResult } from '@aws-cdk/integ-tests-alpha';
|
|
5
5
|
import * as subs from 'aws-cdk-lib/aws-sns-subscriptions';
|
|
6
|
-
|
|
7
|
-
topic: sns.Topic;
|
|
8
|
-
queue: sqs.Queue;
|
|
9
|
-
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
|
|
10
|
-
super(scope, id, props);
|
|
11
|
-
this.topic = new sns.Topic(this, 'MyTopic');
|
|
12
|
-
const queueStack = new cdk.Stack(app, 'QueueStack');
|
|
13
|
-
this.queue = new sqs.Queue(queueStack, 'MyQueue');
|
|
14
|
-
this.topic.addSubscription(new subs.SqsSubscription(this.queue, {
|
|
15
|
-
filterPolicyWithMessageBody: {
|
|
16
|
-
background: sns.Policy.policy({
|
|
17
|
-
color: sns.Filter.filter(sns.SubscriptionFilter.stringFilter({
|
|
18
|
-
allowlist: ['red', 'green'],
|
|
19
|
-
denylist: ['white', 'orange'],
|
|
20
|
-
})),
|
|
21
|
-
}),
|
|
22
|
-
price: sns.Filter.filter(sns.SubscriptionFilter.numericFilter({
|
|
23
|
-
allowlist: [100, 200],
|
|
24
|
-
between: { start: 300, stop: 350 },
|
|
25
|
-
greaterThan: 500,
|
|
26
|
-
lessThan: 1000,
|
|
27
|
-
betweenStrict: { start: 2000, stop: 3000 },
|
|
28
|
-
})),
|
|
29
|
-
},
|
|
30
|
-
}));
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
// Beginning of the test suite
|
|
6
|
+
|
|
34
7
|
const app = new cdk.App();
|
|
35
|
-
|
|
8
|
+
|
|
9
|
+
const stack = new cdk.Stack(app, 'SnsToSqsStack');
|
|
10
|
+
|
|
11
|
+
const topic = new sns.Topic(stack, 'MyTopic');
|
|
12
|
+
|
|
13
|
+
const queue = new sqs.Queue(stack, 'MyQueue');
|
|
14
|
+
|
|
15
|
+
topic.addSubscription(new subs.SqsSubscription(queue, { rawMessageDelivery: true }));
|
|
16
|
+
|
|
36
17
|
const integTest = new IntegTest(app, 'SNS Subscriptions', {
|
|
37
|
-
testCases: [
|
|
38
|
-
stack,
|
|
39
|
-
],
|
|
18
|
+
testCases: [stack],
|
|
40
19
|
});
|
|
20
|
+
|
|
21
|
+
const message = JSON.stringify({ color: 'green', price: 200 });
|
|
22
|
+
|
|
41
23
|
integTest.assertions.awsApiCall('SNS', 'publish', {
|
|
42
|
-
Message:
|
|
43
|
-
TopicArn:
|
|
24
|
+
Message: message,
|
|
25
|
+
TopicArn: topic.topicArn,
|
|
44
26
|
});
|
|
45
|
-
|
|
46
|
-
|
|
27
|
+
|
|
28
|
+
integTest.assertions.awsApiCall('SQS', 'receiveMessage', {
|
|
29
|
+
QueueUrl: queue.queueUrl,
|
|
47
30
|
WaitTimeSeconds: 20,
|
|
48
|
-
})
|
|
49
|
-
message
|
|
50
|
-
Messages: [{ Body: '{color: "green", price: 200}' }],
|
|
31
|
+
}).expect(ExpectedResult.objectLike({
|
|
32
|
+
Messages: [{ Body: message }],
|
|
51
33
|
}));
|
|
52
|
-
app.synth();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { App, Stack, StackProps } from 'aws-cdk-lib';
|
|
2
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
3
|
+
import { Construct } from 'constructs';
|
|
4
|
+
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
|
|
5
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
6
|
+
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
|
|
7
|
+
|
|
8
|
+
class TestStack extends Stack {
|
|
9
|
+
constructor(scope: Construct, id: string, props?: StackProps) {
|
|
10
|
+
super(scope, id, props);
|
|
11
|
+
|
|
12
|
+
const task = new tasks.EvaluateExpression(this, 'Task', {
|
|
13
|
+
expression: '$.a + $.b',
|
|
14
|
+
runtime: lambda.Runtime.NODEJS_22_X,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
new sfn.StateMachine(this, 'StateMachine', {
|
|
18
|
+
definition: task,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const app = new App();
|
|
24
|
+
|
|
25
|
+
new integ.IntegTest(app, 'EvaluateExpressionNodejs22', {
|
|
26
|
+
testCases: [new TestStack(app, 'evaluate-expression-nodejs22')],
|
|
27
|
+
});
|