konokenj.cdk-api-mcp-server 0.40.0__py3-none-any.whl → 0.42.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 (47) hide show
  1. cdk_api_mcp_server/__about__.py +1 -1
  2. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-bedrock-alpha/README.md +540 -0
  3. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-eks-v2-alpha/README.md +44 -46
  4. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-lambda-python-alpha/README.md +6 -6
  5. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-s3tables-alpha/README.md +28 -1
  6. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/README.md/README.md +364 -16
  7. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/README.md +144 -0
  8. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api-dualstack.ts +3 -4
  9. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api.ts +2 -4
  10. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.stage.ts +7 -20
  11. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.usage-plan.ts +80 -0
  12. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-authorizers/integ.iam.ts +34 -38
  13. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.sqs.ts +58 -71
  14. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codepipeline-actions/integ.pipeline-elastic-beanstalk-deploy.ts +1 -1
  15. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cognito/README.md +11 -0
  16. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cognito/integ.user-pool-client-explicit-props.ts +1 -0
  17. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/README.md +38 -13
  18. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb-v2.cci.ts +49 -0
  19. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb.cci.ts +27 -0
  20. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb.contirubtor-insights-for-gsi.ts +6 -2
  21. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.table-v2-global.ts +9 -3
  22. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/README.md +3 -0
  23. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.ebs-volume-initialization-rate.ts +80 -0
  24. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs-patterns/README.md +2 -0
  25. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs-patterns/integ.alb-fargate-service-smart-defaults.ts +143 -0
  26. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events/README.md +25 -3
  27. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events/integ.archive-customer-managed-key.ts +23 -0
  28. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/README.md +2 -2
  29. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-route53/integ.delete-existing-record-set.ts +0 -1
  30. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/README.md +18 -0
  31. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-cross-stack-ssm-source.ts +91 -0
  32. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-signer/integ.signing-profile.ts +5 -0
  33. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-sns/README.md +2 -0
  34. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-sns-subscriptions/integ.sns-sqs-subscription-filter.ts +75 -0
  35. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-sns-subscriptions/integ.sns-sqs.ts +21 -40
  36. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/README.md +9 -3
  37. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke-jsonata.ts +87 -80
  38. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke.ts +87 -69
  39. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.start-job-run.ts +102 -104
  40. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/core/README.md +2 -1893
  41. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +52 -0
  42. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/README.md +24 -1
  43. {konokenj_cdk_api_mcp_server-0.40.0.dist-info → konokenj_cdk_api_mcp_server-0.42.0.dist-info}/METADATA +2 -2
  44. {konokenj_cdk_api_mcp_server-0.40.0.dist-info → konokenj_cdk_api_mcp_server-0.42.0.dist-info}/RECORD +47 -39
  45. {konokenj_cdk_api_mcp_server-0.40.0.dist-info → konokenj_cdk_api_mcp_server-0.42.0.dist-info}/WHEEL +0 -0
  46. {konokenj_cdk_api_mcp_server-0.40.0.dist-info → konokenj_cdk_api_mcp_server-0.42.0.dist-info}/entry_points.txt +0 -0
  47. {konokenj_cdk_api_mcp_server-0.40.0.dist-info → konokenj_cdk_api_mcp_server-0.42.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -19,7 +19,9 @@ class TestStack extends Stack {
19
19
  writeCapacity: Capacity.autoscaled({ maxCapacity: 20, targetUtilizationPercent: 60, seedCapacity: 10 }),
20
20
  }),
21
21
  encryption: TableEncryptionV2.awsManagedKey(),
22
- contributorInsights: true,
22
+ contributorInsightsSpecification: {
23
+ enabled: true,
24
+ },
23
25
  pointInTimeRecovery: true,
24
26
  tableClass: TableClass.STANDARD_INFREQUENT_ACCESS,
25
27
  timeToLiveAttribute: 'attr',
@@ -49,7 +51,9 @@ class TestStack extends Stack {
49
51
  readCapacity: Capacity.autoscaled({ minCapacity: 5, maxCapacity: 25 }),
50
52
  globalSecondaryIndexOptions: {
51
53
  gsi2: {
52
- contributorInsights: false,
54
+ contributorInsightsSpecification: {
55
+ enabled: false,
56
+ },
53
57
  },
54
58
  },
55
59
  tags: [{ key: 'USE2ReplicaTagKey', value: 'USE2ReplicaTagValue' }],
@@ -57,7 +61,9 @@ class TestStack extends Stack {
57
61
  {
58
62
  region: 'us-west-2',
59
63
  tableClass: TableClass.STANDARD,
60
- contributorInsights: false,
64
+ contributorInsightsSpecification: {
65
+ enabled: false,
66
+ },
61
67
  globalSecondaryIndexOptions: {
62
68
  gsi1: {
63
69
  readCapacity: Capacity.fixed(15),
@@ -1970,6 +1970,9 @@ const volumeFromSnapshot = new ecs.ServiceManagedVolume(this, 'EBSVolume', {
1970
1970
  snapShotId: 'snap-066877671789bd71b',
1971
1971
  volumeType: ec2.EbsDeviceVolumeType.GP3,
1972
1972
  fileSystemType: ecs.FileSystemType.XFS,
1973
+ // Specifies the Amazon EBS Provisioned Rate for Volume Initialization.
1974
+ // Valid range is between 100 and 300 MiB/s.
1975
+ volumeInitializationRate: Size.mebibytes(200),
1973
1976
  },
1974
1977
  });
1975
1978
 
@@ -0,0 +1,80 @@
1
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
2
+ import * as cdk from 'aws-cdk-lib';
3
+ import * as ecs from 'aws-cdk-lib/aws-ecs';
4
+ import * as integ from '@aws-cdk/integ-tests-alpha';
5
+ import { Construct } from 'constructs';
6
+
7
+ /*
8
+ * This integration test demonstrates how to use EBS volume initialization rate
9
+ * with Service Managed Volumes.
10
+ *
11
+ * To run this test with a real EBS snapshot:
12
+ * 1. Create an EBS volume:
13
+ * aws ec2 create-volume --size 1 --volume-type gp3 --availability-zone us-east-1a
14
+ * 2. Create a snapshot from the volume:
15
+ * aws ec2 create-snapshot --volume-id vol-xxxxxxxxx --description "Test snapshot"
16
+ * 3. Wait for snapshot completion:
17
+ * aws ec2 wait snapshot-completed --snapshot-ids snap-xxxxxxxxx
18
+ * 4. Set the environment variable SNAPSHOT_ID to the snapshot ID:
19
+ * export SNAPSHOT_ID=snap-xxxxxxxxx
20
+ */
21
+
22
+ const snapShotId = process.env.SNAPSHOT_ID ?? 'snap-123456789abcdef0';
23
+
24
+ class TestStack extends cdk.Stack {
25
+ constructor(scope: Construct, id: string) {
26
+ super(scope, id);
27
+
28
+ const vpc = new ec2.Vpc(this, 'Vpc', {
29
+ maxAzs: 1,
30
+ restrictDefaultSecurityGroup: false,
31
+ });
32
+
33
+ const cluster = new ecs.Cluster(this, 'FargateCluster', {
34
+ vpc,
35
+ });
36
+
37
+ const taskDefinition = new ecs.FargateTaskDefinition(this, 'TaskDef');
38
+
39
+ const container = taskDefinition.addContainer('web', {
40
+ image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
41
+ portMappings: [{
42
+ containerPort: 80,
43
+ protocol: ecs.Protocol.TCP,
44
+ }],
45
+ });
46
+
47
+ const volume = new ecs.ServiceManagedVolume(this, 'EBSVolume', {
48
+ name: 'ebs1',
49
+ managedEBSVolume: {
50
+ volumeType: ec2.EbsDeviceVolumeType.GP3,
51
+ size: cdk.Size.gibibytes(1),
52
+ fileSystemType: ecs.FileSystemType.EXT4,
53
+ volumeInitializationRate: cdk.Size.mebibytes(200),
54
+ snapShotId: snapShotId,
55
+ },
56
+ });
57
+
58
+ volume.mountIn(container, {
59
+ containerPath: '/var/lib',
60
+ readOnly: false,
61
+ });
62
+
63
+ taskDefinition.addVolume(volume);
64
+
65
+ const service = new ecs.FargateService(this, 'FargateService', {
66
+ cluster,
67
+ taskDefinition,
68
+ desiredCount: 1,
69
+ });
70
+
71
+ service.addVolume(volume);
72
+ }
73
+ }
74
+
75
+ const app = new cdk.App();
76
+ const stack = new TestStack(app, 'integ-aws-ecs-ebs-volume-initialization-rate');
77
+
78
+ new integ.IntegTest(app, 'EBSVolumeInitializationRate', {
79
+ testCases: [stack],
80
+ });
@@ -70,6 +70,8 @@ Fargate services will use the `LATEST` platform version by default, but you can
70
70
 
71
71
  Fargate services use the default VPC Security Group unless one or more are provided using the `securityGroups` property in the constructor.
72
72
 
73
+ **Security Considerations**: When using custom security groups on your load balancer, the `openListener` property controls whether the load balancer listener allows traffic from anywhere on the internet (0.0.0.0/0). By default, `openListener` is `true`, but it will automatically default to `false` when custom security groups are detected, preventing unintended internet exposure. You can always explicitly set `openListener: true` to override this behavior if needed.
74
+
73
75
  By setting `redirectHTTP` to true, CDK will automatically create a listener on port 80 that redirects HTTP traffic to the HTTPS port.
74
76
 
75
77
  If you specify the option `recordType` you can decide if you want the construct to use CNAME or Route53-Aliases as record sets.
@@ -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
- **Note**: Archives and schema discovery are not supported for event buses encrypted using a customer managed key.
336
- To enable archives or schema discovery on an event bus, choose to use an AWS owned key.
337
- 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).
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
+ });
@@ -1177,7 +1177,7 @@ const version = fn.currentVersion;
1177
1177
  You can use Application AutoScaling to automatically configure the provisioned concurrency for your functions. AutoScaling can be set to track utilization or be based on a schedule. To configure AutoScaling on a function alias:
1178
1178
 
1179
1179
  ```ts
1180
- import * as autoscaling from 'aws-cdk-lib/aws-autoscaling';
1180
+ import * as appscaling from 'aws-cdk-lib/aws-applicationautoscaling';
1181
1181
 
1182
1182
  declare const fn: lambda.Function;
1183
1183
  const alias = fn.addAlias('prod');
@@ -1192,7 +1192,7 @@ as.scaleOnUtilization({
1192
1192
 
1193
1193
  // Configure Scheduled Scaling
1194
1194
  as.scaleOnSchedule('ScaleUpInTheMorning', {
1195
- schedule: autoscaling.Schedule.cron({ hour: '8', minute: '0'}),
1195
+ schedule: appscaling.Schedule.cron({ hour: '8', minute: '0'}),
1196
1196
  minCapacity: 20,
1197
1197
  });
1198
1198
  ```
@@ -23,7 +23,6 @@ class TestStack extends Stack {
23
23
  ttl: Duration.hours(2),
24
24
  zone: hostedZone,
25
25
  recordName: 'integ',
26
- deleteExisting: true,
27
26
  });
28
27
  newRecord.node.addDependency(existingRecord);
29
28
  }
@@ -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`
@@ -0,0 +1,91 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import { Construct } from 'constructs';
3
+ import * as s3 from 'aws-cdk-lib/aws-s3';
4
+ import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
5
+ import * as ssm from 'aws-cdk-lib/aws-ssm';
6
+ import * as integ from '@aws-cdk/integ-tests-alpha';
7
+
8
+ class SsmStack extends cdk.NestedStack {
9
+ public readonly ssmParam: ssm.StringListParameter;
10
+
11
+ constructor(scope: Construct, id: string, props?: cdk.NestedStackProps) {
12
+ super(scope, id, props);
13
+
14
+ const testSubnets = ['subnet-12345', 'subnet-67890'];
15
+
16
+ this.ssmParam = new ssm.StringListParameter(this, 'TestParam', {
17
+ parameterName: '/repro/subnets',
18
+ stringListValue: testSubnets,
19
+ description: 'Test parameter for reproduction',
20
+ });
21
+ }
22
+ }
23
+
24
+ class S3Stack extends cdk.NestedStack {
25
+ public readonly bucket: s3.Bucket;
26
+
27
+ constructor(scope: Construct, id: string, props?: cdk.NestedStackProps) {
28
+ super(scope, id, props);
29
+
30
+ const readParam = ssm.StringListParameter.fromStringListParameterName(
31
+ this,
32
+ 'ReadParam',
33
+ '/repro/subnets',
34
+ );
35
+
36
+ this.bucket = new s3.Bucket(this, 'ReproBucket', {
37
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
38
+ autoDeleteObjects: true,
39
+ });
40
+
41
+ new s3deploy.BucketDeployment(this, 'ReproDeployment', {
42
+ sources: [
43
+ s3deploy.Source.jsonData('config.json', {
44
+ subnets: readParam.stringListValue,
45
+ expectedValues: ['subnet-12345', 'subnet-67890'],
46
+ version: '2.207.0',
47
+ issue: 'StringListParameter tokens not resolved in Source.jsonData',
48
+ timestamp: new Date().toISOString(),
49
+ }),
50
+ ],
51
+ destinationBucket: this.bucket,
52
+ });
53
+ }
54
+ }
55
+
56
+ export class MainStack extends cdk.Stack {
57
+ constructor(scope: Construct, id: string, props?: cdk.StackProps) {
58
+ super(scope, id, props);
59
+
60
+ const ssmStack = new SsmStack(this, 'SsmStack');
61
+ const s3Stack = new S3Stack(this, 'S3Stack');
62
+ s3Stack.addDependency(ssmStack);
63
+
64
+ new cdk.CfnOutput(this, 'BucketName', {
65
+ value: s3Stack.bucket.bucketName,
66
+ description: 'Check config.json in this bucket',
67
+ });
68
+
69
+ new cdk.CfnOutput(this, 'ParameterName', {
70
+ value: ssmStack.ssmParam.parameterName,
71
+ description: 'SSM parameter name',
72
+ });
73
+
74
+ new cdk.CfnOutput(this, 'ExpectedValues', {
75
+ value: JSON.stringify(['subnet-12345', 'subnet-67890']),
76
+ description: 'Expected subnet values in config.json',
77
+ });
78
+
79
+ new cdk.CfnOutput(this, 'VerificationCommand', {
80
+ value: `aws s3 cp s3://${s3Stack.bucket.bucketName}/config.json - | jq .`,
81
+ description: 'Command to check the deployed JSON',
82
+ });
83
+ }
84
+ }
85
+
86
+ const app = new cdk.App();
87
+ const stack = new MainStack(app, 'integ-bucket-deployment-cross-stack-ssm');
88
+
89
+ new integ.IntegTest(app, 'integ-bucket-deployment-cross-stack-ssm-source', {
90
+ testCases: [stack],
91
+ });
@@ -16,6 +16,11 @@ new signer.SigningProfile(stack, 'SigningProfileOCI', {
16
16
  signatureValidity: cdk.Duration.days(60),
17
17
  });
18
18
 
19
+ new signer.SigningProfile(stack, 'SigningProfileWithName', {
20
+ platform: signer.Platform.AWS_LAMBDA_SHA384_ECDSA,
21
+ signingProfileName: 'test-signing-profile-name',
22
+ });
23
+
19
24
  new IntegTest(app, 'cdk-integ-signer-signing-profile', {
20
25
  testCases: [stack],
21
26
  });
@@ -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
+ }));
@@ -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
- class SnsToSqsStack extends cdk.Stack {
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
- const stack = new SnsToSqsStack(app, 'SnsToSqsStack');
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: '{ background: { color: \'green\' }, price: 200 }',
43
- TopicArn: stack.topic.topicArn,
24
+ Message: message,
25
+ TopicArn: topic.topicArn,
44
26
  });
45
- const message = integTest.assertions.awsApiCall('SQS', 'receiveMessage', {
46
- QueueUrl: stack.queue.queueUrl,
27
+
28
+ integTest.assertions.awsApiCall('SQS', 'receiveMessage', {
29
+ QueueUrl: queue.queueUrl,
47
30
  WaitTimeSeconds: 20,
48
- });
49
- message.expect(ExpectedResult.objectLike({
50
- Messages: [{ Body: '{color: "green", price: 200}' }],
31
+ }).expect(ExpectedResult.objectLike({
32
+ Messages: [{ Body: message }],
51
33
  }));
52
- app.synth();