konokenj.cdk-api-mcp-server 0.52.0__py3-none-any.whl → 0.54.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.
- cdk_api_mcp_server/__about__.py +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-eks-v2-alpha/README.md +45 -45
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-imagebuilder-alpha/README.md +94 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-lambda-go-alpha/README.md +102 -4
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/aws-sagemaker-alpha/README.md +32 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/@aws-cdk/mixins-preview/README.md +151 -5
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/README.md/README.md +2 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigateway/README.md +25 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigateway/integ.lambda-permission-consolidation.ts +55 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/README.md +35 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.lambda-permission-consolidation.ts +45 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codebuild/README.md +0 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/README.md +26 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-dynamodb/integ.dynamodb.add-to-resource-policy.ts +17 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.placement-strategies.ts +32 -8
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-eks/README.md +86 -86
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-eks/integ.eks-al2023-nodegroup.ts +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-eks/integ.fargate-cluster.ts +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.runtime.inlinecode.ts +7 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/README.md +65 -4
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-big-response.ts +13 -6
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-cloudfront.ts +20 -18
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-cross-nested-stack-source.ts +7 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-cross-stack-source.ts +6 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-cross-stack-ssm-source.ts +7 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-data.ts +83 -62
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-deployed-bucket.ts +10 -4
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-large-file.ts +20 -12
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-loggroup.ts +7 -2
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-security-groups-efs.ts +77 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-security-groups-empty.ts +69 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-security-groups-multiple.ts +89 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-security-groups-single.ts +77 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-signcontent.ts +11 -7
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-substitution-with-destination-key.ts +15 -8
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-substitution-with-role.ts +29 -14
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-substitution.ts +16 -8
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-vpc-basic.ts +65 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-vpc-config.ts +66 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-vpc-custom-subnets.ts +66 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-vpc-efs.ts +66 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-vpc-security-groups.ts +72 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-vpc-subnet-selection.ts +70 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment.ts +47 -69
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-secretsmanager/integ.secret.dynamic-reference-key.ts +38 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions/integ.sm-jsonpath-with-distributed-map-jsonata.ts +105 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/README.md +14 -3
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.evaluate-expression-arm64.ts +27 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.evaluate-expression-default.ts +25 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.evaluate-expression-mixed-arch.ts +35 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.evaluate-expression-x86.ts +27 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +2 -2
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/interfaces/README.md +33 -0
- {konokenj_cdk_api_mcp_server-0.52.0.dist-info → konokenj_cdk_api_mcp_server-0.54.0.dist-info}/METADATA +2 -2
- {konokenj_cdk_api_mcp_server-0.52.0.dist-info → konokenj_cdk_api_mcp_server-0.54.0.dist-info}/RECORD +58 -38
- {konokenj_cdk_api_mcp_server-0.52.0.dist-info → konokenj_cdk_api_mcp_server-0.54.0.dist-info}/WHEEL +0 -0
- {konokenj_cdk_api_mcp_server-0.52.0.dist-info → konokenj_cdk_api_mcp_server-0.54.0.dist-info}/entry_points.txt +0 -0
- {konokenj_cdk_api_mcp_server-0.52.0.dist-info → konokenj_cdk_api_mcp_server-0.54.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -1,16 +1,162 @@
|
|
|
1
|
-
# CDK Mixins
|
|
2
|
-
|
|
1
|
+
# CDK Mixins (Preview)
|
|
3
2
|
<!--BEGIN STABILITY BANNER-->
|
|
4
3
|
|
|
5
4
|
---
|
|
6
5
|
|
|
7
6
|

|
|
8
7
|
|
|
9
|
-
> The APIs of higher level constructs in this module are experimental and under active development.
|
|
8
|
+
> The APIs of higher level constructs in this module are experimental and under active development.
|
|
9
|
+
> They are subject to non-backward compatible changes or removal in any future version. These are
|
|
10
|
+
> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be
|
|
11
|
+
> announced in the release notes. This means that while you may use them, you may need to update
|
|
12
|
+
> your source code when upgrading to a newer version of this package.
|
|
10
13
|
|
|
11
14
|
---
|
|
12
15
|
|
|
13
16
|
<!--END STABILITY BANNER-->
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
CDK Mixins provide a new, advanced way to add functionality through composable abstractions.
|
|
19
|
+
Unlike traditional L2 constructs that bundle all features together, Mixins allow you to pick and choose exactly the capabilities you need for constructs.
|
|
20
|
+
|
|
21
|
+
## Key Benefits
|
|
22
|
+
|
|
23
|
+
* **Universal Compatibility**: Apply the same abstractions to L1 constructs, L2 constructs, or custom constructs
|
|
24
|
+
* **Composable Design**: Mix and match features without being locked into specific implementations
|
|
25
|
+
* **Cross-Service Abstractions**: Use common patterns like encryption across different AWS services
|
|
26
|
+
* **Escape Hatch Freedom**: Customize resources in a safe, typed way while keeping the abstractions you want
|
|
27
|
+
|
|
28
|
+
## Basic Usage
|
|
29
|
+
|
|
30
|
+
Mixins use `Mixins.of()` as the fundamental API for applying abstractions to constructs:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Base form: apply mixins to any construct
|
|
34
|
+
const bucket = new s3.CfnBucket(scope, "MyBucket");
|
|
35
|
+
Mixins.of(bucket)
|
|
36
|
+
.apply(new EncryptionAtRest())
|
|
37
|
+
.apply(new AutoDeleteObjects());
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Creating Custom Mixins
|
|
41
|
+
|
|
42
|
+
Mixins are simple classes that implement the `IMixin` interface:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// Simple mixin that enables versioning
|
|
46
|
+
class CustomVersioningMixin implements IMixin {
|
|
47
|
+
supports(construct: any): boolean {
|
|
48
|
+
return construct instanceof s3.CfnBucket;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
applyTo(bucket: any): any {
|
|
52
|
+
bucket.versioningConfiguration = {
|
|
53
|
+
status: "Enabled"
|
|
54
|
+
};
|
|
55
|
+
return bucket;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Usage
|
|
60
|
+
const bucket = new s3.CfnBucket(scope, "MyBucket");
|
|
61
|
+
Mixins.of(bucket).apply(new CustomVersioningMixin());
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Construct Selection
|
|
65
|
+
|
|
66
|
+
Mixins operate on construct trees and can be applied selectively:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// Apply to all constructs in a scope
|
|
70
|
+
Mixins.of(scope).apply(new EncryptionAtRest());
|
|
71
|
+
|
|
72
|
+
// Apply to specific resource types
|
|
73
|
+
Mixins.of(scope, ConstructSelector.resourcesOfType(s3.CfnBucket))
|
|
74
|
+
.apply(new EncryptionAtRest());
|
|
75
|
+
|
|
76
|
+
// Apply to constructs matching a pattern
|
|
77
|
+
Mixins.of(scope, ConstructSelector.byId(/.*-prod-.*/))
|
|
78
|
+
.apply(new ProductionSecurityMixin());
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Built-in Mixins
|
|
82
|
+
|
|
83
|
+
### Cross-Service Mixins
|
|
84
|
+
|
|
85
|
+
**EncryptionAtRest**: Applies encryption to supported AWS resources
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Works across different resource types
|
|
89
|
+
const bucket = new s3.CfnBucket(scope, "Bucket");
|
|
90
|
+
Mixins.of(bucket).apply(new EncryptionAtRest());
|
|
91
|
+
|
|
92
|
+
const logGroup = new logs.CfnLogGroup(scope, "LogGroup");
|
|
93
|
+
Mixins.of(logGroup).apply(new EncryptionAtRest());
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### S3-Specific Mixins
|
|
97
|
+
|
|
98
|
+
**AutoDeleteObjects**: Configures automatic object deletion for S3 buckets
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const bucket = new s3.CfnBucket(scope, "Bucket");
|
|
102
|
+
Mixins.of(bucket).apply(new AutoDeleteObjects());
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**EnableVersioning**: Enables versioning on S3 buckets
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const bucket = new s3.CfnBucket(scope, "Bucket");
|
|
109
|
+
Mixins.of(bucket).apply(new EnableVersioning());
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Generic Mixins
|
|
113
|
+
|
|
114
|
+
**CfnPropertiesMixin**: Applies arbitrary CloudFormation properties
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const bucket = new s3.CfnBucket(scope, "Bucket");
|
|
118
|
+
Mixins.of(bucket).apply(new CfnPropertiesMixin({
|
|
119
|
+
customProperty: { enabled: true }
|
|
120
|
+
}));
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Error Handling
|
|
124
|
+
|
|
125
|
+
Mixins provide comprehensive error handling:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Graceful handling of unsupported constructs
|
|
129
|
+
Mixins.of(scope)
|
|
130
|
+
.apply(new EncryptionAtRest()); // Skips unsupported constructs
|
|
131
|
+
|
|
132
|
+
// Strict application that requires all constructs to match
|
|
133
|
+
Mixins.of(scope)
|
|
134
|
+
.mustApply(new EncryptionAtRest()); // Throws if no constructs support the mixin
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## API Reference
|
|
138
|
+
|
|
139
|
+
### Core Interfaces
|
|
140
|
+
|
|
141
|
+
* `IMixin` - Interface that all mixins must implement
|
|
142
|
+
* `Mixins` - Main entry point for applying mixins
|
|
143
|
+
* `ConstructSelector` - Selects constructs from a tree based on criteria
|
|
144
|
+
* `MixinApplicator` - Applies mixins to selected constructs
|
|
145
|
+
|
|
146
|
+
### Mixins
|
|
147
|
+
|
|
148
|
+
* `EncryptionAtRest` - Cross-service encryption mixin
|
|
149
|
+
* `AutoDeleteObjects` - S3 auto-delete objects mixin
|
|
150
|
+
* `EnableVersioning` - S3 versioning mixin
|
|
151
|
+
* `CfnPropertiesMixin` - Generic CloudFormation properties mixin
|
|
152
|
+
|
|
153
|
+
### Selectors
|
|
154
|
+
|
|
155
|
+
* `ConstructSelector.all()` - Select all constructs
|
|
156
|
+
* `ConstructSelector.cfnResource()` - Select CfnResource constructs
|
|
157
|
+
* `ConstructSelector.resourcesOfType()` - Select by type
|
|
158
|
+
* `ConstructSelector.byId()` - Select by ID pattern
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
This project is licensed under the Apache-2.0 License.
|
|
@@ -480,6 +480,8 @@ CloudFormation to re-read the secret.
|
|
|
480
480
|
`SecretValue.ssmSecure()` is only supported for a limited set of resources.
|
|
481
481
|
[Click here for a list of supported resources and properties](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html#template-parameters-dynamic-patterns-resources).
|
|
482
482
|
|
|
483
|
+
`SecretValue.cfnDynamicReferenceKey` takes the same parameters as `SecretValue.secretsManager` and returns a key which can be used within a [dynamic reference](#dynamic-references) to dynamically load a secret from AWS Secrets Manager.
|
|
484
|
+
|
|
483
485
|
## ARN manipulation
|
|
484
486
|
|
|
485
487
|
Sometimes you will need to put together or pick apart Amazon Resource Names
|
|
@@ -334,6 +334,31 @@ const getMessageIntegration = new apigateway.AwsIntegration({
|
|
|
334
334
|
});
|
|
335
335
|
```
|
|
336
336
|
|
|
337
|
+
### Lambda Integration Permissions
|
|
338
|
+
|
|
339
|
+
By default, creating a `LambdaIntegration` will add a permission for API Gateway to invoke your AWS Lambda function, scoped to the specific method which uses the integration.
|
|
340
|
+
|
|
341
|
+
If you reuse the same AWS Lambda function for many integrations, the AWS Lambda permission policy size can be exceeded by adding a separate policy statement for each method which invokes the AWS Lambda function. To avoid this, you can opt to scope permissions to any method on the API by setting `scopePermissionToMethod` to `false`, and this will ensure only a single policy statement is added to the AWS Lambda permission policy.
|
|
342
|
+
|
|
343
|
+
```ts
|
|
344
|
+
declare const book: apigateway.Resource;
|
|
345
|
+
declare const backend: lambda.Function;
|
|
346
|
+
|
|
347
|
+
const getBookIntegration = new apigateway.LambdaIntegration(backend, {
|
|
348
|
+
scopePermissionToMethod: false,
|
|
349
|
+
});
|
|
350
|
+
const createBookIntegration = new apigateway.LambdaIntegration(backend, {
|
|
351
|
+
scopePermissionToMethod: false,
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
book.addMethod('GET', getBookIntegration);
|
|
355
|
+
book.addMethod('POST', createBookIntegration);
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
In the above example, a single permission is added, shared by both `getBookIntegration` and `createBookIntegration`.
|
|
359
|
+
|
|
360
|
+
Note that setting `scopePermissionToMethod` to `false` will always allow test invocations, no matter the value specified for `allowTestInvoke`.
|
|
361
|
+
|
|
337
362
|
## Usage Plan & API Keys
|
|
338
363
|
|
|
339
364
|
A usage plan specifies who can access one or more deployed API stages and methods, and the rate at which they can be
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda';
|
|
2
|
+
import { App, Stack } from 'aws-cdk-lib';
|
|
3
|
+
import { ExpectedResult, IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
4
|
+
import { Construct } from 'constructs';
|
|
5
|
+
import { LambdaIntegration, RestApi } from 'aws-cdk-lib/aws-apigateway';
|
|
6
|
+
|
|
7
|
+
class LambdaPermissionConsolidationStack extends Stack {
|
|
8
|
+
public readonly api: RestApi;
|
|
9
|
+
constructor(scope: Construct) {
|
|
10
|
+
super(scope, 'LambdaPermissionConsolidationStack');
|
|
11
|
+
|
|
12
|
+
const fn = new Function(this, 'Handler', {
|
|
13
|
+
code: Code.fromInline(`exports.handler = async function(event) {
|
|
14
|
+
return {
|
|
15
|
+
body: JSON.stringify({
|
|
16
|
+
message: 'Hello from ' + event.httpMethod,
|
|
17
|
+
}),
|
|
18
|
+
statusCode: 200,
|
|
19
|
+
headers: { 'Content-Type': 'application/json' }
|
|
20
|
+
};
|
|
21
|
+
}`),
|
|
22
|
+
runtime: Runtime.NODEJS_18_X,
|
|
23
|
+
handler: 'index.handler',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
this.api = new RestApi(this, 'Api', {
|
|
27
|
+
cloudWatchRole: true,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'];
|
|
31
|
+
methods.forEach(method => {
|
|
32
|
+
this.api.root.addMethod(method, new LambdaIntegration(fn, {
|
|
33
|
+
scopePermissionToMethod: false,
|
|
34
|
+
}));
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const app = new App({
|
|
40
|
+
postCliContext: {
|
|
41
|
+
'@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
const testCase = new LambdaPermissionConsolidationStack(app);
|
|
45
|
+
const integ = new IntegTest(app, 'lambda-permission-consolidation', {
|
|
46
|
+
testCases: [testCase],
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Test that all methods work after consolidation
|
|
50
|
+
const call = integ.assertions.httpApiCall(testCase.api.deploymentStage.urlForPath('/'), {
|
|
51
|
+
method: 'GET',
|
|
52
|
+
});
|
|
53
|
+
call.expect(ExpectedResult.objectLike({
|
|
54
|
+
body: { message: 'Hello from GET' },
|
|
55
|
+
}));
|
cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/README.md
CHANGED
|
@@ -47,6 +47,41 @@ httpApi.addRoutes({
|
|
|
47
47
|
});
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
#### Lambda Integration Permissions
|
|
51
|
+
|
|
52
|
+
By default, creating a `HttpLambdaIntegration` will add a permission for API Gateway to invoke your AWS Lambda function, scoped to the specific route which uses the integration.
|
|
53
|
+
|
|
54
|
+
If you reuse the same AWS Lambda function for many integrations, the AWS Lambda permission policy size can be exceeded by adding a separate policy statement for each route which invokes the AWS Lambda function. To avoid this, you can opt to scope permissions to any route on the API by setting `scopePermissionToRoute` to `false`, and this will ensure only a single policy statement is added to the AWS Lambda permission policy.
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations';
|
|
58
|
+
|
|
59
|
+
declare const booksDefaultFn: lambda.Function;
|
|
60
|
+
|
|
61
|
+
const httpApi = new apigwv2.HttpApi(this, 'HttpApi');
|
|
62
|
+
|
|
63
|
+
const getBooksIntegration = new HttpLambdaIntegration('GetBooksIntegration', booksDefaultFn, {
|
|
64
|
+
scopePermissionToRoute: false,
|
|
65
|
+
});
|
|
66
|
+
const createBookIntegration = new HttpLambdaIntegration('CreateBookIntegration', booksDefaultFn, {
|
|
67
|
+
scopePermissionToRoute: false,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
httpApi.addRoutes({
|
|
71
|
+
path: '/books',
|
|
72
|
+
methods: [ apigwv2.HttpMethod.GET ],
|
|
73
|
+
integration: getBooksIntegration,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
httpApi.addRoutes({
|
|
77
|
+
path: '/books',
|
|
78
|
+
methods: [ apigwv2.HttpMethod.POST ],
|
|
79
|
+
integration: createBookIntegration,
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
In the above example, a single permission is added, shared by both `getBookIntegration` and `createBookIntegration`.
|
|
84
|
+
|
|
50
85
|
### HTTP Proxy
|
|
51
86
|
|
|
52
87
|
HTTP Proxy integrations enables connecting an HTTP API route to a publicly routable HTTP endpoint. When a client
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { HttpApi, HttpMethod, HttpRoute, HttpRouteKey } from 'aws-cdk-lib/aws-apigatewayv2';
|
|
2
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
3
|
+
import { ExpectedResult, IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
4
|
+
import { App, Stack } from 'aws-cdk-lib';
|
|
5
|
+
import { HttpLambdaIntegration } from 'aws-cdk-lib/aws-apigatewayv2-integrations';
|
|
6
|
+
|
|
7
|
+
const app = new App({
|
|
8
|
+
postCliContext: {
|
|
9
|
+
'@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
const stack = new Stack(app, 'integ-lambda-permission-consolidation');
|
|
13
|
+
|
|
14
|
+
const httpApi = new HttpApi(stack, 'HttpApi');
|
|
15
|
+
|
|
16
|
+
const lambdaHandler = new lambda.Function(stack, 'Handler', {
|
|
17
|
+
runtime: lambda.Runtime.NODEJS_18_X,
|
|
18
|
+
handler: 'index.handler',
|
|
19
|
+
code: new lambda.InlineCode('exports.handler = async function(event, context) { return { statusCode: 200, body: JSON.stringify({ message: \'Hello from \' + event.requestContext.http.path }) }; };'),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Add several routes
|
|
23
|
+
for (let i = 1; i <= 10; i++) {
|
|
24
|
+
new HttpRoute(stack, `Route${i}`, {
|
|
25
|
+
httpApi: httpApi,
|
|
26
|
+
integration: new HttpLambdaIntegration(`Integration${i}`, lambdaHandler, {
|
|
27
|
+
scopePermissionToRoute: false,
|
|
28
|
+
}),
|
|
29
|
+
routeKey: HttpRouteKey.with(`/path${i}`, HttpMethod.GET),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Integ Test Assertions
|
|
34
|
+
const integ = new IntegTest(app, 'Integ', { testCases: [stack] });
|
|
35
|
+
|
|
36
|
+
// Test that routes work after consolidation
|
|
37
|
+
integ.assertions.httpApiCall(httpApi.apiEndpoint + '/path1').expect(ExpectedResult.objectLike({
|
|
38
|
+
body: { message: 'Hello from /path1' },
|
|
39
|
+
status: 200,
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
integ.assertions.httpApiCall(httpApi.apiEndpoint + '/path12').expect(ExpectedResult.objectLike({
|
|
43
|
+
body: { message: 'Hello from /path10' },
|
|
44
|
+
status: 200,
|
|
45
|
+
}));
|
|
@@ -872,6 +872,32 @@ table.addToResourcePolicy(new iam.PolicyStatement({
|
|
|
872
872
|
TableV2 doesn’t support creating a replica and adding a resource-based policy to that replica in the same stack update in Regions other than the Region where you deploy the stack update.
|
|
873
873
|
To incorporate a resource-based policy into a replica, you'll need to initially deploy the replica without the policy, followed by a subsequent update to include the desired policy.
|
|
874
874
|
|
|
875
|
+
### Grant Methods and Resource Policies
|
|
876
|
+
|
|
877
|
+
Grant methods like `grantReadData()`, `grantWriteData()`, and `grantReadWriteData()` automatically add permissions to resource policies when used with same-account principals (like `AccountRootPrincipal`). This happens transparently:
|
|
878
|
+
|
|
879
|
+
```ts
|
|
880
|
+
const table = new dynamodb.TableV2(this, 'Table', {
|
|
881
|
+
partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
|
|
882
|
+
});
|
|
883
|
+
|
|
884
|
+
// Automatically adds to table's resource policy (same account)
|
|
885
|
+
table.grantReadData(new iam.AccountRootPrincipal());
|
|
886
|
+
|
|
887
|
+
// Adds to IAM user's policy (not resource policy)
|
|
888
|
+
declare const user: iam.User;
|
|
889
|
+
table.grantReadData(user);
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
**How it works:**
|
|
893
|
+
- **Same-account principals** (AccountRootPrincipal, AccountPrincipal): Grant adds statement to table's resource policy
|
|
894
|
+
- **IAM identities** (User, Role, Group): Grant adds statement to the identity's IAM policy
|
|
895
|
+
- **Resource policy statements**: Automatically use wildcard resources (`*`) to avoid circular dependencies
|
|
896
|
+
|
|
897
|
+
This behavior follows the same pattern as other AWS services like KMS and S3, where grants intelligently choose between resource policies and identity policies based on the principal type.
|
|
898
|
+
|
|
899
|
+
**To avoid wildcards in resource policies:** If you need scoped resource ARNs instead of wildcards, use `addToResourcePolicy()` directly with an explicit table name instead of grant methods. See the "Scoped Resource Policies (Advanced)" section above for details.
|
|
900
|
+
|
|
875
901
|
## Grants
|
|
876
902
|
|
|
877
903
|
Using any of the `grant*` methods on an instance of the `TableV2` construct will only apply to the primary table, its indexes, and any associated `encryptionKey`. As an example, `grantReadData` used below will only apply the table in `us-west-2`:
|
|
@@ -26,6 +26,7 @@ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
|
26
26
|
export class TestStack extends Stack {
|
|
27
27
|
public readonly wildcardTable: dynamodb.Table;
|
|
28
28
|
public readonly scopedTable: dynamodb.Table;
|
|
29
|
+
public readonly grantTable: dynamodb.Table;
|
|
29
30
|
|
|
30
31
|
constructor(scope: Construct, id: string, props?: StackProps) {
|
|
31
32
|
super(scope, id, props);
|
|
@@ -66,6 +67,22 @@ export class TestStack extends Stack {
|
|
|
66
67
|
// Use CloudFormation intrinsic function to construct table ARN with known table name
|
|
67
68
|
resources: [Fn.sub('arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/my-explicit-scoped-table')],
|
|
68
69
|
}));
|
|
70
|
+
|
|
71
|
+
// TEST 3: Table using grant methods with AccountRootPrincipal
|
|
72
|
+
// This validates the fix for issue #35967: circular dependency when using grant methods
|
|
73
|
+
// Before fix: grant methods with AccountRootPrincipal caused circular dependency
|
|
74
|
+
// After fix: grant methods use resourceSelfArns: ['*'] to avoid circular dependency
|
|
75
|
+
this.grantTable = new dynamodb.Table(this, 'GrantTable', {
|
|
76
|
+
partitionKey: {
|
|
77
|
+
name: 'id',
|
|
78
|
+
type: dynamodb.AttributeType.STRING,
|
|
79
|
+
},
|
|
80
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// This should NOT cause circular dependency - validates fix for #35967
|
|
84
|
+
// Using grantWriteData because it has simpler actions valid for resource policies
|
|
85
|
+
this.grantTable.grantWriteData(new iam.AccountRootPrincipal());
|
|
69
86
|
}
|
|
70
87
|
}
|
|
71
88
|
|
cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.placement-strategies.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
|
2
2
|
import * as cdk from 'aws-cdk-lib';
|
|
3
3
|
import { Construct } from 'constructs';
|
|
4
4
|
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
5
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
5
6
|
|
|
6
7
|
const app = new cdk.App({
|
|
7
8
|
postCliContext: {
|
|
@@ -12,24 +13,29 @@ const app = new cdk.App({
|
|
|
12
13
|
},
|
|
13
14
|
});
|
|
14
15
|
|
|
15
|
-
class
|
|
16
|
-
|
|
17
|
-
super(scope, id, props);
|
|
18
|
-
|
|
16
|
+
class BaseEcsStack extends cdk.Stack {
|
|
17
|
+
protected createBaseResources() {
|
|
19
18
|
const vpc = new ec2.Vpc(this, 'VPC', { restrictDefaultSecurityGroup: false });
|
|
20
|
-
|
|
21
19
|
const cluster = new ecs.Cluster(this, 'EcsCluster', { vpc });
|
|
22
20
|
cluster.addCapacity('DefaultAutoScalingGroup', {
|
|
23
21
|
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T2, ec2.InstanceSize.MICRO),
|
|
24
22
|
});
|
|
25
|
-
|
|
26
23
|
const taskDefinition = new ecs.Ec2TaskDefinition(this, 'TaskDef');
|
|
27
24
|
taskDefinition.addContainer('web', {
|
|
28
25
|
image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'),
|
|
29
26
|
memoryLimitMiB: 256,
|
|
30
27
|
});
|
|
28
|
+
return { vpc, cluster, taskDefinition };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Test service with multiple placement strategies
|
|
33
|
+
class EcsWithStrategiesStack extends BaseEcsStack {
|
|
34
|
+
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
|
35
|
+
super(scope, id, props);
|
|
36
|
+
const { cluster, taskDefinition } = this.createBaseResources();
|
|
31
37
|
|
|
32
|
-
new ecs.Ec2Service(this, '
|
|
38
|
+
new ecs.Ec2Service(this, 'Service', {
|
|
33
39
|
cluster,
|
|
34
40
|
taskDefinition,
|
|
35
41
|
placementStrategies: [
|
|
@@ -40,6 +46,24 @@ class EcsStack extends cdk.Stack {
|
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
// Test service with empty placement strategies
|
|
50
|
+
class EcsWithEmptyStrategiesStack extends BaseEcsStack {
|
|
51
|
+
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
|
52
|
+
super(scope, id, props);
|
|
53
|
+
const { cluster, taskDefinition } = this.createBaseResources();
|
|
54
|
+
|
|
55
|
+
new ecs.Ec2Service(this, 'Service', {
|
|
56
|
+
cluster,
|
|
57
|
+
taskDefinition,
|
|
58
|
+
placementStrategies: [],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
new integ.IntegTest(app, 'LambdaTest', {
|
|
63
|
+
testCases: [
|
|
64
|
+
new EcsWithStrategiesStack(app, 'ecs-placement-strategies-with-strategies'),
|
|
65
|
+
new EcsWithEmptyStrategiesStack(app, 'ecs-placement-strategies-empty'),
|
|
66
|
+
],
|
|
67
|
+
});
|
|
44
68
|
|
|
45
69
|
app.synth();
|