@intentius/chant-lexicon-aws 0.18.16 → 0.18.17
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.
- package/dist/components/cloud-executor.d.ts +17 -0
- package/dist/components/cloud-executor.d.ts.map +1 -1
- package/dist/composites/agentcore-agent.d.ts.map +1 -1
- package/dist/generated/index.d.ts +2 -1
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/integrity.json +4 -4
- package/dist/intrinsics.d.ts +5 -4
- package/dist/intrinsics.d.ts.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/meta.json +15 -6
- package/dist/serializer.d.ts.map +1 -1
- package/dist/types/index.d.ts +31 -17
- package/package.json +2 -2
- package/src/components/cloud-executor.test.ts +21 -1
- package/src/components/cloud-executor.ts +21 -6
- package/src/composites/agentcore-agent.test.ts +12 -0
- package/src/composites/agentcore-agent.ts +5 -1
- package/src/generated/index.d.ts +31 -17
- package/src/generated/index.ts +3 -2
- package/src/generated/lexicon-aws.json +15 -6
- package/src/intrinsics.test.ts +16 -0
- package/src/intrinsics.ts +20 -7
- package/src/serializer.test.ts +52 -1
- package/src/serializer.ts +51 -14
package/dist/integrity.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
5
|
-
"meta.json": "
|
|
6
|
-
"types/index.d.ts": "
|
|
4
|
+
"manifest.json": "217158f543f70284b4839d43754abbdbffa089322abc5274655c0fb6ef7ee584",
|
|
5
|
+
"meta.json": "956ce9e79ca7bc2b9f5169a2a4418207e8c58da478435116c25867d909209d3f",
|
|
6
|
+
"types/index.d.ts": "25b58838c3895ad9ba9e5f5e24af38c43df112703d5315ce0efea9bfc9aa40d5",
|
|
7
7
|
"rules/hardcoded-region.ts": "5a0eaf7ab391231fe6cd51426ece29539cb4b36f31c8dd060956638fed55722a",
|
|
8
8
|
"rules/iam-wildcard.ts": "135d7217d278fef50939e605c5da32603ba35674b8c4b5c4d66a06c77903e945",
|
|
9
9
|
"rules/s3-encryption.ts": "c4f9f8aa8dc382ed98c7b04e820a600590cc75335a8db2e087cbfbfe4003d09e",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"skills/chant-aws.md": "4d65eb160e001f2af42eb7c622a5b498c2fd1f5afbd6c8155615c010fb265c63",
|
|
59
59
|
"skills/chant-aws-eks.md": "8789255709ff004ad0a875fd5999edcdc66fc6e33d710db058d9f42703bcfdfe"
|
|
60
60
|
},
|
|
61
|
-
"composite": "
|
|
61
|
+
"composite": "fc4e487d0f9d9159f025788277385185cd9c4f9b13f6c2e2d037500e3a8dcd51"
|
|
62
62
|
}
|
package/dist/intrinsics.d.ts
CHANGED
|
@@ -80,15 +80,16 @@ export declare class JoinIntrinsic implements Intrinsic {
|
|
|
80
80
|
readonly [INTRINSIC_MARKER]: true;
|
|
81
81
|
private delimiter;
|
|
82
82
|
private values;
|
|
83
|
-
constructor(delimiter: string, values: unknown[]);
|
|
83
|
+
constructor(delimiter: string, values: unknown[] | Intrinsic);
|
|
84
84
|
toJSON(): {
|
|
85
|
-
"Fn::Join": [string, unknown
|
|
85
|
+
"Fn::Join": [string, unknown];
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
|
-
* Create a Join intrinsic
|
|
89
|
+
* Create a Join intrinsic. `values` is a literal array, or a single
|
|
90
|
+
* list-returning intrinsic (e.g. `Join(",", zone.NameServers)`).
|
|
90
91
|
*/
|
|
91
|
-
export declare function Join(delimiter: string, values: unknown[]): JoinIntrinsic;
|
|
92
|
+
export declare function Join(delimiter: string, values: unknown[] | Intrinsic): JoinIntrinsic;
|
|
92
93
|
/**
|
|
93
94
|
* Fn::Select intrinsic function
|
|
94
95
|
* Selects a value from a list by index
|
package/dist/intrinsics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../src/intrinsics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../src/intrinsics.ts"],"names":[],"mappings":"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"}
|
package/dist/manifest.json
CHANGED
package/dist/meta.json
CHANGED
|
@@ -5045,6 +5045,11 @@
|
|
|
5045
5045
|
"kind": "property",
|
|
5046
5046
|
"lexicon": "aws"
|
|
5047
5047
|
},
|
|
5048
|
+
"AppConfiguration": {
|
|
5049
|
+
"resourceType": "AWS::EMR::InstanceGroupConfig.AppConfiguration",
|
|
5050
|
+
"kind": "property",
|
|
5051
|
+
"lexicon": "aws"
|
|
5052
|
+
},
|
|
5048
5053
|
"AppCookieStickinessPolicy": {
|
|
5049
5054
|
"resourceType": "AWS::ElasticLoadBalancing::LoadBalancer.AppCookieStickinessPolicy",
|
|
5050
5055
|
"kind": "property",
|
|
@@ -48824,7 +48829,7 @@
|
|
|
48824
48829
|
"kind": "resource",
|
|
48825
48830
|
"lexicon": "aws",
|
|
48826
48831
|
"attrs": {
|
|
48827
|
-
"
|
|
48832
|
+
"InstanceGroupId": "InstanceGroupId"
|
|
48828
48833
|
},
|
|
48829
48834
|
"createOnly": [
|
|
48830
48835
|
"InstanceRole",
|
|
@@ -48837,17 +48842,21 @@
|
|
|
48837
48842
|
"Market",
|
|
48838
48843
|
"BidPrice"
|
|
48839
48844
|
],
|
|
48845
|
+
"writeOnly": [
|
|
48846
|
+
"EbsConfiguration/EbsBlockDeviceConfigs/*/VolumesPerInstance"
|
|
48847
|
+
],
|
|
48840
48848
|
"primaryIdentifier": [
|
|
48841
|
-
"
|
|
48849
|
+
"InstanceGroupId",
|
|
48850
|
+
"JobFlowId"
|
|
48842
48851
|
]
|
|
48843
48852
|
},
|
|
48844
|
-
"
|
|
48845
|
-
"resourceType": "AWS::EMR::InstanceGroupConfig.
|
|
48853
|
+
"InstanceGroupConfig_AppConfiguration": {
|
|
48854
|
+
"resourceType": "AWS::EMR::InstanceGroupConfig.AppConfiguration",
|
|
48846
48855
|
"kind": "property",
|
|
48847
48856
|
"lexicon": "aws"
|
|
48848
48857
|
},
|
|
48849
|
-
"
|
|
48850
|
-
"resourceType": "AWS::EMR::InstanceGroupConfig.
|
|
48858
|
+
"InstanceGroupConfig_AutoScalingPolicy": {
|
|
48859
|
+
"resourceType": "AWS::EMR::InstanceGroupConfig.AutoScalingPolicy",
|
|
48851
48860
|
"kind": "property",
|
|
48852
48861
|
"lexicon": "aws"
|
|
48853
48862
|
},
|
package/dist/serializer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAsC,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAsC,MAAM,6BAA6B,CAAC;AA2WlG;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,UAoE3B,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -17601,14 +17601,14 @@ export declare class InstanceGroupConfig {
|
|
|
17601
17601
|
JobFlowId: string;
|
|
17602
17602
|
AutoScalingPolicy?: InstanceGroupConfig_AutoScalingPolicy;
|
|
17603
17603
|
BidPrice?: string;
|
|
17604
|
-
Configurations?:
|
|
17604
|
+
Configurations?: InstanceGroupConfig_AppConfiguration[];
|
|
17605
17605
|
CustomAmiId?: string;
|
|
17606
17606
|
EbsConfiguration?: InstanceGroupConfig_EbsConfiguration;
|
|
17607
|
-
|
|
17607
|
+
InstanceGroupId?: string;
|
|
17608
17608
|
Market?: string;
|
|
17609
17609
|
Name?: string;
|
|
17610
17610
|
}, attributes?: CFResourceAttributes);
|
|
17611
|
-
readonly
|
|
17611
|
+
readonly InstanceGroupId: string;
|
|
17612
17612
|
}
|
|
17613
17613
|
|
|
17614
17614
|
export declare class InstanceProfile {
|
|
@@ -41403,6 +41403,14 @@ export declare class AppConfigResourceObject {
|
|
|
41403
41403
|
});
|
|
41404
41404
|
}
|
|
41405
41405
|
|
|
41406
|
+
export declare class AppConfiguration {
|
|
41407
|
+
constructor(props: {
|
|
41408
|
+
Classification?: string;
|
|
41409
|
+
ConfigurationProperties?: Record<string, unknown>;
|
|
41410
|
+
Configurations?: InstanceGroupConfig_AppConfiguration[];
|
|
41411
|
+
});
|
|
41412
|
+
}
|
|
41413
|
+
|
|
41406
41414
|
export declare class AppCookieStickinessPolicy {
|
|
41407
41415
|
constructor(props: {
|
|
41408
41416
|
/** The name of the application cookie used for stickiness. */
|
|
@@ -78935,24 +78943,26 @@ export declare class InstanceFleetConfig_SpotResizingSpecification {
|
|
|
78935
78943
|
});
|
|
78936
78944
|
}
|
|
78937
78945
|
|
|
78938
|
-
export declare class
|
|
78946
|
+
export declare class InstanceGroupConfig_AppConfiguration {
|
|
78939
78947
|
constructor(props: {
|
|
78940
|
-
|
|
78941
|
-
|
|
78948
|
+
Classification?: string;
|
|
78949
|
+
ConfigurationProperties?: Record<string, unknown>;
|
|
78950
|
+
Configurations?: InstanceGroupConfig_AppConfiguration[];
|
|
78942
78951
|
});
|
|
78943
78952
|
}
|
|
78944
78953
|
|
|
78945
|
-
export declare class
|
|
78954
|
+
export declare class InstanceGroupConfig_AutoScalingPolicy {
|
|
78946
78955
|
constructor(props: {
|
|
78947
|
-
|
|
78948
|
-
|
|
78949
|
-
Configurations?: InstanceGroupConfig_Configuration[];
|
|
78956
|
+
Constraints: InstanceGroupConfig_ScalingConstraints;
|
|
78957
|
+
Rules: InstanceGroupConfig_ScalingRule[];
|
|
78950
78958
|
});
|
|
78951
78959
|
}
|
|
78952
78960
|
|
|
78953
78961
|
export declare class InstanceGroupConfig_EbsBlockDeviceConfig {
|
|
78954
78962
|
constructor(props: {
|
|
78955
78963
|
VolumeSpecification: InstanceGroupConfig_VolumeSpecification;
|
|
78964
|
+
/** Use of this property can confuse CloudFormation drift detection. The EbsBlockDeviceConfigs read from the system may return a list with one entry per volume, replacing any entry specified in the template with a VolumesPerInstance greater than one by that many entries containing only the VolumeSpecification. Thus to avoid false drift detection, it is recommended to supply repeated entries in EbsBlockDeviceConfigs for any VolumeSpecification which is intended to be repeated and not to use this property.
|
|
78965
|
+
*/
|
|
78956
78966
|
VolumesPerInstance?: number;
|
|
78957
78967
|
});
|
|
78958
78968
|
}
|
|
@@ -85949,10 +85959,10 @@ export declare class LogAlarm_ScheduleConfiguration {
|
|
|
85949
85959
|
constructor(props: {
|
|
85950
85960
|
/** The expression that defines when the scheduled query runs, e.g. rate(1 minute). */
|
|
85951
85961
|
ScheduleExpression: string;
|
|
85952
|
-
/** The number of seconds into the past to
|
|
85962
|
+
/** The number of seconds into the past to start the query window. Must be a positive value and cannot exceed 2592000 seconds (30 days). */
|
|
85963
|
+
StartTimeOffset: number;
|
|
85964
|
+
/** The number of seconds into the past to end the query window. Must be a non-negative value and cannot exceed 2592000 seconds (30 days). */
|
|
85953
85965
|
EndTimeOffset?: number;
|
|
85954
|
-
/** The number of seconds into the past to start the query window. */
|
|
85955
|
-
StartTimeOffset?: number;
|
|
85956
85966
|
});
|
|
85957
85967
|
}
|
|
85958
85968
|
|
|
@@ -85960,14 +85970,16 @@ export declare class LogAlarm_ScheduledQueryConfiguration {
|
|
|
85960
85970
|
constructor(props: {
|
|
85961
85971
|
/** The aggregation expression for the scheduled query, e.g. count(*) or avg(latency) by host. */
|
|
85962
85972
|
AggregationExpression: string;
|
|
85963
|
-
/** The log groups to query. */
|
|
85964
|
-
LogGroupIdentifiers: string[];
|
|
85965
85973
|
/** The query string to execute against the specified log groups. */
|
|
85966
85974
|
QueryString: string;
|
|
85967
85975
|
/** The schedule configuration. */
|
|
85968
85976
|
ScheduleConfiguration: LogAlarm_ScheduleConfiguration;
|
|
85969
85977
|
/** The ARN of the IAM role that grants permissions to execute the scheduled query. */
|
|
85970
85978
|
ScheduledQueryRoleARN: string;
|
|
85979
|
+
/** The log groups to query. */
|
|
85980
|
+
LogGroupIdentifiers?: string[];
|
|
85981
|
+
/** A list of key-value pairs to associate with the scheduled query that backs the log alarm. */
|
|
85982
|
+
Tags?: LogAlarm_Tag[];
|
|
85971
85983
|
});
|
|
85972
85984
|
}
|
|
85973
85985
|
|
|
@@ -109455,14 +109467,16 @@ export declare class ScheduledQueryConfiguration {
|
|
|
109455
109467
|
constructor(props: {
|
|
109456
109468
|
/** The aggregation expression for the scheduled query, e.g. count(*) or avg(latency) by host. */
|
|
109457
109469
|
AggregationExpression: string;
|
|
109458
|
-
/** The log groups to query. */
|
|
109459
|
-
LogGroupIdentifiers: string[];
|
|
109460
109470
|
/** The query string to execute against the specified log groups. */
|
|
109461
109471
|
QueryString: string;
|
|
109462
109472
|
/** The schedule configuration. */
|
|
109463
109473
|
ScheduleConfiguration: LogAlarm_ScheduleConfiguration;
|
|
109464
109474
|
/** The ARN of the IAM role that grants permissions to execute the scheduled query. */
|
|
109465
109475
|
ScheduledQueryRoleARN: string;
|
|
109476
|
+
/** The log groups to query. */
|
|
109477
|
+
LogGroupIdentifiers?: string[];
|
|
109478
|
+
/** A list of key-value pairs to associate with the scheduled query that backs the log alarm. */
|
|
109479
|
+
Tags?: LogAlarm_Tag[];
|
|
109466
109480
|
});
|
|
109467
109481
|
}
|
|
109468
109482
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-aws",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.17",
|
|
4
4
|
"description": "AWS CloudFormation lexicon for chant — declarative IaC in TypeScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"typescript": "^5.9.3"
|
|
81
81
|
},
|
|
82
82
|
"peerDependencies": {
|
|
83
|
-
"@intentius/chant": "^0.18.
|
|
83
|
+
"@intentius/chant": "^0.18.17",
|
|
84
84
|
"typescript": "^5.9.3"
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import { describe, test, expect } from "vitest";
|
|
2
|
-
import { applyAwsEndpoint, applyAwsEndpointArgv } from "./cloud-executor";
|
|
2
|
+
import { applyAwsEndpoint, applyAwsEndpointArgv, ecsDeploymentId, ecsServiceStable } from "./cloud-executor";
|
|
3
|
+
|
|
4
|
+
describe("ecsDeploymentId / ecsServiceStable — tolerate Floci's missing deployments (#937)", () => {
|
|
5
|
+
test("deployment id: real AWS shape", () => {
|
|
6
|
+
expect(ecsDeploymentId({ service: { deployments: [{ id: "ecs-svc/123" }] } })).toBe("ecs-svc/123");
|
|
7
|
+
});
|
|
8
|
+
test("deployment id: Floci omits `deployments` entirely → '' (no crash)", () => {
|
|
9
|
+
expect(ecsDeploymentId({ service: {} })).toBe("");
|
|
10
|
+
expect(ecsDeploymentId({ service: { deployments: [] } })).toBe("");
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test("stable: running==desired with ≤1 deployment", () => {
|
|
14
|
+
expect(ecsServiceStable({ runningCount: 2, desiredCount: 2, deployments: [{}] })).toBe(true);
|
|
15
|
+
expect(ecsServiceStable({ runningCount: 1, desiredCount: 2, deployments: [{}] })).toBe(false);
|
|
16
|
+
expect(ecsServiceStable({ runningCount: 2, desiredCount: 2, deployments: [{}, {}] })).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
test("stable: Floci omits `deployments` → treated as 0, no crash", () => {
|
|
19
|
+
expect(ecsServiceStable({ runningCount: 2, desiredCount: 2 })).toBe(true);
|
|
20
|
+
expect(ecsServiceStable(undefined)).toBe(true); // 0 == 0
|
|
21
|
+
});
|
|
22
|
+
});
|
|
3
23
|
|
|
4
24
|
describe("applyAwsEndpoint", () => {
|
|
5
25
|
const url = "http://localhost:4566";
|
|
@@ -463,6 +463,23 @@ const realCloudFormation: CloudFormationClient = {
|
|
|
463
463
|
},
|
|
464
464
|
};
|
|
465
465
|
|
|
466
|
+
/** Deployment id from an ECS `update-service` response. Tolerant of Floci, whose
|
|
467
|
+
* `service` omits `deployments` entirely (real AWS always includes it) — guards
|
|
468
|
+
* the index, not just `.id` (#937). Exported for testing. */
|
|
469
|
+
export function ecsDeploymentId(described: { service: { deployments?: Array<{ id: string }> } }): string {
|
|
470
|
+
return described.service.deployments?.[0]?.id ?? "";
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/** Whether an ECS service is steady (running == desired, ≤1 active deployment).
|
|
474
|
+
* Tolerant of Floci's missing `deployments` field. Exported for testing. */
|
|
475
|
+
export function ecsServiceStable(
|
|
476
|
+
svc: { runningCount?: number; desiredCount?: number; deployments?: unknown[] } | undefined,
|
|
477
|
+
): boolean {
|
|
478
|
+
const running = svc?.runningCount ?? 0;
|
|
479
|
+
const desired = svc?.desiredCount ?? 0;
|
|
480
|
+
return running === desired && (svc?.deployments?.length ?? 0) <= 1;
|
|
481
|
+
}
|
|
482
|
+
|
|
466
483
|
const realEcs: EcsClient = {
|
|
467
484
|
async updateService(args) {
|
|
468
485
|
const parts = [`aws ecs update-service`, `--cluster ${q(args.cluster)}`, `--service ${q(args.service)}`];
|
|
@@ -470,20 +487,18 @@ const realEcs: EcsClient = {
|
|
|
470
487
|
if (args.desiredCount !== undefined) parts.push(`--desired-count ${args.desiredCount}`);
|
|
471
488
|
if (args.forceNewDeployment) parts.push(`--force-new-deployment`);
|
|
472
489
|
const { stdout } = await run(parts.join(" "));
|
|
473
|
-
const described = JSON.parse(stdout) as { service: { deployments
|
|
474
|
-
return { deploymentId: described
|
|
490
|
+
const described = JSON.parse(stdout) as { service: { deployments?: Array<{ id: string }> } };
|
|
491
|
+
return { deploymentId: ecsDeploymentId(described) };
|
|
475
492
|
},
|
|
476
493
|
async describeService(cluster, service) {
|
|
477
494
|
const { stdout } = await run(
|
|
478
495
|
`aws ecs describe-services --cluster ${q(cluster)} --services ${q(service)}`,
|
|
479
496
|
);
|
|
480
497
|
const described = JSON.parse(stdout) as {
|
|
481
|
-
services: Array<{ runningCount: number; desiredCount: number; deployments
|
|
498
|
+
services: Array<{ runningCount: number; desiredCount: number; deployments?: unknown[] }>;
|
|
482
499
|
};
|
|
483
500
|
const svc = described.services[0];
|
|
484
|
-
|
|
485
|
-
const desired = svc?.desiredCount ?? 0;
|
|
486
|
-
return { runningCount: running, desiredCount: desired, stable: running === desired && (svc?.deployments.length ?? 0) <= 1 };
|
|
501
|
+
return { runningCount: svc?.runningCount ?? 0, desiredCount: svc?.desiredCount ?? 0, stable: ecsServiceStable(svc) };
|
|
487
502
|
},
|
|
488
503
|
async rollbackService(args) {
|
|
489
504
|
await realEcs.updateService(args);
|
|
@@ -7,6 +7,7 @@ import { AttrRef } from "@intentius/chant/attrref";
|
|
|
7
7
|
// precedent for aws-lexicon integration-style tests.
|
|
8
8
|
import { resolveAttrRefs } from "../../../../packages/core/src/discovery/resolve";
|
|
9
9
|
import { AgentCoreAgent } from "./agentcore-agent";
|
|
10
|
+
import { Split, Ref } from "../intrinsics";
|
|
10
11
|
import { awsSerializer } from "../serializer";
|
|
11
12
|
|
|
12
13
|
const baseProps = {
|
|
@@ -104,6 +105,17 @@ describe("AgentCoreAgent", () => {
|
|
|
104
105
|
);
|
|
105
106
|
});
|
|
106
107
|
|
|
108
|
+
test("VPC mode accepts a cross-stack intrinsic (Fn::Split) — checks presence, not .length (#938)", () => {
|
|
109
|
+
// A cross-stack value (Split of a Parameter) is a truthy intrinsic with no
|
|
110
|
+
// `.length`; it WAS supplied, so the composite must not reject it.
|
|
111
|
+
const subnets = Split(",", Ref("SubnetIdsParam")) as unknown as string[];
|
|
112
|
+
const sgs = Split(",", Ref("SgIdsParam")) as unknown as string[];
|
|
113
|
+
const instance = AgentCoreAgent({ ...baseProps, networkMode: "VPC", vpcSubnetIds: subnets, vpcSecurityGroupIds: sgs });
|
|
114
|
+
const vpcConfigProps = ((instance.runtime as any).props.NetworkConfiguration as any).props.NetworkModeConfig.props;
|
|
115
|
+
expect(vpcConfigProps.Subnets).toBe(subnets);
|
|
116
|
+
expect(vpcConfigProps.SecurityGroups).toBe(sgs);
|
|
117
|
+
});
|
|
118
|
+
|
|
107
119
|
test("throws when memoryEventExpiryDays is out of CFN bounds (3-365)", () => {
|
|
108
120
|
expect(() => AgentCoreAgent({ ...baseProps, memoryEventExpiryDays: 1 })).toThrow(
|
|
109
121
|
"AgentCoreAgent memoryEventExpiryDays must be between 3 and 365",
|
|
@@ -107,7 +107,11 @@ export type AgentCoreAgentResult = {
|
|
|
107
107
|
export const AgentCoreAgent = Composite<AgentCoreAgentProps, AgentCoreAgentResult>((props) => {
|
|
108
108
|
const { defaults } = props;
|
|
109
109
|
const networkMode = props.networkMode ?? "PUBLIC";
|
|
110
|
-
|
|
110
|
+
// Check presence, not `.length`: a cross-stack value (Fn::Split of a Parameter,
|
|
111
|
+
// the shape stackOutput/Ref/Split produce) is a truthy intrinsic object with no
|
|
112
|
+
// `.length`, so a `.length` check wrongly rejects a value that WAS supplied
|
|
113
|
+
// (#938). An actually-empty list is caught by CloudFormation at deploy time.
|
|
114
|
+
if (networkMode === "VPC" && (props.vpcSubnetIds === undefined || props.vpcSecurityGroupIds === undefined)) {
|
|
111
115
|
throw new Error("AgentCoreAgent requires vpcSubnetIds and vpcSecurityGroupIds when networkMode is \"VPC\"");
|
|
112
116
|
}
|
|
113
117
|
const memoryEventExpiryDays = props.memoryEventExpiryDays ?? 30;
|
package/src/generated/index.d.ts
CHANGED
|
@@ -17601,14 +17601,14 @@ export declare class InstanceGroupConfig {
|
|
|
17601
17601
|
JobFlowId: string;
|
|
17602
17602
|
AutoScalingPolicy?: InstanceGroupConfig_AutoScalingPolicy;
|
|
17603
17603
|
BidPrice?: string;
|
|
17604
|
-
Configurations?:
|
|
17604
|
+
Configurations?: InstanceGroupConfig_AppConfiguration[];
|
|
17605
17605
|
CustomAmiId?: string;
|
|
17606
17606
|
EbsConfiguration?: InstanceGroupConfig_EbsConfiguration;
|
|
17607
|
-
|
|
17607
|
+
InstanceGroupId?: string;
|
|
17608
17608
|
Market?: string;
|
|
17609
17609
|
Name?: string;
|
|
17610
17610
|
}, attributes?: CFResourceAttributes);
|
|
17611
|
-
readonly
|
|
17611
|
+
readonly InstanceGroupId: string;
|
|
17612
17612
|
}
|
|
17613
17613
|
|
|
17614
17614
|
export declare class InstanceProfile {
|
|
@@ -41403,6 +41403,14 @@ export declare class AppConfigResourceObject {
|
|
|
41403
41403
|
});
|
|
41404
41404
|
}
|
|
41405
41405
|
|
|
41406
|
+
export declare class AppConfiguration {
|
|
41407
|
+
constructor(props: {
|
|
41408
|
+
Classification?: string;
|
|
41409
|
+
ConfigurationProperties?: Record<string, unknown>;
|
|
41410
|
+
Configurations?: InstanceGroupConfig_AppConfiguration[];
|
|
41411
|
+
});
|
|
41412
|
+
}
|
|
41413
|
+
|
|
41406
41414
|
export declare class AppCookieStickinessPolicy {
|
|
41407
41415
|
constructor(props: {
|
|
41408
41416
|
/** The name of the application cookie used for stickiness. */
|
|
@@ -78935,24 +78943,26 @@ export declare class InstanceFleetConfig_SpotResizingSpecification {
|
|
|
78935
78943
|
});
|
|
78936
78944
|
}
|
|
78937
78945
|
|
|
78938
|
-
export declare class
|
|
78946
|
+
export declare class InstanceGroupConfig_AppConfiguration {
|
|
78939
78947
|
constructor(props: {
|
|
78940
|
-
|
|
78941
|
-
|
|
78948
|
+
Classification?: string;
|
|
78949
|
+
ConfigurationProperties?: Record<string, unknown>;
|
|
78950
|
+
Configurations?: InstanceGroupConfig_AppConfiguration[];
|
|
78942
78951
|
});
|
|
78943
78952
|
}
|
|
78944
78953
|
|
|
78945
|
-
export declare class
|
|
78954
|
+
export declare class InstanceGroupConfig_AutoScalingPolicy {
|
|
78946
78955
|
constructor(props: {
|
|
78947
|
-
|
|
78948
|
-
|
|
78949
|
-
Configurations?: InstanceGroupConfig_Configuration[];
|
|
78956
|
+
Constraints: InstanceGroupConfig_ScalingConstraints;
|
|
78957
|
+
Rules: InstanceGroupConfig_ScalingRule[];
|
|
78950
78958
|
});
|
|
78951
78959
|
}
|
|
78952
78960
|
|
|
78953
78961
|
export declare class InstanceGroupConfig_EbsBlockDeviceConfig {
|
|
78954
78962
|
constructor(props: {
|
|
78955
78963
|
VolumeSpecification: InstanceGroupConfig_VolumeSpecification;
|
|
78964
|
+
/** Use of this property can confuse CloudFormation drift detection. The EbsBlockDeviceConfigs read from the system may return a list with one entry per volume, replacing any entry specified in the template with a VolumesPerInstance greater than one by that many entries containing only the VolumeSpecification. Thus to avoid false drift detection, it is recommended to supply repeated entries in EbsBlockDeviceConfigs for any VolumeSpecification which is intended to be repeated and not to use this property.
|
|
78965
|
+
*/
|
|
78956
78966
|
VolumesPerInstance?: number;
|
|
78957
78967
|
});
|
|
78958
78968
|
}
|
|
@@ -85949,10 +85959,10 @@ export declare class LogAlarm_ScheduleConfiguration {
|
|
|
85949
85959
|
constructor(props: {
|
|
85950
85960
|
/** The expression that defines when the scheduled query runs, e.g. rate(1 minute). */
|
|
85951
85961
|
ScheduleExpression: string;
|
|
85952
|
-
/** The number of seconds into the past to
|
|
85962
|
+
/** The number of seconds into the past to start the query window. Must be a positive value and cannot exceed 2592000 seconds (30 days). */
|
|
85963
|
+
StartTimeOffset: number;
|
|
85964
|
+
/** The number of seconds into the past to end the query window. Must be a non-negative value and cannot exceed 2592000 seconds (30 days). */
|
|
85953
85965
|
EndTimeOffset?: number;
|
|
85954
|
-
/** The number of seconds into the past to start the query window. */
|
|
85955
|
-
StartTimeOffset?: number;
|
|
85956
85966
|
});
|
|
85957
85967
|
}
|
|
85958
85968
|
|
|
@@ -85960,14 +85970,16 @@ export declare class LogAlarm_ScheduledQueryConfiguration {
|
|
|
85960
85970
|
constructor(props: {
|
|
85961
85971
|
/** The aggregation expression for the scheduled query, e.g. count(*) or avg(latency) by host. */
|
|
85962
85972
|
AggregationExpression: string;
|
|
85963
|
-
/** The log groups to query. */
|
|
85964
|
-
LogGroupIdentifiers: string[];
|
|
85965
85973
|
/** The query string to execute against the specified log groups. */
|
|
85966
85974
|
QueryString: string;
|
|
85967
85975
|
/** The schedule configuration. */
|
|
85968
85976
|
ScheduleConfiguration: LogAlarm_ScheduleConfiguration;
|
|
85969
85977
|
/** The ARN of the IAM role that grants permissions to execute the scheduled query. */
|
|
85970
85978
|
ScheduledQueryRoleARN: string;
|
|
85979
|
+
/** The log groups to query. */
|
|
85980
|
+
LogGroupIdentifiers?: string[];
|
|
85981
|
+
/** A list of key-value pairs to associate with the scheduled query that backs the log alarm. */
|
|
85982
|
+
Tags?: LogAlarm_Tag[];
|
|
85971
85983
|
});
|
|
85972
85984
|
}
|
|
85973
85985
|
|
|
@@ -109455,14 +109467,16 @@ export declare class ScheduledQueryConfiguration {
|
|
|
109455
109467
|
constructor(props: {
|
|
109456
109468
|
/** The aggregation expression for the scheduled query, e.g. count(*) or avg(latency) by host. */
|
|
109457
109469
|
AggregationExpression: string;
|
|
109458
|
-
/** The log groups to query. */
|
|
109459
|
-
LogGroupIdentifiers: string[];
|
|
109460
109470
|
/** The query string to execute against the specified log groups. */
|
|
109461
109471
|
QueryString: string;
|
|
109462
109472
|
/** The schedule configuration. */
|
|
109463
109473
|
ScheduleConfiguration: LogAlarm_ScheduleConfiguration;
|
|
109464
109474
|
/** The ARN of the IAM role that grants permissions to execute the scheduled query. */
|
|
109465
109475
|
ScheduledQueryRoleARN: string;
|
|
109476
|
+
/** The log groups to query. */
|
|
109477
|
+
LogGroupIdentifiers?: string[];
|
|
109478
|
+
/** A list of key-value pairs to associate with the scheduled query that backs the log alarm. */
|
|
109479
|
+
Tags?: LogAlarm_Tag[];
|
|
109466
109480
|
});
|
|
109467
109481
|
}
|
|
109468
109482
|
|
package/src/generated/index.ts
CHANGED
|
@@ -688,7 +688,7 @@ export const Instance = createResource("AWS::EC2::Instance", "aws", {"InstanceId
|
|
|
688
688
|
export const InstanceAccessControlAttributeConfiguration = createResource("AWS::SSO::InstanceAccessControlAttributeConfiguration", "aws", {});
|
|
689
689
|
export const InstanceConnectEndpoint = createResource("AWS::EC2::InstanceConnectEndpoint", "aws", {"Id":"Id","AvailabilityZone":"AvailabilityZone","AvailabilityZoneId":"AvailabilityZoneId","CreatedAt":"CreatedAt","InstanceConnectEndpointArn":"InstanceConnectEndpointArn","NetworkInterfaceIds":"NetworkInterfaceIds","OwnerId":"OwnerId","PublicDnsNames":"PublicDnsNames","State":"State","StateMessage":"StateMessage","VpcId":"VpcId"});
|
|
690
690
|
export const InstanceFleetConfig = createResource("AWS::EMR::InstanceFleetConfig", "aws", {"Id":"Id"});
|
|
691
|
-
export const InstanceGroupConfig = createResource("AWS::EMR::InstanceGroupConfig", "aws", {"
|
|
691
|
+
export const InstanceGroupConfig = createResource("AWS::EMR::InstanceGroupConfig", "aws", {"InstanceGroupId":"InstanceGroupId"});
|
|
692
692
|
export const InstanceProfile = createResource("AWS::IAM::InstanceProfile", "aws", {"Arn":"Arn"});
|
|
693
693
|
export const InstanceSnapshot = createResource("AWS::Lightsail::InstanceSnapshot", "aws", {"Arn":"Arn","IsFromAutoSnapshot":"IsFromAutoSnapshot","Location":"Location","FromInstanceName":"FromInstanceName","FromInstanceArn":"FromInstanceArn","ResourceType":"ResourceType","SizeInGb":"SizeInGb","State":"State","SupportCode":"SupportCode"});
|
|
694
694
|
export const InstanceStorageConfig = createResource("AWS::Connect::InstanceStorageConfig", "aws", {"AssociationId":"AssociationId"});
|
|
@@ -1985,6 +1985,7 @@ export const AppConfigDeployment_Tag = createProperty("AWS::AppConfig::Deploymen
|
|
|
1985
1985
|
export const AppConfigEnvironment_Monitor = createProperty("AWS::AppConfig::Environment.Monitor", "aws");
|
|
1986
1986
|
export const AppConfigEnvironment_Tag = createProperty("AWS::AppConfig::Environment.Tag", "aws");
|
|
1987
1987
|
export const AppConfigResourceObject = createProperty("AWS::Evidently::Project.AppConfigResourceObject", "aws");
|
|
1988
|
+
export const AppConfiguration = createProperty("AWS::EMR::InstanceGroupConfig.AppConfiguration", "aws");
|
|
1988
1989
|
export const AppCookieStickinessPolicy = createProperty("AWS::ElasticLoadBalancing::LoadBalancer.AppCookieStickinessPolicy", "aws");
|
|
1989
1990
|
export const AppFlowConnector_ConnectorProvisioningConfig = createProperty("AWS::AppFlow::Connector.ConnectorProvisioningConfig", "aws");
|
|
1990
1991
|
export const AppFlowConnector_LambdaConnectorProvisioningConfig = createProperty("AWS::AppFlow::Connector.LambdaConnectorProvisioningConfig", "aws");
|
|
@@ -5823,8 +5824,8 @@ export const InstanceFleetConfig_OnDemandProvisioningSpecification = createPrope
|
|
|
5823
5824
|
export const InstanceFleetConfig_OnDemandResizingSpecification = createProperty("AWS::EMR::InstanceFleetConfig.OnDemandResizingSpecification", "aws");
|
|
5824
5825
|
export const InstanceFleetConfig_SpotProvisioningSpecification = createProperty("AWS::EMR::InstanceFleetConfig.SpotProvisioningSpecification", "aws");
|
|
5825
5826
|
export const InstanceFleetConfig_SpotResizingSpecification = createProperty("AWS::EMR::InstanceFleetConfig.SpotResizingSpecification", "aws");
|
|
5827
|
+
export const InstanceGroupConfig_AppConfiguration = createProperty("AWS::EMR::InstanceGroupConfig.AppConfiguration", "aws");
|
|
5826
5828
|
export const InstanceGroupConfig_AutoScalingPolicy = createProperty("AWS::EMR::InstanceGroupConfig.AutoScalingPolicy", "aws");
|
|
5827
|
-
export const InstanceGroupConfig_Configuration = createProperty("AWS::EMR::InstanceGroupConfig.Configuration", "aws");
|
|
5828
5829
|
export const InstanceGroupConfig_EbsBlockDeviceConfig = createProperty("AWS::EMR::InstanceGroupConfig.EbsBlockDeviceConfig", "aws");
|
|
5829
5830
|
export const InstanceGroupConfig_EbsConfiguration = createProperty("AWS::EMR::InstanceGroupConfig.EbsConfiguration", "aws");
|
|
5830
5831
|
export const InstanceGroupConfig_ScalingAction = createProperty("AWS::EMR::InstanceGroupConfig.ScalingAction", "aws");
|
|
@@ -5045,6 +5045,11 @@
|
|
|
5045
5045
|
"kind": "property",
|
|
5046
5046
|
"lexicon": "aws"
|
|
5047
5047
|
},
|
|
5048
|
+
"AppConfiguration": {
|
|
5049
|
+
"resourceType": "AWS::EMR::InstanceGroupConfig.AppConfiguration",
|
|
5050
|
+
"kind": "property",
|
|
5051
|
+
"lexicon": "aws"
|
|
5052
|
+
},
|
|
5048
5053
|
"AppCookieStickinessPolicy": {
|
|
5049
5054
|
"resourceType": "AWS::ElasticLoadBalancing::LoadBalancer.AppCookieStickinessPolicy",
|
|
5050
5055
|
"kind": "property",
|
|
@@ -48824,7 +48829,7 @@
|
|
|
48824
48829
|
"kind": "resource",
|
|
48825
48830
|
"lexicon": "aws",
|
|
48826
48831
|
"attrs": {
|
|
48827
|
-
"
|
|
48832
|
+
"InstanceGroupId": "InstanceGroupId"
|
|
48828
48833
|
},
|
|
48829
48834
|
"createOnly": [
|
|
48830
48835
|
"InstanceRole",
|
|
@@ -48837,17 +48842,21 @@
|
|
|
48837
48842
|
"Market",
|
|
48838
48843
|
"BidPrice"
|
|
48839
48844
|
],
|
|
48845
|
+
"writeOnly": [
|
|
48846
|
+
"EbsConfiguration/EbsBlockDeviceConfigs/*/VolumesPerInstance"
|
|
48847
|
+
],
|
|
48840
48848
|
"primaryIdentifier": [
|
|
48841
|
-
"
|
|
48849
|
+
"InstanceGroupId",
|
|
48850
|
+
"JobFlowId"
|
|
48842
48851
|
]
|
|
48843
48852
|
},
|
|
48844
|
-
"
|
|
48845
|
-
"resourceType": "AWS::EMR::InstanceGroupConfig.
|
|
48853
|
+
"InstanceGroupConfig_AppConfiguration": {
|
|
48854
|
+
"resourceType": "AWS::EMR::InstanceGroupConfig.AppConfiguration",
|
|
48846
48855
|
"kind": "property",
|
|
48847
48856
|
"lexicon": "aws"
|
|
48848
48857
|
},
|
|
48849
|
-
"
|
|
48850
|
-
"resourceType": "AWS::EMR::InstanceGroupConfig.
|
|
48858
|
+
"InstanceGroupConfig_AutoScalingPolicy": {
|
|
48859
|
+
"resourceType": "AWS::EMR::InstanceGroupConfig.AutoScalingPolicy",
|
|
48851
48860
|
"kind": "property",
|
|
48852
48861
|
"lexicon": "aws"
|
|
48853
48862
|
},
|
package/src/intrinsics.test.ts
CHANGED
|
@@ -116,6 +116,22 @@ describe("Join intrinsic", () => {
|
|
|
116
116
|
"Fn::Join": ["-", [{ Ref: "Prefix" }, "bucket"]],
|
|
117
117
|
});
|
|
118
118
|
});
|
|
119
|
+
|
|
120
|
+
test("accepts a single list-returning intrinsic (not only an array) (#517)", () => {
|
|
121
|
+
// Fn::Join's second arg legitimately takes a list-returning intrinsic
|
|
122
|
+
// (GetAtt of a list attr, Split, Ref to a List<>) — emitted as-is, no `.map`.
|
|
123
|
+
expect(Join(",", GetAtt("Zone", "NameServers")).toJSON()).toEqual({
|
|
124
|
+
"Fn::Join": [",", { "Fn::GetAtt": ["Zone", "NameServers"] }],
|
|
125
|
+
});
|
|
126
|
+
expect(Join(",", Split(",", "a,b")).toJSON()).toEqual({
|
|
127
|
+
"Fn::Join": [",", { "Fn::Split": [",", "a,b"] }],
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("throws a clear error for a non-array, non-intrinsic value (#517)", () => {
|
|
132
|
+
// @ts-expect-error — exercising the runtime guard
|
|
133
|
+
expect(() => Join(",", "oops")).toThrow(/array or a list-returning intrinsic/);
|
|
134
|
+
});
|
|
119
135
|
});
|
|
120
136
|
|
|
121
137
|
describe("Select intrinsic", () => {
|
package/src/intrinsics.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INTRINSIC_MARKER, resolveIntrinsicValue, type Intrinsic } from "@intentius/chant/intrinsic";
|
|
1
|
+
import { INTRINSIC_MARKER, resolveIntrinsicValue, isIntrinsic, type Intrinsic } from "@intentius/chant/intrinsic";
|
|
2
2
|
import { buildInterpolatedString, defaultInterpolationSerializer } from "@intentius/chant/intrinsic-interpolation";
|
|
3
3
|
import { type Declarable } from "@intentius/chant/declarable";
|
|
4
4
|
import { getLogicalName } from "@intentius/chant/utils";
|
|
@@ -129,22 +129,35 @@ export function If(conditionName: string, valueIfTrue: unknown, valueIfFalse: un
|
|
|
129
129
|
export class JoinIntrinsic implements Intrinsic {
|
|
130
130
|
readonly [INTRINSIC_MARKER] = true as const;
|
|
131
131
|
private delimiter: string;
|
|
132
|
-
private values: unknown[];
|
|
132
|
+
private values: unknown[] | Intrinsic;
|
|
133
133
|
|
|
134
|
-
constructor(delimiter: string, values: unknown[]) {
|
|
134
|
+
constructor(delimiter: string, values: unknown[] | Intrinsic) {
|
|
135
135
|
this.delimiter = delimiter;
|
|
136
136
|
this.values = values;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
toJSON(): { "Fn::Join": [string, unknown
|
|
140
|
-
|
|
139
|
+
toJSON(): { "Fn::Join": [string, unknown] } {
|
|
140
|
+
// Fn::Join's second arg is either a literal list of values OR a single
|
|
141
|
+
// list-returning intrinsic (GetAtt of a list attr, Split, Ref to a List<>
|
|
142
|
+
// param). Only the array form gets `.map`; a lone intrinsic is emitted as-is
|
|
143
|
+
// (#517 — mapping over it dereferenced undefined and crashed the build).
|
|
144
|
+
const list = Array.isArray(this.values)
|
|
145
|
+
? this.values.map(resolveIntrinsicValue)
|
|
146
|
+
: resolveIntrinsicValue(this.values);
|
|
147
|
+
return { "Fn::Join": [this.delimiter, list] };
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
150
|
|
|
144
151
|
/**
|
|
145
|
-
* Create a Join intrinsic
|
|
152
|
+
* Create a Join intrinsic. `values` is a literal array, or a single
|
|
153
|
+
* list-returning intrinsic (e.g. `Join(",", zone.NameServers)`).
|
|
146
154
|
*/
|
|
147
|
-
export function Join(delimiter: string, values: unknown[]): JoinIntrinsic {
|
|
155
|
+
export function Join(delimiter: string, values: unknown[] | Intrinsic): JoinIntrinsic {
|
|
156
|
+
if (!Array.isArray(values) && !isIntrinsic(values)) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
"Join(delimiter, values): values must be an array or a list-returning intrinsic (GetAtt/Split/Ref to a List)",
|
|
159
|
+
);
|
|
160
|
+
}
|
|
148
161
|
return new JoinIntrinsic(delimiter, values);
|
|
149
162
|
}
|
|
150
163
|
|