konokenj.cdk-api-mcp-server 0.49.0__py3-none-any.whl → 0.51.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 (68) hide show
  1. cdk_api_mcp_server/__about__.py +1 -1
  2. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-bedrock-agentcore-alpha/README.md +796 -0
  3. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-eks-v2-alpha/README.md +116 -29
  4. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-msk-alpha/README.md +38 -8
  5. cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/mixins-preview/README.md +16 -0
  6. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigateway/integ.api-with-authorizer-and-proxy.ts +1 -1
  7. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigateway/integ.lambda-api.ts +1 -1
  8. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-authorizers/integ.iam.ts +1 -1
  9. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-authorizers/integ.lambda.ts +2 -2
  10. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-authorizers/integ.user-pool.ts +1 -1
  11. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.add-subroute-integration.ts +7 -4
  12. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.http-proxy.ts +1 -1
  13. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.lambda-proxy.ts +1 -1
  14. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.lambda.ts +4 -4
  15. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-appsync/integ.graphql-lambda-permission.ts +1 -1
  16. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-appsync/integ.js-resolver.ts +1 -1
  17. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudformation/integ.core-custom-resources-node-18.ts +1 -1
  18. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudformation/integ.core-custom-resources-service-timeout.ts +1 -1
  19. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudfront-origins/integ.origin-response-completion-timeout.ts +1 -1
  20. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudtrail/integ.cloudtrail-data-events-only.ts +1 -1
  21. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codepipeline-actions/integ.pipeline-elastic-beanstalk-deploy.ts +4 -1
  22. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/README.md +53 -0
  23. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb.add-to-resource-policy.ts +80 -0
  24. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb.policy.ts +21 -1
  25. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ec2/integ.vpc-flow-logs.ts +4 -0
  26. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecr/README.md +40 -1
  27. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecr/integ.tag-mutability-exclusion.ts +30 -0
  28. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/README.md +3 -0
  29. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.managedinstances-capacity-provider.ts +5 -3
  30. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.managedinstances-no-default-capacity-provider.ts +107 -0
  31. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs-patterns/integ.alb-fargate-service-public-private-switch.ts +45 -0
  32. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-elasticloadbalancingv2/README.md +34 -4
  33. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-elasticloadbalancingv2/integ.alb-lambda-multi-value-headers.ts +1 -1
  34. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-elasticloadbalancingv2/integ.alb.oidc.ts +1 -1
  35. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-elasticloadbalancingv2/integ.nlb.security-group.ts +70 -0
  36. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-elasticloadbalancingv2-actions/integ.cognito.ts +1 -1
  37. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events-targets/README.md +22 -0
  38. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events-targets/integ.firehose-delivery-stream.ts +51 -0
  39. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/README.md +96 -0
  40. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/integ.record-format-conversion-schema.ts +154 -0
  41. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/integ.record-format-conversion.ts +178 -0
  42. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.binary-payload.ts +1 -1
  43. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.logging-config.ts +8 -8
  44. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.params-and-secrets.ts +1 -1
  45. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.runtime-management.ts +1 -1
  46. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.runtime.inlinecode.ts +0 -7
  47. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda-nodejs/integ.dependencies-pnpm.ts +1 -1
  48. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda-nodejs/integ.function-exclude-smithy-models.ts +2 -2
  49. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda-nodejs/integ.nodejs.build.images.ts +1 -1
  50. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-logs/integ.subscriptionfilter.ts +1 -1
  51. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.cluster-data-api-to-imported-cluster.ts +1 -1
  52. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.cluster-data-api.ts +1 -1
  53. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-data.ts +4 -0
  54. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/README.md +1 -1
  55. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.call-aws-service-cross-region-lambda.ts +1 -1
  56. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke-json-path.ts +102 -0
  57. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary.ts +2 -0
  58. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/custom-resources/integ.aws-custom-resource.ts +1 -1
  59. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/custom-resources/integ.custom-resource-config-lambda-node-runtime.ts +1 -1
  60. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/custom-resources/integ.invoke-function-payload.ts +1 -1
  61. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +62 -1
  62. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/README.md +32 -1
  63. {konokenj_cdk_api_mcp_server-0.49.0.dist-info → konokenj_cdk_api_mcp_server-0.51.0.dist-info}/METADATA +2 -2
  64. {konokenj_cdk_api_mcp_server-0.49.0.dist-info → konokenj_cdk_api_mcp_server-0.51.0.dist-info}/RECORD +67 -57
  65. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events-targets/integ.kinesis-firehose-stream.ts +0 -33
  66. {konokenj_cdk_api_mcp_server-0.49.0.dist-info → konokenj_cdk_api_mcp_server-0.51.0.dist-info}/WHEEL +0 -0
  67. {konokenj_cdk_api_mcp_server-0.49.0.dist-info → konokenj_cdk_api_mcp_server-0.51.0.dist-info}/entry_points.txt +0 -0
  68. {konokenj_cdk_api_mcp_server-0.49.0.dist-info → konokenj_cdk_api_mcp_server-0.51.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Integration test for DynamoDB Table.addToResourcePolicy() method
3
+ *
4
+ * This test validates the fix for issue #35062: "(aws-dynamodb): `addToResourcePolicy` has no effect"
5
+ *
6
+ * WHAT WE'RE TESTING:
7
+ * - The addToResourcePolicy() method was broken - it had "no effect" when called
8
+ * - Resource policies weren't being added to the CloudFormation template
9
+ * - This created a security gap where developers thought they were securing tables but policies weren't applied
10
+ *
11
+ * TEST VALIDATION:
12
+ * 1. Creates DynamoDB tables with different resource policy configurations
13
+ * 2. Tests both wildcard resources (for auto-generated names) and scoped resources (for explicit names)
14
+ * 3. Verifies policies get added to CloudFormation templates with correct structure
15
+ * 4. Ensures both patterns work without circular dependencies
16
+ *
17
+ * @see https://github.com/aws/aws-cdk/issues/35062
18
+ */
19
+
20
+ import { App, Fn, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib';
21
+ import { Construct } from 'constructs';
22
+ import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
23
+ import * as iam from 'aws-cdk-lib/aws-iam';
24
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
25
+
26
+ export class TestStack extends Stack {
27
+ public readonly wildcardTable: dynamodb.Table;
28
+ public readonly scopedTable: dynamodb.Table;
29
+
30
+ constructor(scope: Construct, id: string, props?: StackProps) {
31
+ super(scope, id, props);
32
+
33
+ // TEST 1: Table with wildcard resource policy (auto-generated name)
34
+ // This is the standard pattern to avoid circular dependencies
35
+ this.wildcardTable = new dynamodb.Table(this, 'WildcardTable', {
36
+ partitionKey: {
37
+ name: 'id',
38
+ type: dynamodb.AttributeType.STRING,
39
+ },
40
+ removalPolicy: RemovalPolicy.DESTROY,
41
+ });
42
+
43
+ // Add resource policy with wildcard resources
44
+ this.wildcardTable.addToResourcePolicy(new iam.PolicyStatement({
45
+ actions: ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:Query'],
46
+ principals: [new iam.AccountRootPrincipal()],
47
+ resources: ['*'], // Use wildcard to avoid circular dependency - standard pattern for resource policies
48
+ }));
49
+
50
+ // TEST 2: Table with scoped resource policy (explicit table name)
51
+ // This demonstrates how to use scoped resources when table name is known at synthesis time
52
+ this.scopedTable = new dynamodb.Table(this, 'ScopedTable', {
53
+ tableName: 'my-explicit-scoped-table', // Explicit name enables scoped ARN construction
54
+ partitionKey: {
55
+ name: 'id',
56
+ type: dynamodb.AttributeType.STRING,
57
+ },
58
+ removalPolicy: RemovalPolicy.DESTROY,
59
+ });
60
+
61
+ // Add resource policy with properly scoped resource using explicit table name
62
+ // This works because table name is known at synthesis time (no circular dependency)
63
+ this.scopedTable.addToResourcePolicy(new iam.PolicyStatement({
64
+ actions: ['dynamodb:GetItem', 'dynamodb:Query'],
65
+ principals: [new iam.AccountRootPrincipal()],
66
+ // Use CloudFormation intrinsic function to construct table ARN with known table name
67
+ resources: [Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-scoped-table')],
68
+ }));
69
+ }
70
+ }
71
+
72
+ // Test Setup
73
+ const app = new App();
74
+ const stack = new TestStack(app, 'add-to-resource-policy-test-stack');
75
+
76
+ // Integration Test Configuration
77
+ new IntegTest(app, 'add-to-resource-policy-integ-test', {
78
+ testCases: [stack],
79
+ });
80
+
@@ -38,7 +38,27 @@ export class TestStack extends Stack {
38
38
  removalPolicy: RemovalPolicy.DESTROY,
39
39
  });
40
40
 
41
- this.tableTwo.grantReadData(new iam.AccountPrincipal('123456789012'));
41
+ // IMPORTANT: Cross-account grants with auto-generated table names create circular dependencies
42
+ //
43
+ // WHY NOT this.tableTwo.grantReadData(new iam.AccountPrincipal('123456789012'))?
44
+ // - Cross-account principals cannot have policies attached to them
45
+ // - Grant falls back to adding a resource policy to the table
46
+ // - Resource policy tries to reference this.tableArn (the table's own ARN)
47
+ // - This creates a circular dependency: Table → ResourcePolicy → Table ARN → Table
48
+ // - CloudFormation fails with "Circular dependency between resources"
49
+ //
50
+ // SOLUTIONS:
51
+ // 1. Use addToResourcePolicy with wildcard resources (this approach)
52
+ // 2. Use explicit table names: tableName: 'my-table-name' (enables scoped resources)
53
+ // 3. Use same-account principals (grants go to principal policy, not resource policy)
54
+ //
55
+ this.tableTwo.addToResourcePolicy(new iam.PolicyStatement({
56
+ actions: ['dynamodb:*'],
57
+ // we need a valid account for cross-account principal otherwise it won't deploy
58
+ // this account is from fact-table.ts
59
+ principals: [new iam.AccountPrincipal('127311923021')],
60
+ resources: ['*'], // Wildcard avoids circular dependency - same pattern as KMS
61
+ }));
42
62
  }
43
63
  }
44
64
 
@@ -72,6 +72,10 @@ class TestStack extends Stack {
72
72
  destination: FlowLogDestination.toS3(),
73
73
  });
74
74
 
75
+ vpc.addFlowLog('FlowLogsCloudwatch', {
76
+ destination: FlowLogDestination.toCloudWatchLogs(),
77
+ });
78
+
75
79
  const bucket = new s3.Bucket(this, 'Bucket', {
76
80
  removalPolicy: RemovalPolicy.DESTROY,
77
81
  autoDeleteObjects: true,
@@ -121,12 +121,51 @@ By using these methods, you can grant specific operational permissions on the EC
121
121
 
122
122
  ### Image tag immutability
123
123
 
124
- You can set tag immutability on images in our repository using the `imageTagMutability` construct prop.
124
+ You can set tag immutability on images in your repository using the `imageTagMutability` construct prop.
125
125
 
126
126
  ```ts
127
127
  new ecr.Repository(this, 'Repo', { imageTagMutability: ecr.TagMutability.IMMUTABLE });
128
128
  ```
129
129
 
130
+ #### Image tag mutability with exclusion filters
131
+
132
+ ECR supports more granular control over image tag mutability by allowing you to specify exclusion filters. This enables you to make your repository immutable while allowing specific tag patterns to remain mutable (or vice versa).
133
+
134
+ There are two new mutability options that work with exclusion filters:
135
+
136
+ - `MUTABLE_WITH_EXCLUSION`: Tags are mutable by default, except those matching the exclusion filters
137
+ - `IMMUTABLE_WITH_EXCLUSION`: Tags are immutable by default, except those matching the exclusion filters
138
+
139
+ Use `ImageTagMutabilityExclusionFilter.wildcard()` to create filters with wildcard patterns:
140
+
141
+ ```ts
142
+ // Make all tags immutable except for those starting with 'dev-' or 'test-'
143
+ new ecr.Repository(this, 'Repo', {
144
+ imageTagMutability: ecr.TagMutability.IMMUTABLE_WITH_EXCLUSION,
145
+ imageTagMutabilityExclusionFilters: [
146
+ ecr.ImageTagMutabilityExclusionFilter.wildcard('dev-*'),
147
+ ecr.ImageTagMutabilityExclusionFilter.wildcard('test-*'),
148
+ ],
149
+ });
150
+ ```
151
+
152
+ ```ts
153
+ // Make all tags mutable except for production releases
154
+ new ecr.Repository(this, 'Repo', {
155
+ imageTagMutability: ecr.TagMutability.MUTABLE_WITH_EXCLUSION,
156
+ imageTagMutabilityExclusionFilters: [
157
+ ecr.ImageTagMutabilityExclusionFilter.wildcard('prod-*'),
158
+ ecr.ImageTagMutabilityExclusionFilter.wildcard('release-v*'),
159
+ ],
160
+ });
161
+ ```
162
+
163
+ ##### Exclusion filter pattern rules
164
+
165
+ - Patterns can contain alphanumeric characters, dots (.), underscores (_), hyphens (-), and asterisks (*) as wildcards
166
+ - Maximum pattern length is 128 characters
167
+ - You can specify up to 5 exclusion filters per repository
168
+
130
169
  ### Encryption
131
170
 
132
171
  By default, Amazon ECR uses server-side encryption with Amazon S3-managed encryption keys which encrypts your data at rest using an AES-256 encryption algorithm. For more control over the encryption for your Amazon ECR repositories, you can use server-side encryption with KMS keys stored in AWS Key Management Service (AWS KMS). Read more about this feature in the [ECR Developer Guide](https://docs.aws.amazon.com/AmazonECR/latest/userguide/encryption-at-rest.html).
@@ -0,0 +1,30 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
3
+ import * as ecr from 'aws-cdk-lib/aws-ecr';
4
+
5
+ const app = new cdk.App();
6
+ const stack = new cdk.Stack(app, 'aws-ecr-tag-mutability-exclusion-stack');
7
+
8
+ new ecr.Repository(stack, 'ImmutableRepoWithExclusions', {
9
+ imageTagMutability: ecr.TagMutability.IMMUTABLE_WITH_EXCLUSION,
10
+ imageTagMutabilityExclusionFilters: [
11
+ ecr.ImageTagMutabilityExclusionFilter.wildcard('dev-*'),
12
+ ecr.ImageTagMutabilityExclusionFilter.wildcard('test-*'),
13
+ ],
14
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
15
+ emptyOnDelete: true,
16
+ });
17
+
18
+ new ecr.Repository(stack, 'MutableRepoWithExclusions', {
19
+ imageTagMutability: ecr.TagMutability.MUTABLE_WITH_EXCLUSION,
20
+ imageTagMutabilityExclusionFilters: [
21
+ ecr.ImageTagMutabilityExclusionFilter.wildcard('prod-*'),
22
+ ecr.ImageTagMutabilityExclusionFilter.wildcard('release-v*'),
23
+ ],
24
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
25
+ emptyOnDelete: true,
26
+ });
27
+
28
+ new IntegTest(app, 'cdk-ecr-tag-mutability-exclusion-test', {
29
+ testCases: [stack],
30
+ });
@@ -1687,6 +1687,9 @@ const miCapacityProvider = new ecs.ManagedInstancesCapacityProvider(this, 'MICap
1687
1687
  propagateTags: ecs.PropagateManagedInstancesTags.CAPACITY_PROVIDER,
1688
1688
  });
1689
1689
 
1690
+ // Optionally configure security group rules using IConnectable interface
1691
+ miCapacityProvider.connections.allowFrom(ec2.Peer.ipv4(vpc.vpcCidrBlock), ec2.Port.tcp(80));
1692
+
1690
1693
  // Add the capacity provider to the cluster
1691
1694
  cluster.addManagedInstancesCapacityProvider(miCapacityProvider);
1692
1695
 
@@ -24,7 +24,7 @@ const infrastructureRole = new iam.Role(stack, 'InfrastructureRole', {
24
24
  roleName: 'AmazonECSInfrastructureRoleForOmakase',
25
25
  assumedBy: new iam.ServicePrincipal('ecs.amazonaws.com'),
26
26
  managedPolicies: [
27
- iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'),
27
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonECSInfrastructureRolePolicyForManagedInstances'),
28
28
  ],
29
29
  });
30
30
 
@@ -32,7 +32,7 @@ const instanceRole = new iam.Role(stack, 'InstanceRole', {
32
32
  roleName: 'AmazonECSInstanceRoleForOmakase',
33
33
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
34
34
  managedPolicies: [
35
- iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'),
35
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonECSInstanceRolePolicyForManagedInstances'),
36
36
  ],
37
37
  });
38
38
 
@@ -63,6 +63,9 @@ const miCapacityProvider = new ecs.ManagedInstancesCapacityProvider(stack, 'Mana
63
63
  },
64
64
  });
65
65
 
66
+ // Configure security group rules using IConnectable interface
67
+ miCapacityProvider.connections.allowFrom(ec2.Peer.ipv4(vpc.vpcCidrBlock), ec2.Port.tcp(80));
68
+
66
69
  // Add FMI capacity provider to cluster
67
70
  cluster.addManagedInstancesCapacityProvider(miCapacityProvider);
68
71
  cluster.addDefaultCapacityProviderStrategy([
@@ -106,7 +109,6 @@ new ecs.FargateService(stack, 'ManagedInstancesService', {
106
109
 
107
110
  new integ.IntegTest(app, 'ManagedInstancesCapacityProviders', {
108
111
  testCases: [stack],
109
- regions: ['us-west-2'],
110
112
  });
111
113
 
112
114
  app.synth();
@@ -0,0 +1,107 @@
1
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
2
+ import * as iam from 'aws-cdk-lib/aws-iam';
3
+ import * as cdk from 'aws-cdk-lib';
4
+ import * as ecs from 'aws-cdk-lib/aws-ecs';
5
+ import * as integ from '@aws-cdk/integ-tests-alpha';
6
+
7
+ const app = new cdk.App({
8
+ postCliContext: {
9
+ '@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm': true,
10
+ '@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature': false,
11
+ '@aws-cdk/aws-ecs:disableEcsImdsBlocking': false,
12
+ },
13
+ });
14
+ const stack = new cdk.Stack(app, 'integ-managedinstances-no-default-capacity-provider');
15
+
16
+ const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2, restrictDefaultSecurityGroup: false });
17
+ const cluster = new ecs.Cluster(stack, 'ManagedInstancesCluster', {
18
+ vpc,
19
+ });
20
+
21
+ // Create IAM roles required for FMI following Omakase specifications
22
+ const infrastructureRole = new iam.Role(stack, 'InfrastructureRole', {
23
+ roleName: 'InfrastructureRole',
24
+ assumedBy: new iam.ServicePrincipal('ecs.amazonaws.com'),
25
+ managedPolicies: [
26
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonECSInfrastructureRolePolicyForManagedInstances'),
27
+ ],
28
+ });
29
+
30
+ const instanceRole = new iam.Role(stack, 'InstanceRole', {
31
+ roleName: 'InstanceRole',
32
+ assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
33
+ managedPolicies: [
34
+ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonECSInstanceRolePolicyForManagedInstances'),
35
+ ],
36
+ });
37
+
38
+ infrastructureRole.grantPassRole(instanceRole);
39
+
40
+ const instanceProfile = new iam.InstanceProfile(stack, 'InstanceProfile', {
41
+ instanceProfileName: 'InstanceProfile',
42
+ role: instanceRole,
43
+ });
44
+
45
+ // Create a security group for FMI instances
46
+ const fmiSecurityGroup = new ec2.SecurityGroup(stack, 'ManagedInstancesSecurityGroup', {
47
+ vpc,
48
+ description: 'Security group for ManagedInstances capacity provider instances',
49
+ allowAllOutbound: true,
50
+ });
51
+
52
+ // Create MI Capacity Provider
53
+ const miCapacityProvider = new ecs.ManagedInstancesCapacityProvider(stack, 'ManagedInstancesCapacityProvider', {
54
+ infrastructureRole: infrastructureRole,
55
+ ec2InstanceProfile: instanceProfile,
56
+ subnets: vpc.privateSubnets,
57
+ securityGroups: [fmiSecurityGroup],
58
+ propagateTags: ecs.PropagateManagedInstancesTags.CAPACITY_PROVIDER,
59
+ instanceRequirements: {
60
+ vCpuCountMin: 1,
61
+ memoryMin: cdk.Size.gibibytes(2),
62
+ cpuManufacturers: [ec2.CpuManufacturer.INTEL],
63
+ acceleratorManufacturers: [ec2.AcceleratorManufacturer.NVIDIA],
64
+ },
65
+ });
66
+
67
+ // Add FMI capacity provider to cluster
68
+ cluster.addManagedInstancesCapacityProvider(miCapacityProvider);
69
+
70
+ // Create a task definition compatible with Managed Instances and Fargate
71
+ const taskDefinition = new ecs.TaskDefinition(stack, 'TaskDef', {
72
+ compatibility: ecs.Compatibility.FARGATE_AND_MANAGED_INSTANCES,
73
+ cpu: '256',
74
+ memoryMiB: '512',
75
+ networkMode: ecs.NetworkMode.AWS_VPC,
76
+ });
77
+
78
+ taskDefinition.addContainer('web', {
79
+ image: ecs.ContainerImage.fromRegistry('public.ecr.aws/docker/library/httpd:2.4'),
80
+ memoryLimitMiB: 512,
81
+ portMappings: [
82
+ {
83
+ containerPort: 80,
84
+ protocol: ecs.Protocol.TCP,
85
+ },
86
+ ],
87
+ });
88
+
89
+ // Create a service using the MI capacity provider
90
+ new ecs.FargateService(stack, 'ManagedInstancesService', {
91
+ cluster,
92
+ taskDefinition,
93
+ capacityProviderStrategies: [
94
+ {
95
+ capacityProvider: miCapacityProvider.capacityProviderName,
96
+ weight: 1,
97
+ },
98
+ ],
99
+ desiredCount: 1,
100
+ });
101
+
102
+ new integ.IntegTest(app, 'ManagedInstancesCapacityProviders', {
103
+ testCases: [stack],
104
+ regions: ['us-west-2'],
105
+ });
106
+
107
+ app.synth();
@@ -0,0 +1,45 @@
1
+ import * as ec2 from 'aws-cdk-lib/aws-ec2';
2
+ import * as ecs from 'aws-cdk-lib/aws-ecs';
3
+ import * as cdk from 'aws-cdk-lib';
4
+ import * as integ from '@aws-cdk/integ-tests-alpha';
5
+ import * as ecsPatterns from 'aws-cdk-lib/aws-ecs-patterns';
6
+
7
+ const app = new cdk.App();
8
+ const stack = new cdk.Stack(app, 'aws-ecs-integ-alb-fargate-public-private-switch');
9
+
10
+ const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2, restrictDefaultSecurityGroup: false });
11
+ const cluster = new ecs.Cluster(stack, 'FargateCluster', { vpc });
12
+
13
+ // Test private load balancer (the problematic case from the issue)
14
+ new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'PrivateALBFargateService', {
15
+ cluster,
16
+ memoryLimitMiB: 1024,
17
+ cpu: 512,
18
+ publicLoadBalancer: false, // This should create ECSPrivate target group
19
+ taskImageOptions: {
20
+ image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
21
+ },
22
+ });
23
+
24
+ // Test public load balancer for comparison
25
+ new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'PublicALBFargateService', {
26
+ cluster,
27
+ memoryLimitMiB: 1024,
28
+ cpu: 512,
29
+ publicLoadBalancer: true, // This should create ECS target group
30
+ taskImageOptions: {
31
+ image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
32
+ },
33
+ });
34
+
35
+ new integ.IntegTest(app, 'ALBFargatePublicPrivateSwitchTest', {
36
+ testCases: [stack],
37
+ allowDestroy: [
38
+ 'PrivateALBFargateServiceLB3F43693F',
39
+ 'PrivateALBFargateServiceLBPublicListenerECSPrivateGroup81AA5B8B',
40
+ 'PublicALBFargateServiceLBBDD839E7',
41
+ 'PublicALBFargateServiceLBPublicListenerECSGroupD991EA00',
42
+ ],
43
+ });
44
+
45
+ app.synth();
@@ -338,17 +338,13 @@ Balancers:
338
338
  ```ts
339
339
  declare const vpc: ec2.Vpc;
340
340
  declare const asg: autoscaling.AutoScalingGroup;
341
- declare const sg1: ec2.ISecurityGroup;
342
- declare const sg2: ec2.ISecurityGroup;
343
341
 
344
342
  // Create the load balancer in a VPC. 'internetFacing' is 'false'
345
343
  // by default, which creates an internal load balancer.
346
344
  const lb = new elbv2.NetworkLoadBalancer(this, 'LB', {
347
345
  vpc,
348
346
  internetFacing: true,
349
- securityGroups: [sg1],
350
347
  });
351
- lb.addSecurityGroup(sg2);
352
348
 
353
349
  // Add a listener on a particular port.
354
350
  const listener = lb.addListener('Listener', {
@@ -362,6 +358,40 @@ listener.addTargets('AppFleet', {
362
358
  });
363
359
  ```
364
360
 
361
+ ### Security Groups for Network Load Balancer
362
+
363
+ By default, Network Load Balancers (NLB) have a security group associated with them.
364
+ This is controlled by the feature flag `@aws-cdk/aws-elasticloadbalancingv2:networkLoadBalancerWithSecurityGroupByDefault`.
365
+ When this flag is enabled (the default for new projects), a security group will be automatically created and attached to the NLB unless you explicitly provide your own security groups via the `securityGroups` property.
366
+
367
+ If you wish to create an NLB without any security groups, you can set the `disableSecurityGroups` property to `true`. When this property is set, no security group will be associated with the NLB, regardless of the feature flag.
368
+
369
+ ```ts
370
+ declare const vpc: ec2.IVpc;
371
+
372
+ const nlb = new elbv2.NetworkLoadBalancer(this, 'LB', {
373
+ vpc,
374
+ // To disable security groups for this NLB
375
+ disableSecurityGroups: true,
376
+ });
377
+ ```
378
+
379
+ If you want to use your own security groups, provide them via the `securityGroups` property:
380
+
381
+ ```ts
382
+ declare const vpc: ec2.IVpc;
383
+ declare const sg1: ec2.ISecurityGroup;
384
+ declare const sg2: ec2.ISecurityGroup;
385
+
386
+ const nlb = new elbv2.NetworkLoadBalancer(this, 'LB', {
387
+ vpc,
388
+ // Provide your own security groups
389
+ securityGroups: [sg1],
390
+ });
391
+ // Add another security group to the NLB
392
+ nlb.addSecurityGroup(sg2);
393
+ ```
394
+
365
395
  ### Enforce security group inbound rules on PrivateLink traffic for a Network Load Balancer
366
396
 
367
397
  You can indicate whether to evaluate inbound security group rules for traffic
@@ -19,7 +19,7 @@ const vpc = new ec2.Vpc(stack, 'VPC', {
19
19
  });
20
20
 
21
21
  const fn = new lambda.Function(stack, 'Function', {
22
- runtime: lambda.Runtime.NODEJS_18_X,
22
+ runtime: lambda.Runtime.NODEJS_20_X,
23
23
  handler: 'index.handler',
24
24
  code: lambda.Code.fromInline(`
25
25
  exports.handler = async (event) => {
@@ -186,7 +186,7 @@ const signinFunction = new lambda.Function(testCase, 'Signin', {
186
186
  functionName: 'cdk-integ-alb-oidc-signin-handler',
187
187
  code: lambda.Code.fromAsset('alb-oidc-signin-handler', { exclude: ['*.ts'] }),
188
188
  handler: 'index.handler',
189
- runtime: lambda.Runtime.NODEJS_18_X,
189
+ runtime: lambda.Runtime.NODEJS_20_X,
190
190
  environment: {
191
191
  TEST_USERNAME: testUser.username,
192
192
  TEST_PASSWORD: testUser.password,
@@ -0,0 +1,70 @@
1
+ import { ExpectedResult, IntegTest, Match } from '@aws-cdk/integ-tests-alpha';
2
+ import { Stack, aws_ec2 as ec2, aws_elasticloadbalancingv2 as elbv2, App } from 'aws-cdk-lib';
3
+ import { Construct } from 'constructs';
4
+
5
+ class TestStack extends Stack {
6
+ public readonly lbWithSg: elbv2.NetworkLoadBalancer;
7
+ public readonly lbWithSg2: elbv2.NetworkLoadBalancer;
8
+ public readonly lbWithoutSg: elbv2.NetworkLoadBalancer;
9
+
10
+ constructor(scope: Construct, id: string) {
11
+ super(scope, id);
12
+
13
+ const vpc = new ec2.Vpc(this, 'Stack', {
14
+ maxAzs: 1,
15
+ natGateways: 0,
16
+ });
17
+
18
+ this.lbWithSg = new elbv2.NetworkLoadBalancer(this, 'NlbWithSecurityGroup', {
19
+ vpc,
20
+ });
21
+ this.lbWithSg2 = new elbv2.NetworkLoadBalancer(this, 'NlbWithSecurityGroup2', {
22
+ vpc,
23
+ securityGroups: [new ec2.SecurityGroup(this, 'SecurityGroup', {
24
+ vpc,
25
+ allowAllOutbound: true,
26
+ })],
27
+ });
28
+ this.lbWithSg.connections.allowTo(this.lbWithSg2, ec2.Port.tcp(1229));
29
+ this.lbWithoutSg = new elbv2.NetworkLoadBalancer(this, 'NlbWithoutSecurityGroup', {
30
+ vpc,
31
+ disableSecurityGroups: true,
32
+ });
33
+ }
34
+ }
35
+
36
+ const app = new App({
37
+ postCliContext: {
38
+ '@aws-cdk/aws-elasticloadbalancingv2:networkLoadBalancerWithSecurityGroupByDefault': true,
39
+ },
40
+ });
41
+ const stack = new TestStack(app, 'NlbSecurityGroupStack');
42
+ const integ = new IntegTest(app, 'NlbSecurityGroupInteg', {
43
+ testCases: [stack],
44
+ });
45
+ integ.assertions.awsApiCall('elastic-load-balancing-v2', 'describeLoadBalancers', {
46
+ LoadBalancerArns: [
47
+ stack.lbWithSg.loadBalancerArn,
48
+ stack.lbWithSg2.loadBalancerArn,
49
+ stack.lbWithoutSg.loadBalancerArn,
50
+ ],
51
+ }).expect(ExpectedResult.objectLike({
52
+ LoadBalancers: [
53
+ Match.objectLike({
54
+ LoadBalancerArn: stack.lbWithSg.loadBalancerArn,
55
+ SecurityGroups: Match.arrayWith([
56
+ Match.stringLikeRegexp('sg-[0-9a-f]{8,17}'),
57
+ ]),
58
+ }),
59
+ Match.objectLike({
60
+ LoadBalancerArn: stack.lbWithSg2.loadBalancerArn,
61
+ SecurityGroups: Match.arrayWith([
62
+ Match.stringLikeRegexp('sg-[0-9a-f]{8,17}'),
63
+ ]),
64
+ }),
65
+ Match.objectLike({
66
+ LoadBalancerArn: stack.lbWithoutSg.loadBalancerArn,
67
+ SecurityGroups: undefined,
68
+ }),
69
+ ],
70
+ }));
@@ -206,7 +206,7 @@ const signinFunction = new lambda.Function(testCase, 'Signin', {
206
206
  functionName: 'cdk-integ-alb-cognito-signin-handler',
207
207
  code: lambda.Code.fromAsset('alb-cognito-signin-handler', { exclude: ['*.ts'] }),
208
208
  handler: 'index.handler',
209
- runtime: lambda.Runtime.NODEJS_18_X,
209
+ runtime: lambda.Runtime.NODEJS_20_X,
210
210
  environment: {
211
211
  TEST_USERNAME: testUser.username,
212
212
  TEST_PASSWORD: testUser.password,
@@ -19,6 +19,7 @@ Currently supported are:
19
19
  - [Invoke an API Destination](#invoke-an-api-destination)
20
20
  - [Invoke an AppSync GraphQL API](#invoke-an-appsync-graphql-api)
21
21
  - [Put an event on an EventBridge bus](#put-an-event-on-an-eventbridge-bus)
22
+ - [Put an event on a Firehose delivery stream](#put-an-event-on-a-firehose-delivery-stream)
22
23
  - [Run an ECS Task](#run-an-ecs-task)
23
24
  - [Tagging Tasks](#tagging-tasks)
24
25
  - [Launch type for ECS Task](#launch-type-for-ecs-task)
@@ -528,6 +529,27 @@ rule.addTarget(new targets.EventBus(
528
529
  ));
529
530
  ```
530
531
 
532
+ ## Put an event on a Firehose delivery stream
533
+
534
+ Use the `FirehoseDeliveryStream` target to put event to an Amazon Data Firehose delivery stream.
535
+
536
+ The code snippet below creates the scheduled event rule that put events to an Amazon Data Firehose delivery stream.
537
+
538
+ ```ts
539
+ import * as firehose from 'aws-cdk-lib/aws-kinesisfirehose';
540
+ import * as s3 from 'aws-cdk-lib/aws-s3';
541
+
542
+ declare const bucket: s3.Bucket;
543
+ const stream = new firehose.DeliveryStream(this, 'DeliveryStream', {
544
+ destination: new firehose.S3Bucket(bucket),
545
+ });
546
+
547
+ const rule = new events.Rule(this, 'Rule', {
548
+ schedule: events.Schedule.expression('rate(1 minute)'),
549
+ });
550
+ rule.addTarget(new targets.FirehoseDeliveryStream(stream));
551
+ ```
552
+
531
553
  ## Run an ECS Task
532
554
 
533
555
  Use the `EcsTask` target to run an ECS Task.
@@ -0,0 +1,51 @@
1
+ import * as events from 'aws-cdk-lib/aws-events';
2
+ import * as firehose from 'aws-cdk-lib/aws-kinesisfirehose';
3
+ import * as s3 from 'aws-cdk-lib/aws-s3';
4
+ import * as cdk from 'aws-cdk-lib';
5
+ import * as targets from 'aws-cdk-lib/aws-events-targets';
6
+ import { IntegTest, ExpectedResult, AwsApiCall } from '@aws-cdk/integ-tests-alpha';
7
+
8
+ // ---------------------------------
9
+ // Define a rule that triggers a put to a Firehose delivery stream every 1min.
10
+
11
+ const app = new cdk.App();
12
+
13
+ const stack = new cdk.Stack(app, 'aws-cdk-firehose-event-target');
14
+
15
+ const bucket = new s3.Bucket(stack, 'firehose-bucket', {
16
+ autoDeleteObjects: true,
17
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
18
+ });
19
+ const deliveryStream = new firehose.DeliveryStream(stack, 'MyDeliveryStream', {
20
+ destination: new firehose.S3Bucket(bucket, {
21
+ bufferingInterval: cdk.Duration.seconds(30),
22
+ }),
23
+ });
24
+
25
+ const event = new events.Rule(stack, 'EveryMinute', {
26
+ schedule: events.Schedule.rate(cdk.Duration.minutes(1)),
27
+ });
28
+
29
+ event.addTarget(new targets.FirehoseDeliveryStream(deliveryStream));
30
+
31
+ const testCase = new IntegTest(app, 'firehose-event-target-integ', {
32
+ testCases: [stack],
33
+ });
34
+
35
+ const s3ApiCall = testCase.assertions.awsApiCall('S3', 'listObjectsV2', {
36
+ Bucket: bucket.bucketName,
37
+ MaxKeys: 1,
38
+ }).expect(ExpectedResult.objectLike({
39
+ KeyCount: 1,
40
+ })).waitForAssertions({
41
+ interval: cdk.Duration.seconds(30),
42
+ totalTimeout: cdk.Duration.minutes(10),
43
+ });
44
+
45
+ if (s3ApiCall instanceof AwsApiCall) {
46
+ s3ApiCall.waiterProvider?.addToRolePolicy({
47
+ Effect: 'Allow',
48
+ Action: ['s3:GetObject', 's3:ListBucket'],
49
+ Resource: ['*'],
50
+ });
51
+ }