@fjall/components-infrastructure 10.1.1 → 10.1.3
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.
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { Duration } from "aws-cdk-lib";
|
|
1
2
|
import { ApplicationLoadBalancer } from "aws-cdk-lib/aws-elasticloadbalancingv2";
|
|
2
3
|
import { SubnetType } from "aws-cdk-lib/aws-ec2";
|
|
4
|
+
import { DEFAULT_ALB_IDLE_TIMEOUT_SECONDS } from "@fjall/util/httpKeepAlive";
|
|
3
5
|
/**
|
|
4
6
|
* Context-free Application Load Balancer factory shared by the ECS cluster path
|
|
5
7
|
* and the dev substrate. Subnet placement is derived from `internetFacing`
|
|
@@ -10,6 +12,10 @@ export function createApplicationLoadBalancer(scope, id, options) {
|
|
|
10
12
|
return new ApplicationLoadBalancer(scope, id, {
|
|
11
13
|
vpc: options.vpc,
|
|
12
14
|
internetFacing: options.internetFacing,
|
|
15
|
+
// Pinned (rather than left at the AWS default of the same value) because
|
|
16
|
+
// ALB-fronted containers receive it as FJALL_ALB_IDLE_TIMEOUT_SECONDS
|
|
17
|
+
// (ecsTaskDefinition.ts) for keep-alive tuning — one constant, both sides.
|
|
18
|
+
idleTimeout: Duration.seconds(DEFAULT_ALB_IDLE_TIMEOUT_SECONDS),
|
|
13
19
|
...(options.securityGroup && { securityGroup: options.securityGroup }),
|
|
14
20
|
...(options.loadBalancerName && {
|
|
15
21
|
loadBalancerName: options.loadBalancerName
|
|
@@ -41,6 +41,19 @@ export declare const DEFAULT_ROLLING_UPDATE_PAUSE_SECONDS = 300;
|
|
|
41
41
|
export declare function resolveEc2ContainerMemoryMiB(ec2Config: {
|
|
42
42
|
readonly memoryLimitMiB?: number;
|
|
43
43
|
} | undefined): number;
|
|
44
|
+
/**
|
|
45
|
+
* Hard memory limit for the synthetic `fjall-schema-gate` container on
|
|
46
|
+
* EC2-capacity services. The gate is a run-to-completion Node probe (a
|
|
47
|
+
* handful of DB queries, then exit) — giving it the service's full
|
|
48
|
+
* `ec2Config.memoryLimitMiB` doubles the task's placement requirement and
|
|
49
|
+
* can exceed the instance's registered memory entirely: with the 2048 MiB
|
|
50
|
+
* deploy-worker limit the task demanded 4096 MiB against a t4g.medium's
|
|
51
|
+
* 3835, making every task structurally unplaceable (2026-08-12 production
|
|
52
|
+
* wedge — armed silently at desiredCount 0, detonated on the first
|
|
53
|
+
* queue-driven scale-up mid-CFN-update). Fargate services are unaffected:
|
|
54
|
+
* their memory is task-level, so the gate shares the task envelope.
|
|
55
|
+
*/
|
|
56
|
+
export declare const SCHEMA_GATE_CONTAINER_MEMORY_MIB = 512;
|
|
44
57
|
export declare const DEFAULT_ECS_FALLBACK_IMAGE = "amazon/amazon-ecs-sample";
|
|
45
58
|
export declare const DEFAULT_CUSTOM_RESOURCE_TIMEOUT_SECONDS = 300;
|
|
46
59
|
export declare const DEFAULT_HEALTH_CHECK_GRACE_SECONDS = 120;
|
|
@@ -54,6 +54,19 @@ export const DEFAULT_ROLLING_UPDATE_PAUSE_SECONDS = 300;
|
|
|
54
54
|
export function resolveEc2ContainerMemoryMiB(ec2Config) {
|
|
55
55
|
return ec2Config?.memoryLimitMiB ?? DEFAULT_EC2_CONTAINER_MEMORY_MIB;
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Hard memory limit for the synthetic `fjall-schema-gate` container on
|
|
59
|
+
* EC2-capacity services. The gate is a run-to-completion Node probe (a
|
|
60
|
+
* handful of DB queries, then exit) — giving it the service's full
|
|
61
|
+
* `ec2Config.memoryLimitMiB` doubles the task's placement requirement and
|
|
62
|
+
* can exceed the instance's registered memory entirely: with the 2048 MiB
|
|
63
|
+
* deploy-worker limit the task demanded 4096 MiB against a t4g.medium's
|
|
64
|
+
* 3835, making every task structurally unplaceable (2026-08-12 production
|
|
65
|
+
* wedge — armed silently at desiredCount 0, detonated on the first
|
|
66
|
+
* queue-driven scale-up mid-CFN-update). Fargate services are unaffected:
|
|
67
|
+
* their memory is task-level, so the gate shares the task envelope.
|
|
68
|
+
*/
|
|
69
|
+
export const SCHEMA_GATE_CONTAINER_MEMORY_MIB = 512;
|
|
57
70
|
// AWS sample image used when no ECR repository is provided. Consumed by both
|
|
58
71
|
// the resources/ image resolver and the patterns/ defaults block — keep them
|
|
59
72
|
// in lockstep via this single export.
|
|
@@ -3,9 +3,11 @@ import { Duration } from "aws-cdk-lib";
|
|
|
3
3
|
import { Secret as EcsSecret } from "aws-cdk-lib/aws-ecs";
|
|
4
4
|
import { StringParameter } from "aws-cdk-lib/aws-ssm";
|
|
5
5
|
import { buildParameterPath } from "@fjall/util";
|
|
6
|
+
import { DEFAULT_ALB_IDLE_TIMEOUT_SECONDS, FJALL_ALB_IDLE_TIMEOUT_ENV_VAR } from "@fjall/util/httpKeepAlive";
|
|
7
|
+
import { SCHEMA_GATE_CONTAINER_NAME } from "@fjall/util/migration";
|
|
6
8
|
import { resolveOrgId } from "../../../utils/cdkContext.js";
|
|
7
9
|
import { validateSsmPathComponent, validateSecretName } from "./ecsValidation.js";
|
|
8
|
-
import { DEFAULT_LOG_RETENTION, DEFAULT_FARGATE_CPU, DEFAULT_FARGATE_MEMORY_MIB, resolveEc2ContainerMemoryMiB } from "./ecsConstants.js";
|
|
10
|
+
import { DEFAULT_LOG_RETENTION, DEFAULT_FARGATE_CPU, DEFAULT_FARGATE_MEMORY_MIB, resolveEc2ContainerMemoryMiB, SCHEMA_GATE_CONTAINER_MEMORY_MIB } from "./ecsConstants.js";
|
|
9
11
|
import { LogGroup } from "../logging/logGroup.js";
|
|
10
12
|
import { getContainerImage } from "./ecsImages.js";
|
|
11
13
|
import { resolveRemoteConnections } from "./ecsRemoteConnections.js";
|
|
@@ -194,6 +196,14 @@ export function addContainersToTask(ctx, serviceName, serviceProps, taskDefiniti
|
|
|
194
196
|
...remoteEnv,
|
|
195
197
|
...(containerConfig.port
|
|
196
198
|
? { PORT: String(containerConfig.port) }
|
|
199
|
+
: {}),
|
|
200
|
+
// The ALB half of the keep-alive contract (@fjall/util/httpKeepAlive):
|
|
201
|
+
// only the first port-bearing container is ALB-registered, and the
|
|
202
|
+
// value must match the idleTimeout pinned in applicationLoadBalancer.ts.
|
|
203
|
+
...(isFirstWithPort && !ctx.loadBalancerDisabled
|
|
204
|
+
? {
|
|
205
|
+
[FJALL_ALB_IDLE_TIMEOUT_ENV_VAR]: String(DEFAULT_ALB_IDLE_TIMEOUT_SECONDS)
|
|
206
|
+
}
|
|
197
207
|
: {})
|
|
198
208
|
},
|
|
199
209
|
secrets,
|
|
@@ -221,8 +231,13 @@ export function addContainersToTask(ctx, serviceName, serviceProps, taskDefiniti
|
|
|
221
231
|
startTimeout: containerConfig.startTimeout !== undefined
|
|
222
232
|
? Duration.seconds(containerConfig.startTimeout)
|
|
223
233
|
: undefined,
|
|
234
|
+
// EC2 placement demands the SUM of container hard limits — the gate
|
|
235
|
+
// probe must not inherit the service's full per-container limit (see
|
|
236
|
+
// SCHEMA_GATE_CONTAINER_MEMORY_MIB; the gate name is synth-reserved).
|
|
224
237
|
...(isServiceEc2(serviceProps) && {
|
|
225
|
-
memoryLimitMiB:
|
|
238
|
+
memoryLimitMiB: containerConfig.name === SCHEMA_GATE_CONTAINER_NAME
|
|
239
|
+
? SCHEMA_GATE_CONTAINER_MEMORY_MIB
|
|
240
|
+
: resolveEc2ContainerMemoryMiB(serviceProps.ec2Config)
|
|
226
241
|
})
|
|
227
242
|
});
|
|
228
243
|
if (containerConfig.port !== undefined &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/components-infrastructure",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.3",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/fjall-tech/fjall.git",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@aws-sdk/client-organizations": "^3.1098.0",
|
|
83
|
-
"@fjall/generator": "^10.1.
|
|
84
|
-
"@fjall/util": "^10.1.
|
|
83
|
+
"@fjall/generator": "^10.1.3",
|
|
84
|
+
"@fjall/util": "^10.1.3",
|
|
85
85
|
"constructs": "^10.7.2"
|
|
86
86
|
},
|
|
87
87
|
"overrides": {
|