konokenj.cdk-api-mcp-server 0.53.0__py3-none-any.whl → 0.55.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 +298 -0
- 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 +167 -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-cognito/README.md +2 -2
- 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-opensearchservice/integ.opensearch.ebs.ts +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/README.md +1 -1
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.cluster-cloudwatch-logs-exports.ts +56 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-route53/README.md +32 -31
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-route53/integ.zone-delegation-iam-stack.ts +66 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-big-response.ts +4 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-data.ts +15 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-s3-deployment/integ.bucket-deployment-large-file.ts +3 -0
- 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-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/custom-resources/README.md +56 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/custom-resources/integ.external-id.ts +80 -0
- cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/interfaces/README.md +33 -0
- {konokenj_cdk_api_mcp_server-0.53.0.dist-info → konokenj_cdk_api_mcp_server-0.55.0.dist-info}/METADATA +2 -2
- {konokenj_cdk_api_mcp_server-0.53.0.dist-info → konokenj_cdk_api_mcp_server-0.55.0.dist-info}/RECORD +40 -28
- {konokenj_cdk_api_mcp_server-0.53.0.dist-info → konokenj_cdk_api_mcp_server-0.55.0.dist-info}/WHEEL +0 -0
- {konokenj_cdk_api_mcp_server-0.53.0.dist-info → konokenj_cdk_api_mcp_server-0.55.0.dist-info}/entry_points.txt +0 -0
- {konokenj_cdk_api_mcp_server-0.53.0.dist-info → konokenj_cdk_api_mcp_server-0.55.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -367,40 +367,40 @@ const crossAccountRole = new iam.Role(this, 'CrossAccountRole', {
|
|
|
367
367
|
roleName: 'MyDelegationRole',
|
|
368
368
|
// The other account
|
|
369
369
|
assumedBy: new iam.AccountPrincipal('12345678901'),
|
|
370
|
-
// You can scope down this role policy to be least privileged.
|
|
371
|
-
// If you want the other account to be able to manage specific records,
|
|
372
|
-
// you can scope down by resource and/or normalized record names
|
|
373
|
-
inlinePolicies: {
|
|
374
|
-
crossAccountPolicy: new iam.PolicyDocument({
|
|
375
|
-
statements: [
|
|
376
|
-
new iam.PolicyStatement({
|
|
377
|
-
sid: 'ListHostedZonesByName',
|
|
378
|
-
effect: iam.Effect.ALLOW,
|
|
379
|
-
actions: ['route53:ListHostedZonesByName'],
|
|
380
|
-
resources: ['*'],
|
|
381
|
-
}),
|
|
382
|
-
new iam.PolicyStatement({
|
|
383
|
-
sid: 'GetHostedZoneAndChangeResourceRecordSets',
|
|
384
|
-
effect: iam.Effect.ALLOW,
|
|
385
|
-
actions: ['route53:GetHostedZone', 'route53:ChangeResourceRecordSets'],
|
|
386
|
-
// This example assumes the RecordSet subdomain.somexample.com
|
|
387
|
-
// is contained in the HostedZone
|
|
388
|
-
resources: ['arn:aws:route53:::hostedzone/HZID00000000000000000'],
|
|
389
|
-
conditions: {
|
|
390
|
-
'ForAllValues:StringLike': {
|
|
391
|
-
'route53:ChangeResourceRecordSetsNormalizedRecordNames': [
|
|
392
|
-
'subdomain.someexample.com',
|
|
393
|
-
],
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
}),
|
|
397
|
-
],
|
|
398
|
-
}),
|
|
399
|
-
},
|
|
400
370
|
});
|
|
401
371
|
parentZone.grantDelegation(crossAccountRole);
|
|
402
372
|
```
|
|
403
373
|
|
|
374
|
+
To restrict the records that can be created with the delegation IAM role, use the optional `delegatedZoneNames` property in the delegation options,
|
|
375
|
+
which enforces the `route53:ChangeResourceRecordSetsNormalizedRecordNames` condition key for record names that match those hosted zone names.
|
|
376
|
+
The `delegatedZoneNames` list may only consist of hosted zones names that are subzones of the parent hosted zone.
|
|
377
|
+
|
|
378
|
+
If the delegated zone name contains an unresolved token,
|
|
379
|
+
it must resolve to a zone name that satisfies the requirements according to the documentation:
|
|
380
|
+
https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/specifying-conditions-route53.html#route53_rrset_conditionkeys_normalization
|
|
381
|
+
|
|
382
|
+
> All letters must be lowercase.
|
|
383
|
+
> The DNS name must be without the trailing dot.
|
|
384
|
+
> Characters other than a–z, 0–9, - (hyphen), _ (underscore), and . (period, as a delimiter between labels) must use escape codes in the format \three-digit octal code. For example, \052 is the octal code for character *.
|
|
385
|
+
|
|
386
|
+
This feature allows you to better follow the minimum permissions privilege principle:
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
const parentZone = new route53.PublicHostedZone(this, 'HostedZone', {
|
|
390
|
+
zoneName: 'someexample.com',
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
declare const betaCrossAccountRole: iam.Role;
|
|
394
|
+
parentZone.grantDelegation(betaCrossAccountRole, {
|
|
395
|
+
delegatedZoneNames: ['beta.someexample.com'],
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
declare const prodCrossAccountRole: iam.Role;
|
|
399
|
+
parentZone.grantDelegation(prodCrossAccountRole, {
|
|
400
|
+
delegatedZoneNames: ['prod.someexample.com'],
|
|
401
|
+
});
|
|
402
|
+
```
|
|
403
|
+
|
|
404
404
|
In the account containing the child zone to be delegated:
|
|
405
405
|
|
|
406
406
|
```ts
|
|
@@ -540,7 +540,8 @@ const zone = route53.HostedZone.fromHostedZoneAttributes(this, 'MyZone', {
|
|
|
540
540
|
```
|
|
541
541
|
|
|
542
542
|
Alternatively, use the `HostedZone.fromHostedZoneId` to import hosted zones if
|
|
543
|
-
you know the ID and the retrieval for the `zoneName` is undesirable.
|
|
543
|
+
you know the ID and the retrieval for the `zoneName` is undesirable.
|
|
544
|
+
Note that any records created with a hosted zone obtained this way must have their name be fully qualified
|
|
544
545
|
|
|
545
546
|
```ts
|
|
546
547
|
const zone = route53.HostedZone.fromHostedZoneId(this, 'MyZone', 'ZOJJZC49E0EPZ');
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
2
|
+
import * as cdk from 'aws-cdk-lib';
|
|
3
|
+
import * as route53 from 'aws-cdk-lib/aws-route53';
|
|
4
|
+
import { Construct } from 'constructs';
|
|
5
|
+
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
6
|
+
|
|
7
|
+
class ZoneDelegationIamStack extends cdk.Stack {
|
|
8
|
+
constructor(scope: Construct, id: string) {
|
|
9
|
+
super(scope, id);
|
|
10
|
+
|
|
11
|
+
const parentZone = new route53.PublicHostedZone(this, 'ParentZone', {
|
|
12
|
+
zoneName: 'uniqueexample.com',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const trusteeRoleArns = this.formatArn({
|
|
16
|
+
service: 'iam',
|
|
17
|
+
region: '',
|
|
18
|
+
resource: 'role',
|
|
19
|
+
resourceName: 'ZoneDelegationStack-*',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const delegationRole = new iam.Role(this, 'ZoneDelegationRole', {
|
|
23
|
+
roleName: 'ExampleDelegationRole',
|
|
24
|
+
assumedBy: new iam.AccountRootPrincipal().withConditions({
|
|
25
|
+
ArnLike: {
|
|
26
|
+
'aws:PrincipalArn': trusteeRoleArns,
|
|
27
|
+
},
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const delegationGrant = parentZone.grantDelegation(delegationRole, {
|
|
32
|
+
delegatedZoneNames: [
|
|
33
|
+
'sub1.uniqueexample.com',
|
|
34
|
+
'sub2_*$.uniqueexample.com', // should result in octal codes in iam condition
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const subZone = new route53.PublicHostedZone(this, 'SubZone', {
|
|
39
|
+
zoneName: 'sub1.uniqueexample.com',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
new route53.CrossAccountZoneDelegationRecord(subZone, 'ZoneDelegation', {
|
|
43
|
+
delegatedZone: subZone,
|
|
44
|
+
parentHostedZoneName: parentZone.zoneName,
|
|
45
|
+
delegationRole: delegationRole,
|
|
46
|
+
}).node.addDependency(delegationGrant);
|
|
47
|
+
|
|
48
|
+
const subZoneWithSpecialChars = new route53.PublicHostedZone(this, 'SubZoneSpecialChars', {
|
|
49
|
+
zoneName: 'sub2_*$.uniqueexample.com',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
new route53.CrossAccountZoneDelegationRecord(subZoneWithSpecialChars, 'ZoneDelegation', {
|
|
53
|
+
delegatedZone: subZoneWithSpecialChars,
|
|
54
|
+
parentHostedZoneName: parentZone.zoneName,
|
|
55
|
+
delegationRole: delegationRole,
|
|
56
|
+
}).node.addDependency(delegationGrant);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const app = new cdk.App();
|
|
61
|
+
|
|
62
|
+
const stack = new ZoneDelegationIamStack(app, 'ZoneDelegationStack');
|
|
63
|
+
|
|
64
|
+
new IntegTest(app, 'ZoneDelegationIam', {
|
|
65
|
+
testCases: [stack],
|
|
66
|
+
});
|
|
@@ -31,6 +31,10 @@ class TestBucketDeployment extends cdk.Stack {
|
|
|
31
31
|
const sources = [];
|
|
32
32
|
for (let i = 0; i < numFiles; i++) {
|
|
33
33
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tmpcdk'));
|
|
34
|
+
process.on('exit', () => {
|
|
35
|
+
fs.rmSync(tempDir, { force: true, recursive: true });
|
|
36
|
+
});
|
|
37
|
+
|
|
34
38
|
fs.mkdirSync(tempDir, { recursive: true });
|
|
35
39
|
const fileName = `${i+1}.txt`;
|
|
36
40
|
const filePath = path.join(tempDir, fileName);
|
|
@@ -64,6 +64,9 @@ class TestBucketDeploymentData extends Stack {
|
|
|
64
64
|
// Test empty string handling
|
|
65
65
|
const file8 = Source.data('file8.txt', '');
|
|
66
66
|
|
|
67
|
+
// Test null JSON data value
|
|
68
|
+
const file9 = Source.jsonData('my-json/config-with-null.json', { hello: 'there', goodbye: null });
|
|
69
|
+
|
|
67
70
|
const deployment = new BucketDeployment(this, 'DeployWithDataSources', {
|
|
68
71
|
destinationBucket: this.bucket,
|
|
69
72
|
sources: [file1, file2],
|
|
@@ -77,6 +80,7 @@ class TestBucketDeploymentData extends Stack {
|
|
|
77
80
|
deployment.addSource(file6);
|
|
78
81
|
deployment.addSource(file7);
|
|
79
82
|
deployment.addSource(file8);
|
|
83
|
+
deployment.addSource(file9);
|
|
80
84
|
|
|
81
85
|
new CfnOutput(this, 'BucketName', { value: this.bucket.bucketName });
|
|
82
86
|
}
|
|
@@ -105,6 +109,17 @@ assertionProvider.expect(ExpectedResult.objectLike({
|
|
|
105
109
|
Body: '{"secret_value":"test\\"with\\"quotes"}',
|
|
106
110
|
}));
|
|
107
111
|
|
|
112
|
+
// Assert that JSON data with a null value is represented properly
|
|
113
|
+
const jsonNullAssertionProvider = integTest.assertions.awsApiCall('S3', 'getObject', {
|
|
114
|
+
Bucket: testCase.bucket.bucketName,
|
|
115
|
+
Key: path.join('deploy/here', 'my-json/config-with-null.json'),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Verify the content is valid JSON and both null and non-null fields are present
|
|
119
|
+
jsonNullAssertionProvider.expect(ExpectedResult.objectLike({
|
|
120
|
+
Body: '{"hello":"there","goodbye":null}',
|
|
121
|
+
}));
|
|
122
|
+
|
|
108
123
|
// Add assertions to verify the YAML file
|
|
109
124
|
const yamlAssertionProvider = integTest.assertions.awsApiCall('S3', 'getObject', {
|
|
110
125
|
Bucket: testCase.bucket.bucketName,
|
|
@@ -30,6 +30,9 @@ const bucket = new Bucket(stack, 'Bucket', {
|
|
|
30
30
|
|
|
31
31
|
// Create a temporary directory for our large files
|
|
32
32
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdk-large-files-'));
|
|
33
|
+
process.on('exit', () => {
|
|
34
|
+
fs.rmSync(tempDir, { force: true, recursive: true });
|
|
35
|
+
});
|
|
33
36
|
|
|
34
37
|
// Generate a large JSON file (10MB) programmatically
|
|
35
38
|
const largeJsonFilePath = path.join(tempDir, 'large-file.json');
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as cdk from 'aws-cdk-lib';
|
|
2
|
+
import { SecretValue } from 'aws-cdk-lib';
|
|
3
|
+
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
|
|
4
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
5
|
+
|
|
6
|
+
class TestStack extends cdk.Stack {
|
|
7
|
+
constructor(scope: cdk.App, id: string) {
|
|
8
|
+
super(scope, id);
|
|
9
|
+
|
|
10
|
+
// Create a default secret
|
|
11
|
+
const secret = new secretsmanager.Secret(this, 'Secret');
|
|
12
|
+
|
|
13
|
+
// Create a JSON secret containing cfnDynamicReferenceKey values extracted from the default secret
|
|
14
|
+
new secretsmanager.Secret(this, 'JSONSecret', {
|
|
15
|
+
secretObjectValue: {
|
|
16
|
+
cfnDynamicReferenceKeyWithDefaults: SecretValue.unsafePlainText(secret.cfnDynamicReferenceKey()),
|
|
17
|
+
cfnDynamicReferenceKeyWithJsonFieldAndVersionStage: SecretValue.unsafePlainText(secret.cfnDynamicReferenceKey({
|
|
18
|
+
jsonField: 'json-key',
|
|
19
|
+
versionStage: 'version-stage',
|
|
20
|
+
})),
|
|
21
|
+
cfnDynamicReferenceKeyWithJsonFieldAndVersionId: SecretValue.unsafePlainText(secret.cfnDynamicReferenceKey({
|
|
22
|
+
jsonField: 'json-key',
|
|
23
|
+
versionId: 'version-id',
|
|
24
|
+
})),
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const app = new cdk.App();
|
|
31
|
+
|
|
32
|
+
const stack = new TestStack(app, 'cdk-integ-secrets-dynamic-reference-key');
|
|
33
|
+
|
|
34
|
+
new integ.IntegTest(app, 'cdk-integ-secrets-dynamic-reference-key-test', {
|
|
35
|
+
testCases: [stack],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
app.synth();
|
cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/README.md
CHANGED
|
@@ -141,6 +141,17 @@ The `EvaluateExpression` supports a `runtime` prop to specify the Lambda
|
|
|
141
141
|
runtime to use to evaluate the expression. Currently, only runtimes
|
|
142
142
|
of the Node.js family are supported.
|
|
143
143
|
|
|
144
|
+
The `EvaluateExpression` also supports an `architecture` prop to specify the Lambda
|
|
145
|
+
architecture. This can be useful when migrating to ARM64 or when running integration
|
|
146
|
+
tests on ARM64 systems.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
const convertToSecondsArm64 = new tasks.EvaluateExpression(this, 'Convert to seconds', {
|
|
150
|
+
expression: '$.waitMilliseconds / 1000',
|
|
151
|
+
architecture: lambda.Architecture.ARM_64,
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
144
155
|
## API Gateway
|
|
145
156
|
|
|
146
157
|
Step Functions supports [API Gateway](https://docs.aws.amazon.com/step-functions/latest/dg/connect-api-gateway.html) through the service integration pattern.
|
|
@@ -1374,12 +1385,12 @@ The following code snippet includes a Task state that uses eks:call to list the
|
|
|
1374
1385
|
|
|
1375
1386
|
```ts
|
|
1376
1387
|
import * as eks from 'aws-cdk-lib/aws-eks';
|
|
1377
|
-
import {
|
|
1388
|
+
import { KubectlV34Layer } from '@aws-cdk/lambda-layer-kubectl-v34';
|
|
1378
1389
|
|
|
1379
1390
|
const myEksCluster = new eks.Cluster(this, 'my sample cluster', {
|
|
1380
|
-
version: eks.KubernetesVersion.
|
|
1391
|
+
version: eks.KubernetesVersion.V1_34,
|
|
1381
1392
|
clusterName: 'myEksCluster',
|
|
1382
|
-
kubectlLayer: new
|
|
1393
|
+
kubectlLayer: new KubectlV34Layer(this, 'kubectl'),
|
|
1383
1394
|
});
|
|
1384
1395
|
|
|
1385
1396
|
new tasks.EksCall(this, 'Call a EKS Endpoint', {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { App, Stack } from 'aws-cdk-lib';
|
|
2
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
3
|
+
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
|
|
4
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
5
|
+
import * as cdk from 'aws-cdk-lib';
|
|
6
|
+
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
|
|
7
|
+
|
|
8
|
+
const app = new App();
|
|
9
|
+
const stack = new Stack(app, 'aws-cdk-sfn-evaluate-expression-arm64-integ');
|
|
10
|
+
|
|
11
|
+
const evaluateExpression = new tasks.EvaluateExpression(stack, 'EvaluateExpression', {
|
|
12
|
+
expression: '$.a + $.b',
|
|
13
|
+
architecture: lambda.Architecture.ARM_64,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const sm = new sfn.StateMachine(stack, 'StateMachine', {
|
|
17
|
+
definitionBody: sfn.DefinitionBody.fromChainable(evaluateExpression),
|
|
18
|
+
timeout: cdk.Duration.seconds(30),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
new cdk.CfnOutput(stack, 'stateMachineArn', {
|
|
22
|
+
value: sm.stateMachineArn,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
new integ.IntegTest(app, 'EvaluateExpressionArm64Test', {
|
|
26
|
+
testCases: [stack],
|
|
27
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { App, Stack } from 'aws-cdk-lib';
|
|
2
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
3
|
+
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
|
|
4
|
+
import * as cdk from 'aws-cdk-lib';
|
|
5
|
+
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
|
|
6
|
+
|
|
7
|
+
const app = new App();
|
|
8
|
+
const stack = new Stack(app, 'aws-cdk-sfn-evaluate-expression-default-integ');
|
|
9
|
+
|
|
10
|
+
const evaluateExpression = new tasks.EvaluateExpression(stack, 'EvaluateExpression', {
|
|
11
|
+
expression: '$.a + $.b',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const sm = new sfn.StateMachine(stack, 'StateMachine', {
|
|
15
|
+
definitionBody: sfn.DefinitionBody.fromChainable(evaluateExpression),
|
|
16
|
+
timeout: cdk.Duration.seconds(30),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
new cdk.CfnOutput(stack, 'stateMachineArn', {
|
|
20
|
+
value: sm.stateMachineArn,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
new integ.IntegTest(app, 'EvaluateExpressionDefaultTest', {
|
|
24
|
+
testCases: [stack],
|
|
25
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
2
|
+
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
|
|
3
|
+
import * as cdk from 'aws-cdk-lib';
|
|
4
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
5
|
+
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
|
|
6
|
+
|
|
7
|
+
const app = new cdk.App();
|
|
8
|
+
const stack = new cdk.Stack(app, 'aws-cdk-sfn-evaluate-expression-mixed-arch-integ');
|
|
9
|
+
|
|
10
|
+
const evalTaskArm = new tasks.EvaluateExpression(stack, 'EvalExpressionArm', {
|
|
11
|
+
expression: '$.a + $.b',
|
|
12
|
+
runtime: lambda.Runtime.NODEJS_20_X,
|
|
13
|
+
architecture: lambda.Architecture.ARM_64,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const evalTaskX86 = new tasks.EvaluateExpression(stack, 'EvalExpressionX86', {
|
|
17
|
+
expression: '$.a * $.b',
|
|
18
|
+
runtime: lambda.Runtime.NODEJS_20_X,
|
|
19
|
+
architecture: lambda.Architecture.X86_64,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const definition = new sfn.Pass(stack, 'Start', {
|
|
23
|
+
result: sfn.Result.fromObject({ a: 3, b: 4 }),
|
|
24
|
+
}).next(new sfn.Parallel(stack, 'ParallelEval')
|
|
25
|
+
.branch(evalTaskArm)
|
|
26
|
+
.branch(evalTaskX86),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
new sfn.StateMachine(stack, 'StateMachine', {
|
|
30
|
+
definitionBody: sfn.DefinitionBody.fromChainable(definition),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
new integ.IntegTest(app, 'EvaluateExpressionMixedArchTest', {
|
|
34
|
+
testCases: [stack],
|
|
35
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { App, Stack } from 'aws-cdk-lib';
|
|
2
|
+
import * as integ from '@aws-cdk/integ-tests-alpha';
|
|
3
|
+
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
|
|
4
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
5
|
+
import * as cdk from 'aws-cdk-lib';
|
|
6
|
+
import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
|
|
7
|
+
|
|
8
|
+
const app = new App();
|
|
9
|
+
const stack = new Stack(app, 'aws-cdk-sfn-evaluate-expression-x86-integ');
|
|
10
|
+
|
|
11
|
+
const evaluateExpression = new tasks.EvaluateExpression(stack, 'EvaluateExpression', {
|
|
12
|
+
expression: '$.a + $.b',
|
|
13
|
+
architecture: lambda.Architecture.X86_64,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const sm = new sfn.StateMachine(stack, 'StateMachine', {
|
|
17
|
+
definitionBody: sfn.DefinitionBody.fromChainable(evaluateExpression),
|
|
18
|
+
timeout: cdk.Duration.seconds(30),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
new cdk.CfnOutput(stack, 'stateMachineArn', {
|
|
22
|
+
value: sm.stateMachineArn,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
new integ.IntegTest(app, 'EvaluateExpressionX86Test', {
|
|
26
|
+
testCases: [stack],
|
|
27
|
+
});
|
|
@@ -831,6 +831,62 @@ new cr.AwsCustomResource(this, 'CrossAccount', {
|
|
|
831
831
|
});
|
|
832
832
|
```
|
|
833
833
|
|
|
834
|
+
#### Using External IDs for Enhanced Security
|
|
835
|
+
|
|
836
|
+
When assuming cross-account roles, you can specify an external ID to prevent the "confused deputy" problem. The external ID is a unique identifier provided by the third-party service that helps ensure the service is acting on behalf of the correct customer:
|
|
837
|
+
|
|
838
|
+
```ts
|
|
839
|
+
const crossAccountRoleArn = 'arn:aws:iam::OTHERACCOUNT:role/CrossAccountRoleName';
|
|
840
|
+
const serviceExternalId = 'unique-secret-value-12345'; // External ID provided by the third party service. This value should be unique among the third-party service's customers.
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
new cr.AwsCustomResource(this, 'SecureCrossAccount', {
|
|
844
|
+
onCreate: {
|
|
845
|
+
assumedRoleArn: crossAccountRoleArn,
|
|
846
|
+
externalId: serviceExternalId, // Prevents confused deputy attacks
|
|
847
|
+
service: 'sts',
|
|
848
|
+
action: 'GetCallerIdentity',
|
|
849
|
+
physicalResourceId: cr.PhysicalResourceId.of('id'),
|
|
850
|
+
},
|
|
851
|
+
policy: cr.AwsCustomResourcePolicy.fromStatements([iam.PolicyStatement.fromJson({
|
|
852
|
+
Effect: "Allow",
|
|
853
|
+
Action: "sts:AssumeRole",
|
|
854
|
+
Resource: crossAccountRoleArn,
|
|
855
|
+
})]),
|
|
856
|
+
});
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
The external ID can also be different for each lifecycle operation:
|
|
860
|
+
|
|
861
|
+
```ts
|
|
862
|
+
declare const createRoleArn: string;
|
|
863
|
+
declare const updateRoleArn: string;
|
|
864
|
+
|
|
865
|
+
new cr.AwsCustomResource(this, 'MultiRoleSecure', {
|
|
866
|
+
onCreate: {
|
|
867
|
+
assumedRoleArn: createRoleArn,
|
|
868
|
+
externalId: 'create-secret-123',
|
|
869
|
+
service: 'ec2',
|
|
870
|
+
action: 'DescribeInstances',
|
|
871
|
+
physicalResourceId: cr.PhysicalResourceId.of('id'),
|
|
872
|
+
},
|
|
873
|
+
onUpdate: {
|
|
874
|
+
assumedRoleArn: updateRoleArn,
|
|
875
|
+
externalId: 'update-secret-456',
|
|
876
|
+
service: 'ec2',
|
|
877
|
+
action: 'DescribeInstances',
|
|
878
|
+
},
|
|
879
|
+
policy: cr.AwsCustomResourcePolicy.fromStatements([
|
|
880
|
+
new iam.PolicyStatement({
|
|
881
|
+
actions: ['sts:AssumeRole'],
|
|
882
|
+
resources: [createRoleArn, updateRoleArn],
|
|
883
|
+
}),
|
|
884
|
+
]),
|
|
885
|
+
});
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
For more information on external IDs and preventing confused deputy attacks, see the [AWS IAM User Guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html).
|
|
889
|
+
|
|
834
890
|
#### Custom Resource Config
|
|
835
891
|
|
|
836
892
|
**This feature is currently experimental**
|
cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/custom-resources/integ.external-id.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
3
|
+
import * as cdk from 'aws-cdk-lib';
|
|
4
|
+
import { IntegTest } from '@aws-cdk/integ-tests-alpha';
|
|
5
|
+
import { AwsCustomResource, AwsCustomResourcePolicy, PhysicalResourceId } from 'aws-cdk-lib/custom-resources';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Integration test for AwsCustomResource External ID support.
|
|
9
|
+
*
|
|
10
|
+
* This test demonstrates the use of external IDs when assuming roles
|
|
11
|
+
* in cross-account scenarios to prevent "confused deputy" attacks.
|
|
12
|
+
*
|
|
13
|
+
* Note: This test may introduce destructive changes to CDK metadata
|
|
14
|
+
* and Lambda function assets due to CDK version updates. These changes
|
|
15
|
+
* are expected and safe for integration testing purposes.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const app = new cdk.App({
|
|
19
|
+
postCliContext: {
|
|
20
|
+
// Disable CDK managed log groups to prevent Lambda changes
|
|
21
|
+
'@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
|
|
22
|
+
// Disable version reporting to prevent CDK metadata changes
|
|
23
|
+
'@aws-cdk/core:disableVersionReporting': true,
|
|
24
|
+
// Disable new style synthesis to maintain compatibility
|
|
25
|
+
'@aws-cdk/core:newStyleStackSynthesis': false,
|
|
26
|
+
// Use legacy asset bundling to prevent asset hash changes
|
|
27
|
+
'@aws-cdk/core:enableLegacyV2AssetKeys': true,
|
|
28
|
+
// Disable stack name validation to prevent naming conflicts
|
|
29
|
+
'@aws-cdk/core:stackRelativeExports': false,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const stack = new cdk.Stack(app, 'aws-custom-resource-external-id-test');
|
|
34
|
+
|
|
35
|
+
// Create a role that requires an external ID
|
|
36
|
+
const externalId = 'test-external-id-12345';
|
|
37
|
+
const roleWithExternalId = new iam.Role(stack, 'RoleWithExternalId', {
|
|
38
|
+
// Use a principal that can be used in integration tests
|
|
39
|
+
assumedBy: new iam.AccountPrincipal(cdk.Stack.of(stack).account),
|
|
40
|
+
externalIds: [externalId],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Add the necessary permissions as managed policies to reduce template variability
|
|
44
|
+
roleWithExternalId.addToPolicy(
|
|
45
|
+
new iam.PolicyStatement({
|
|
46
|
+
actions: ['sts:GetCallerIdentity'],
|
|
47
|
+
resources: ['*'],
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Test basic external ID usage
|
|
52
|
+
new AwsCustomResource(stack, 'ExternalIdTest', {
|
|
53
|
+
installLatestAwsSdk: false,
|
|
54
|
+
onCreate: {
|
|
55
|
+
assumedRoleArn: roleWithExternalId.roleArn,
|
|
56
|
+
externalId: externalId,
|
|
57
|
+
service: 'STS',
|
|
58
|
+
action: 'GetCallerIdentity',
|
|
59
|
+
physicalResourceId: PhysicalResourceId.of('external-id-test'),
|
|
60
|
+
},
|
|
61
|
+
policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: [] }),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
new IntegTest(app, 'AwsCustomResourceTest', {
|
|
65
|
+
testCases: [stack],
|
|
66
|
+
diffAssets: true,
|
|
67
|
+
allowDestroy: ['AWS::CDK::Metadata'],
|
|
68
|
+
cdkCommandOptions: {
|
|
69
|
+
deploy: {
|
|
70
|
+
args: {
|
|
71
|
+
rollback: false,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
destroy: {
|
|
75
|
+
args: {
|
|
76
|
+
force: true,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
CDK Resource Interfaces
|
|
2
|
+
=======================
|
|
3
|
+
|
|
4
|
+
This module contains resource interfaces for all AWS service resources.
|
|
5
|
+
|
|
6
|
+
These are interfaces that look like this:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
/**
|
|
10
|
+
* Indicates that this resource can be referenced as a Bucket.
|
|
11
|
+
*/
|
|
12
|
+
interface IBucketRef {
|
|
13
|
+
/**
|
|
14
|
+
* A reference to a Bucket resource.
|
|
15
|
+
*/
|
|
16
|
+
readonly bucketRef: BucketReference;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface BucketReference {
|
|
20
|
+
/**
|
|
21
|
+
* The BucketName of the Bucket resource.
|
|
22
|
+
*/
|
|
23
|
+
readonly bucketName: string;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The ARN of the Bucket resource.
|
|
27
|
+
*/
|
|
28
|
+
readonly bucketArn: string;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
These are in a separate submodule so that they can be referenced from all other
|
|
33
|
+
service submodules without introducing cyclic dependencies between them.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: konokenj.cdk-api-mcp-server
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.55.0
|
|
4
4
|
Summary: An MCP server provides AWS CDK API Reference
|
|
5
5
|
Project-URL: Documentation, https://github.com/konokenj/cdk-api-mcp-server#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/konokenj/cdk-api-mcp-server/issues
|
|
@@ -26,7 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
[](https://pypi.org/project/konokenj.cdk-api-mcp-server)
|
|
27
27
|
|
|
28
28
|
<!-- DEP-VERSIONS-START -->
|
|
29
|
-
[](https://github.com/konokenj/cdk-api-mcp-server/blob/main/current-versions/aws-cdk.txt)
|
|
30
30
|
<!-- DEP-VERSIONS-END -->
|
|
31
31
|
|
|
32
32
|
---
|