@intentius/chant-lexicon-aws 0.1.1 → 0.1.4
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/integrity.json +25 -19
- package/dist/manifest.json +1 -1
- package/dist/meta.json +705 -435
- package/dist/rules/waw032.ts +52 -0
- package/dist/rules/waw033.ts +86 -0
- package/dist/rules/waw034.ts +63 -0
- package/dist/rules/waw035.ts +71 -0
- package/dist/rules/waw036.ts +88 -0
- package/dist/rules/waw037.ts +81 -0
- package/dist/types/index.d.ts +956 -59
- package/package.json +2 -2
- package/src/composites/composites.test.ts +65 -0
- package/src/composites/ec2-instance-role.ts +39 -0
- package/src/composites/fargate-service.ts +9 -0
- package/src/composites/index.ts +6 -0
- package/src/composites/lambda-function.ts +2 -1
- package/src/composites/minimal-vpc.ts +71 -0
- package/src/composites/solr-fargate-service.ts +42 -0
- package/src/generated/index.d.ts +956 -59
- package/src/generated/index.ts +31 -5
- package/src/generated/lexicon-aws.json +705 -435
- package/src/index.ts +2 -0
- package/src/lint/post-synth/waw032.test.ts +83 -0
- package/src/lint/post-synth/waw032.ts +52 -0
- package/src/lint/post-synth/waw033.test.ts +68 -0
- package/src/lint/post-synth/waw033.ts +86 -0
- package/src/lint/post-synth/waw034.test.ts +54 -0
- package/src/lint/post-synth/waw034.ts +63 -0
- package/src/lint/post-synth/waw035.test.ts +74 -0
- package/src/lint/post-synth/waw035.ts +71 -0
- package/src/lint/post-synth/waw036.test.ts +217 -0
- package/src/lint/post-synth/waw036.ts +88 -0
- package/src/lint/post-synth/waw037.test.ts +155 -0
- package/src/lint/post-synth/waw037.ts +81 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-aws",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
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",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"js-yaml": "^4.1.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@intentius/chant": "0.1.
|
|
50
|
+
"@intentius/chant": "0.1.4",
|
|
51
51
|
"typescript": "^5.9.3"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
@@ -14,6 +14,8 @@ import { FargateAlb } from "./fargate-alb";
|
|
|
14
14
|
import { AlbShared } from "./alb-shared";
|
|
15
15
|
import { FargateService } from "./fargate-service";
|
|
16
16
|
import { RdsInstance } from "./rds-instance";
|
|
17
|
+
import { Ec2InstanceRole } from "./ec2-instance-role";
|
|
18
|
+
import { MinimalVpc } from "./minimal-vpc";
|
|
17
19
|
|
|
18
20
|
const baseProps = {
|
|
19
21
|
name: "TestFunc",
|
|
@@ -865,3 +867,66 @@ describe("per-member defaults", () => {
|
|
|
865
867
|
expect(funcPropsA.Timeout).toBe(funcPropsB.Timeout);
|
|
866
868
|
});
|
|
867
869
|
});
|
|
870
|
+
|
|
871
|
+
describe("Ec2InstanceRole", () => {
|
|
872
|
+
test("returns role and instanceProfile members", () => {
|
|
873
|
+
const instance = Ec2InstanceRole({});
|
|
874
|
+
expect(instance.role).toBeDefined();
|
|
875
|
+
expect(instance.instanceProfile).toBeDefined();
|
|
876
|
+
expect(Object.keys(instance.members)).toEqual(["role", "instanceProfile"]);
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
test("role has EC2 trust policy", () => {
|
|
880
|
+
const instance = Ec2InstanceRole({});
|
|
881
|
+
const roleProps = (instance.role as any).props;
|
|
882
|
+
expect(roleProps.AssumeRolePolicyDocument.Statement[0].Principal.Service).toBe("ec2.amazonaws.com");
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
test("ManagedPolicyArns are passed through", () => {
|
|
886
|
+
const arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore";
|
|
887
|
+
const instance = Ec2InstanceRole({ ManagedPolicyArns: [arn] });
|
|
888
|
+
const roleProps = (instance.role as any).props;
|
|
889
|
+
expect(roleProps.ManagedPolicyArns).toContain(arn);
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
test("expandComposite produces 2 entries", () => {
|
|
893
|
+
const expanded = expandComposite("myRole", Ec2InstanceRole({}));
|
|
894
|
+
expect(expanded.size).toBe(2);
|
|
895
|
+
expect(expanded.has("myRoleRole")).toBe(true);
|
|
896
|
+
expect(expanded.has("myRoleInstanceProfile")).toBe(true);
|
|
897
|
+
});
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
describe("MinimalVpc", () => {
|
|
901
|
+
test("returns 8 members", () => {
|
|
902
|
+
const instance = MinimalVpc({});
|
|
903
|
+
expect(Object.keys(instance.members)).toEqual([
|
|
904
|
+
"vpc", "subnet", "igw", "igwAttachment", "routeTable", "defaultRoute", "subnetRta", "securityGroup",
|
|
905
|
+
]);
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
test("subnet uses Select/GetAZs for AZ (not a plain string)", () => {
|
|
909
|
+
const instance = MinimalVpc({});
|
|
910
|
+
const subnetProps = (instance.subnet as any).props;
|
|
911
|
+
expect(typeof subnetProps.AvailabilityZone).not.toBe("string");
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
test("vpc cidr defaults to 10.0.0.0/24", () => {
|
|
915
|
+
const instance = MinimalVpc({});
|
|
916
|
+
const vpcProps = (instance.vpc as any).props;
|
|
917
|
+
expect(vpcProps.CidrBlock).toBe("10.0.0.0/24");
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
test("custom cidr is respected", () => {
|
|
921
|
+
const instance = MinimalVpc({ cidr: "192.168.0.0/16", subnetCidr: "192.168.1.0/24" });
|
|
922
|
+
const vpcProps = (instance.vpc as any).props;
|
|
923
|
+
const subnetProps = (instance.subnet as any).props;
|
|
924
|
+
expect(vpcProps.CidrBlock).toBe("192.168.0.0/16");
|
|
925
|
+
expect(subnetProps.CidrBlock).toBe("192.168.1.0/24");
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
test("expandComposite produces 8 entries", () => {
|
|
929
|
+
const expanded = expandComposite("net", MinimalVpc({}));
|
|
930
|
+
expect(expanded.size).toBe(8);
|
|
931
|
+
});
|
|
932
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
2
|
+
import { Role, InstanceProfile } from "../generated";
|
|
3
|
+
import { Ref } from "../intrinsics";
|
|
4
|
+
|
|
5
|
+
export interface Ec2InstanceRoleProps {
|
|
6
|
+
ManagedPolicyArns?: string[];
|
|
7
|
+
Policies?: ConstructorParameters<typeof Role>[0]["Policies"];
|
|
8
|
+
defaults?: {
|
|
9
|
+
role?: Partial<ConstructorParameters<typeof Role>[0]>;
|
|
10
|
+
instanceProfile?: Partial<ConstructorParameters<typeof InstanceProfile>[0]>;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const EC2_ASSUME_ROLE = {
|
|
15
|
+
Version: "2012-10-17" as const,
|
|
16
|
+
Statement: [
|
|
17
|
+
{
|
|
18
|
+
Effect: "Allow" as const,
|
|
19
|
+
Principal: { Service: "ec2.amazonaws.com" },
|
|
20
|
+
Action: "sts:AssumeRole",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Ec2InstanceRole = Composite<Ec2InstanceRoleProps>((props) => {
|
|
26
|
+
const { defaults } = props;
|
|
27
|
+
|
|
28
|
+
const role = new Role(mergeDefaults({
|
|
29
|
+
AssumeRolePolicyDocument: EC2_ASSUME_ROLE,
|
|
30
|
+
ManagedPolicyArns: props.ManagedPolicyArns ?? [],
|
|
31
|
+
Policies: props.Policies ?? [],
|
|
32
|
+
}, defaults?.role));
|
|
33
|
+
|
|
34
|
+
const instanceProfile = new InstanceProfile(mergeDefaults({
|
|
35
|
+
Roles: [Ref(role)],
|
|
36
|
+
}, defaults?.instanceProfile));
|
|
37
|
+
|
|
38
|
+
return { role, instanceProfile };
|
|
39
|
+
}, "Ec2InstanceRole");
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
TaskDefinition_KeyValuePair,
|
|
13
13
|
TaskDefinition_EFSVolumeConfiguration,
|
|
14
14
|
TaskDefinition_Volume,
|
|
15
|
+
TaskDefinition_Ulimit,
|
|
15
16
|
TargetGroup,
|
|
16
17
|
ListenerRule,
|
|
17
18
|
ListenerRule_Action,
|
|
@@ -74,6 +75,9 @@ export interface FargateServiceProps {
|
|
|
74
75
|
privateSubnetIds: string[];
|
|
75
76
|
healthCheckPath?: string;
|
|
76
77
|
|
|
78
|
+
// Ulimits (container-level)
|
|
79
|
+
ulimits?: Array<{ name: string; softLimit: number; hardLimit: number }>;
|
|
80
|
+
|
|
77
81
|
// IAM
|
|
78
82
|
ManagedPolicyArns?: string[];
|
|
79
83
|
Policies?: InstanceType<typeof Role_Policy>[];
|
|
@@ -175,6 +179,11 @@ export const FargateService = Composite<FargateServiceProps>((props) => {
|
|
|
175
179
|
Environment: environmentVars.length > 0 ? environmentVars : undefined,
|
|
176
180
|
Command: props.command,
|
|
177
181
|
MountPoints: allMountPoints.length > 0 ? allMountPoints : undefined,
|
|
182
|
+
Ulimits: props.ulimits?.map(u => new TaskDefinition_Ulimit({
|
|
183
|
+
Name: u.name,
|
|
184
|
+
SoftLimit: u.softLimit,
|
|
185
|
+
HardLimit: u.hardLimit,
|
|
186
|
+
})),
|
|
178
187
|
});
|
|
179
188
|
|
|
180
189
|
// Task definition
|
package/src/composites/index.ts
CHANGED
|
@@ -26,3 +26,9 @@ export { RdsInstance, RdsInstance as RdsPostgres } from "./rds-instance";
|
|
|
26
26
|
export type { RdsInstanceProps, RdsInstanceProps as RdsPostgresProps } from "./rds-instance";
|
|
27
27
|
export { EfsWithAccessPoint } from "./efs-with-access-point";
|
|
28
28
|
export type { EfsWithAccessPointProps } from "./efs-with-access-point";
|
|
29
|
+
export { SolrFargateService } from "./solr-fargate-service";
|
|
30
|
+
export type { SolrFargateServiceProps } from "./solr-fargate-service";
|
|
31
|
+
export { Ec2InstanceRole } from "./ec2-instance-role";
|
|
32
|
+
export type { Ec2InstanceRoleProps } from "./ec2-instance-role";
|
|
33
|
+
export { MinimalVpc } from "./minimal-vpc";
|
|
34
|
+
export type { MinimalVpcProps } from "./minimal-vpc";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Composite, withDefaults, mergeDefaults } from "@intentius/chant";
|
|
2
2
|
import { Role, Function, Function_VpcConfig, Role_Policy } from "../generated";
|
|
3
|
+
import { Sub } from "../intrinsics";
|
|
3
4
|
|
|
4
5
|
const lambdaTrustPolicy = {
|
|
5
6
|
Version: "2012-10-17" as const,
|
|
@@ -18,7 +19,7 @@ const VPC_ACCESS_ARN =
|
|
|
18
19
|
"arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole";
|
|
19
20
|
|
|
20
21
|
export interface LambdaFunctionProps {
|
|
21
|
-
name: string
|
|
22
|
+
name: string | ReturnType<typeof Sub>;
|
|
22
23
|
Runtime: string;
|
|
23
24
|
Handler: string;
|
|
24
25
|
Code: ConstructorParameters<typeof Function>[0]["Code"];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Composite, mergeDefaults } from "@intentius/chant";
|
|
2
|
+
import {
|
|
3
|
+
Vpc,
|
|
4
|
+
Subnet,
|
|
5
|
+
InternetGateway,
|
|
6
|
+
VPCGatewayAttachment,
|
|
7
|
+
RouteTable,
|
|
8
|
+
EC2Route,
|
|
9
|
+
SubnetRouteTableAssociation,
|
|
10
|
+
SecurityGroup,
|
|
11
|
+
} from "../generated";
|
|
12
|
+
import { Select, GetAZs } from "../intrinsics";
|
|
13
|
+
|
|
14
|
+
export interface MinimalVpcProps {
|
|
15
|
+
cidr?: string;
|
|
16
|
+
subnetCidr?: string;
|
|
17
|
+
defaults?: {
|
|
18
|
+
vpc?: Partial<ConstructorParameters<typeof Vpc>[0]>;
|
|
19
|
+
subnet?: Partial<ConstructorParameters<typeof Subnet>[0]>;
|
|
20
|
+
securityGroup?: Partial<ConstructorParameters<typeof SecurityGroup>[0]>;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const MinimalVpc = Composite<MinimalVpcProps>((props) => {
|
|
25
|
+
const { defaults } = props;
|
|
26
|
+
const cidr = props.cidr ?? "10.0.0.0/24";
|
|
27
|
+
const subnetCidr = props.subnetCidr ?? "10.0.0.0/25";
|
|
28
|
+
|
|
29
|
+
const vpc = new Vpc(mergeDefaults({
|
|
30
|
+
CidrBlock: cidr,
|
|
31
|
+
EnableDnsHostnames: true,
|
|
32
|
+
EnableDnsSupport: true,
|
|
33
|
+
}, defaults?.vpc));
|
|
34
|
+
|
|
35
|
+
const subnet = new Subnet(mergeDefaults({
|
|
36
|
+
VpcId: vpc.VpcId,
|
|
37
|
+
CidrBlock: subnetCidr,
|
|
38
|
+
AvailabilityZone: Select(0, GetAZs("")),
|
|
39
|
+
MapPublicIpOnLaunch: true,
|
|
40
|
+
}, defaults?.subnet));
|
|
41
|
+
|
|
42
|
+
const igw = new InternetGateway({});
|
|
43
|
+
|
|
44
|
+
const igwAttachment = new VPCGatewayAttachment({
|
|
45
|
+
VpcId: vpc.VpcId,
|
|
46
|
+
InternetGatewayId: igw.InternetGatewayId,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const routeTable = new RouteTable({ VpcId: vpc.VpcId });
|
|
50
|
+
|
|
51
|
+
const defaultRoute = new EC2Route(
|
|
52
|
+
{
|
|
53
|
+
RouteTableId: routeTable.RouteTableId,
|
|
54
|
+
DestinationCidrBlock: "0.0.0.0/0",
|
|
55
|
+
GatewayId: igw.InternetGatewayId,
|
|
56
|
+
},
|
|
57
|
+
{ DependsOn: [igwAttachment] },
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
const subnetRta = new SubnetRouteTableAssociation({
|
|
61
|
+
SubnetId: subnet.SubnetId,
|
|
62
|
+
RouteTableId: routeTable.RouteTableId,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const securityGroup = new SecurityGroup(mergeDefaults({
|
|
66
|
+
GroupDescription: "MinimalVpc default security group",
|
|
67
|
+
VpcId: vpc.VpcId,
|
|
68
|
+
}, defaults?.securityGroup));
|
|
69
|
+
|
|
70
|
+
return { vpc, subnet, igw, igwAttachment, routeTable, defaultRoute, subnetRta, securityGroup };
|
|
71
|
+
}, "MinimalVpc");
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Composite } from "@intentius/chant";
|
|
2
|
+
import { FargateService, FargateServiceProps } from "./fargate-service";
|
|
3
|
+
|
|
4
|
+
export interface SolrFargateServiceProps extends FargateServiceProps {
|
|
5
|
+
/**
|
|
6
|
+
* JVM heap size passed as SOLR_HEAP. Defaults to 45% of task memory.
|
|
7
|
+
* Examples: "1843m", "4g". Must not exceed 50% of task memory.
|
|
8
|
+
*/
|
|
9
|
+
solrHeap?: string;
|
|
10
|
+
/**
|
|
11
|
+
* GC tuning string passed as GC_TUNE.
|
|
12
|
+
* Default: "-XX:+UseG1GC -XX:MaxGCPauseMillis=200"
|
|
13
|
+
*/
|
|
14
|
+
gcOpts?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const SolrFargateService = Composite<SolrFargateServiceProps>((props) => {
|
|
18
|
+
const memoryMb = parseInt(props.memory ?? "4096");
|
|
19
|
+
const solrHeap = props.solrHeap ?? `${Math.floor(memoryMb * 0.45)}m`;
|
|
20
|
+
const gcOpts = props.gcOpts ?? "-XX:+UseG1GC -XX:MaxGCPauseMillis=200";
|
|
21
|
+
|
|
22
|
+
// Solr env defaults — user-supplied environment entries override these
|
|
23
|
+
const solrEnv: Record<string, string> = {
|
|
24
|
+
SOLR_HEAP: solrHeap,
|
|
25
|
+
GC_TUNE: gcOpts,
|
|
26
|
+
SOLR_OPTS: "-XX:-UseLargePages",
|
|
27
|
+
...props.environment,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Solr-specific ulimit default — user-supplied ulimits override
|
|
31
|
+
const solrUlimits = props.ulimits ?? [
|
|
32
|
+
{ name: "nofile", softLimit: 65535, hardLimit: 65535 },
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
return FargateService({
|
|
36
|
+
containerPort: 8983,
|
|
37
|
+
healthCheckPath: "/solr/admin/info/health",
|
|
38
|
+
...props,
|
|
39
|
+
environment: solrEnv,
|
|
40
|
+
ulimits: solrUlimits,
|
|
41
|
+
});
|
|
42
|
+
}, "SolrFargateService");
|