@fjall/components-infrastructure 0.96.0 → 0.99.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.
- package/dist/lib/app.d.ts +68 -1
- package/dist/lib/app.js +113 -4
- package/dist/lib/config/aws/__t17fixture.d.ts +1 -0
- package/dist/lib/config/aws/__t17fixture.js +3 -0
- package/dist/lib/config/aws/__t17fixtureType.d.ts +2 -0
- package/dist/lib/config/aws/__t17fixtureType.js +1 -0
- package/dist/lib/config/aws/alarmTopic.js +8 -4
- package/dist/lib/config/aws/cloudTrail.js +1 -1
- package/dist/lib/config/aws/disasterRecovery.js +11 -16
- package/dist/lib/config/aws/ecrDefaultImage.d.ts +0 -1
- package/dist/lib/config/aws/ecrDefaultImage.js +13 -23
- package/dist/lib/config/aws/identityCenter.d.ts +10 -3
- package/dist/lib/config/aws/identityCenter.js +101 -37
- package/dist/lib/config/aws/identityCenterGroupMembership.js +8 -2
- package/dist/lib/config/aws/identityCenterMembership.d.ts +11 -0
- package/dist/lib/config/aws/identityCenterMembership.js +61 -0
- package/dist/lib/config/aws/index.d.ts +1 -1
- package/dist/lib/config/aws/index.js +1 -1
- package/dist/lib/config/aws/ipam.js +6 -11
- package/dist/lib/config/aws/oidcConnector.js +5 -1
- package/dist/lib/config/aws/scpPreset.js +4 -1
- package/dist/lib/patterns/aws/_eslint_test_tmp/leak.d.ts +1 -0
- package/dist/lib/patterns/aws/_eslint_test_tmp/leak.js +4 -0
- package/dist/lib/patterns/aws/account.js +2 -4
- package/dist/lib/patterns/aws/apexDomainPattern.js +10 -10
- package/dist/lib/patterns/aws/bastionFactory.d.ts +10 -0
- package/dist/lib/patterns/aws/bastionFactory.js +29 -0
- package/dist/lib/patterns/aws/buildkite.d.ts +2 -2
- package/dist/lib/patterns/aws/buildkite.js +51 -97
- package/dist/lib/patterns/aws/cdn.js +1 -1
- package/dist/lib/patterns/aws/clickhouseDatabase.d.ts +173 -0
- package/dist/lib/patterns/aws/clickhouseDatabase.js +601 -0
- package/dist/lib/patterns/aws/compute.d.ts +4 -6
- package/dist/lib/patterns/aws/compute.js +7 -13
- package/dist/lib/patterns/aws/computeEcs.d.ts +93 -5
- package/dist/lib/patterns/aws/computeEcs.js +867 -37
- package/dist/lib/patterns/aws/computeEcsTypes.d.ts +528 -25
- package/dist/lib/patterns/aws/computeEcsTypes.js +10 -0
- package/dist/lib/patterns/aws/computeLambda.d.ts +0 -5
- package/dist/lib/patterns/aws/computeLambda.js +1 -2
- package/dist/lib/patterns/aws/database.d.ts +50 -8
- package/dist/lib/patterns/aws/database.js +183 -27
- package/dist/lib/patterns/aws/domain.js +6 -4
- package/dist/lib/patterns/aws/index.d.ts +1 -0
- package/dist/lib/patterns/aws/index.js +1 -0
- package/dist/lib/patterns/aws/interfaces/compute.d.ts +7 -1
- package/dist/lib/patterns/aws/interfaces/database.d.ts +187 -8
- package/dist/lib/patterns/aws/interfaces/database.js +17 -3
- package/dist/lib/patterns/aws/interfaces/index.d.ts +2 -1
- package/dist/lib/patterns/aws/interfaces/index.js +3 -1
- package/dist/lib/patterns/aws/interfaces/messaging.d.ts +7 -0
- package/dist/lib/patterns/aws/interfaces/migrationContributor.d.ts +47 -0
- package/dist/lib/patterns/aws/interfaces/migrationContributor.js +9 -0
- package/dist/lib/patterns/aws/messaging.d.ts +66 -10
- package/dist/lib/patterns/aws/messaging.js +115 -20
- package/dist/lib/patterns/aws/network.js +16 -7
- package/dist/lib/patterns/aws/organisation.d.ts +4 -0
- package/dist/lib/patterns/aws/organisation.js +22 -4
- package/dist/lib/patterns/aws/storage.d.ts +1 -2
- package/dist/lib/patterns/aws/storage.js +3 -2
- package/dist/lib/patterns/aws/vpcPeer.js +3 -1
- package/dist/lib/resources/aws/analytics/clickhouse.js +18 -9
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.d.ts +24 -9
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.js +61 -10
- package/dist/lib/resources/aws/analytics/clickhouseConstants.d.ts +3 -3
- package/dist/lib/resources/aws/analytics/clickhouseConstants.js +3 -3
- package/dist/lib/resources/aws/analytics/clickhouseTypes.d.ts +7 -1
- package/dist/lib/resources/aws/analytics/clickhouseUserData.d.ts +1 -1
- package/dist/lib/resources/aws/analytics/clickhouseUserData.js +53 -3
- package/dist/lib/resources/aws/base/awsStack.js +4 -2
- package/dist/lib/resources/aws/compute/__tmp__/regression-shape.d.ts +2 -0
- package/dist/lib/resources/aws/compute/__tmp__/regression-shape.js +11 -0
- package/dist/lib/resources/aws/compute/asgInlineLifecycleHook.d.ts +52 -0
- package/dist/lib/resources/aws/compute/asgInlineLifecycleHook.js +60 -0
- package/dist/lib/resources/aws/compute/blockDeviceVolume.d.ts +8 -0
- package/dist/lib/resources/aws/compute/blockDeviceVolume.js +10 -0
- package/dist/lib/resources/aws/compute/ec2.d.ts +132 -12
- package/dist/lib/resources/aws/compute/ec2.js +163 -23
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationHandler.d.ts +41 -0
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationHandler.js +194 -0
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationLambda.source.cjs +458 -0
- package/dist/lib/resources/aws/compute/ecs.d.ts +27 -1
- package/dist/lib/resources/aws/compute/ecs.js +42 -2
- package/dist/lib/resources/aws/compute/ecsConstants.d.ts +9 -0
- package/dist/lib/resources/aws/compute/ecsConstants.js +16 -0
- package/dist/lib/resources/aws/compute/ecsImages.js +32 -20
- package/dist/lib/resources/aws/compute/ecsLifecycleHookMigration.d.ts +96 -0
- package/dist/lib/resources/aws/compute/ecsLifecycleHookMigration.js +113 -0
- package/dist/lib/resources/aws/compute/ecsNetworking.d.ts +2 -1
- package/dist/lib/resources/aws/compute/ecsNetworking.js +18 -6
- package/dist/lib/resources/aws/compute/ecsServiceFactory.d.ts +13 -4
- package/dist/lib/resources/aws/compute/ecsServiceFactory.js +155 -33
- package/dist/lib/resources/aws/compute/ecsTaskDefinition.d.ts +31 -1
- package/dist/lib/resources/aws/compute/ecsTaskDefinition.js +102 -6
- package/dist/lib/resources/aws/compute/ecsTypes.d.ts +173 -13
- package/dist/lib/resources/aws/compute/ecsValidation.d.ts +9 -0
- package/dist/lib/resources/aws/compute/ecsValidation.js +63 -0
- package/dist/lib/resources/aws/compute/index.d.ts +2 -0
- package/dist/lib/resources/aws/compute/index.js +2 -0
- package/dist/lib/resources/aws/compute/lambda.d.ts +7 -13
- package/dist/lib/resources/aws/compute/lambda.js +30 -38
- package/dist/lib/resources/aws/compute/lifecycleHookLambda.source.cjs +192 -0
- package/dist/lib/resources/aws/compute/persistentDataVolume.d.ts +104 -0
- package/dist/lib/resources/aws/compute/persistentDataVolume.js +245 -0
- package/dist/lib/resources/aws/compute/persistentDataVolumeLambda.source.cjs +398 -0
- package/dist/lib/resources/aws/compute/samApplication.d.ts +15 -0
- package/dist/lib/resources/aws/compute/samApplication.js +27 -0
- package/dist/lib/resources/aws/database/clickhouseConstants.d.ts +159 -0
- package/dist/lib/resources/aws/database/clickhouseConstants.js +181 -0
- package/dist/lib/resources/aws/database/clickhouseSchemas.d.ts +71 -0
- package/dist/lib/resources/aws/database/clickhouseSchemas.js +160 -0
- package/dist/lib/resources/aws/database/clickhouseSecurityGroup.d.ts +14 -0
- package/dist/lib/resources/aws/database/clickhouseSecurityGroup.js +23 -0
- package/dist/lib/resources/aws/database/clickhouseUserData.d.ts +69 -0
- package/dist/lib/resources/aws/database/clickhouseUserData.js +371 -0
- package/dist/lib/resources/aws/database/clickhouseXmlRenderer.d.ts +56 -0
- package/dist/lib/resources/aws/database/clickhouseXmlRenderer.js +112 -0
- package/dist/lib/resources/aws/database/rdsAurora.d.ts +8 -1
- package/dist/lib/resources/aws/database/rdsAurora.js +42 -32
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.d.ts +15 -2
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +39 -43
- package/dist/lib/resources/aws/database/rdsDefaults.d.ts +6 -0
- package/dist/lib/resources/aws/database/rdsDefaults.js +7 -1
- package/dist/lib/resources/aws/database/rdsHelpers.d.ts +3 -3
- package/dist/lib/resources/aws/database/rdsHelpers.js +1 -0
- package/dist/lib/resources/aws/database/rdsInstance.d.ts +8 -1
- package/dist/lib/resources/aws/database/rdsInstance.js +51 -34
- package/dist/lib/resources/aws/database/rdsProxyOutput.d.ts +1 -1
- package/dist/lib/resources/aws/database/rdsProxyOutput.js +1 -1
- package/dist/lib/resources/aws/iam/delegationRole.js +1 -1
- package/dist/lib/resources/aws/iam/identityCenter/groupMembership.d.ts +9 -0
- package/dist/lib/resources/aws/iam/identityCenter/groupMembership.js +12 -0
- package/dist/lib/resources/aws/iam/identityCenter/index.d.ts +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/index.js +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/permissionSet.d.ts +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/permissionSet.js +1 -0
- package/dist/lib/resources/aws/logging/logGroup.d.ts +0 -8
- package/dist/lib/resources/aws/logging/logGroup.js +0 -11
- package/dist/lib/resources/aws/messaging/defaultEventBus.d.ts +7 -0
- package/dist/lib/resources/aws/messaging/defaultEventBus.js +21 -0
- package/dist/lib/resources/aws/messaging/eventBridgeRule.d.ts +96 -0
- package/dist/lib/resources/aws/messaging/eventBridgeRule.js +110 -0
- package/dist/lib/resources/aws/messaging/eventTargets.d.ts +84 -0
- package/dist/lib/resources/aws/messaging/eventTargets.js +152 -0
- package/dist/lib/resources/aws/messaging/eventbridge.d.ts +25 -2
- package/dist/lib/resources/aws/messaging/eventbridge.js +22 -10
- package/dist/lib/resources/aws/messaging/index.d.ts +5 -0
- package/dist/lib/resources/aws/messaging/index.js +2 -0
- package/dist/lib/resources/aws/messaging/schedule.d.ts +118 -0
- package/dist/lib/resources/aws/messaging/schedule.js +64 -0
- package/dist/lib/resources/aws/messaging/sns.d.ts +2 -1
- package/dist/lib/resources/aws/messaging/sqs.d.ts +2 -1
- package/dist/lib/resources/aws/messaging/subscription.d.ts +112 -0
- package/dist/lib/resources/aws/messaging/subscription.js +67 -0
- package/dist/lib/resources/aws/messaging/utils.d.ts +6 -0
- package/dist/lib/resources/aws/messaging/utils.js +10 -0
- package/dist/lib/resources/aws/monitoring/clickhouseAlarms.d.ts +60 -0
- package/dist/lib/resources/aws/monitoring/clickhouseAlarms.js +139 -0
- package/dist/lib/resources/aws/monitoring/index.d.ts +2 -0
- package/dist/lib/resources/aws/monitoring/index.js +2 -0
- package/dist/lib/resources/aws/monitoring/scheduleAlarms.d.ts +47 -0
- package/dist/lib/resources/aws/monitoring/scheduleAlarms.js +106 -0
- package/dist/lib/resources/aws/networking/crossAccountDelegationRecord.js +6 -4
- package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.js +17 -13
- package/dist/lib/resources/aws/networking/dnsRecord/dnsRecordBase.js +7 -5
- package/dist/lib/resources/aws/networking/domainCertificate.d.ts +2 -2
- package/dist/lib/resources/aws/networking/domainCertificate.js +6 -4
- package/dist/lib/resources/aws/networking/hostedZone.js +6 -5
- package/dist/lib/resources/aws/networking/serviceDiscovery.d.ts +96 -0
- package/dist/lib/resources/aws/networking/serviceDiscovery.js +96 -0
- package/dist/lib/resources/aws/networking/vpc.d.ts +4 -1
- package/dist/lib/resources/aws/networking/vpc.js +4 -1
- package/dist/lib/resources/aws/networking/vpcPeeringConnection.js +21 -3
- package/dist/lib/resources/aws/organisation/costAllocationTagActivator.d.ts +16 -5
- package/dist/lib/resources/aws/organisation/costAllocationTagActivator.js +17 -3
- package/dist/lib/resources/aws/organisation/index.d.ts +1 -1
- package/dist/lib/resources/aws/organisation/organisationPolicy.d.ts +2 -0
- package/dist/lib/resources/aws/organisation/organisationPolicy.js +3 -2
- package/dist/lib/resources/aws/secrets/secret.d.ts +7 -0
- package/dist/lib/resources/aws/secrets/secret.js +4 -3
- package/dist/lib/resources/aws/storage/bucketDeployment.d.ts +16 -0
- package/dist/lib/resources/aws/storage/bucketDeployment.js +17 -0
- package/dist/lib/resources/aws/storage/ecr.js +5 -5
- package/dist/lib/resources/aws/storage/index.d.ts +1 -0
- package/dist/lib/resources/aws/storage/index.js +1 -0
- package/dist/lib/resources/aws/storage/s3.js +10 -3
- package/dist/lib/resources/aws/utilities/customResource.js +18 -9
- package/dist/lib/synth_dump.d.ts +1 -0
- package/dist/lib/synth_dump.js +42 -0
- package/dist/lib/utils/cdkContext.d.ts +2 -0
- package/dist/lib/utils/cdkContext.js +4 -2
- package/dist/lib/utils/connections.js +6 -0
- package/dist/lib/utils/connector.d.ts +12 -0
- package/dist/lib/utils/costAllocationTags.d.ts +9 -0
- package/dist/lib/utils/costAllocationTags.js +11 -1
- package/dist/lib/utils/databaseTypes.d.ts +14 -0
- package/dist/lib/utils/getConfig.d.ts +2 -0
- package/dist/lib/utils/getConfig.js +2 -0
- package/dist/lib/utils/index.d.ts +1 -0
- package/dist/lib/utils/index.js +1 -0
- package/dist/lib/utils/manifestWriter.d.ts +6 -89
- package/dist/lib/utils/manifestWriter.js +36 -23
- package/dist/lib/utils/migrationVersionResolvers.d.ts +2 -0
- package/dist/lib/utils/migrationVersionResolvers.js +2 -0
- package/dist/lib/utils/orgConfigParser.js +2 -1
- package/dist/lib/utils/resolveAlertsTopic.d.ts +14 -0
- package/dist/lib/utils/resolveAlertsTopic.js +30 -0
- package/dist/lib/utils/validationLogger.js +6 -3
- package/package.json +22 -19
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { type Repository } from "aws-cdk-lib/aws-ecr";
|
|
2
|
-
import { type RepositoryImage } from "aws-cdk-lib/aws-ecs";
|
|
3
|
-
import { type IVpc } from "aws-cdk-lib/aws-ec2";
|
|
4
|
-
import { type
|
|
2
|
+
import { type RepositoryImage, type ContainerImage, type PortMapping, type Secret as EcsSecret, type NetworkMode } from "aws-cdk-lib/aws-ecs";
|
|
3
|
+
import { type IPeer, type ISecurityGroup, type IVpc, type Port, type SubnetSelection } from "aws-cdk-lib/aws-ec2";
|
|
4
|
+
import { type ILogGroup, type RetentionDays } from "aws-cdk-lib/aws-logs";
|
|
5
|
+
import { type PolicyDocument, type IManagedPolicy, type PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
5
6
|
import type { ITopic } from "aws-cdk-lib/aws-sns";
|
|
6
7
|
import { type ConnectionSpec } from "./interfaces/connector.js";
|
|
7
8
|
import { type RemoteConnectionSpec } from "../../resources/aws/compute/ecsRemoteConnections.js";
|
|
8
|
-
import { type EcsRoutingConfig } from "../../resources/aws/compute/ecsTypes.js";
|
|
9
|
+
import { type EcsRoutingConfig, type EcsContainerDependency } from "../../resources/aws/compute/ecsTypes.js";
|
|
9
10
|
import { ScalingType, type DomainConfig, type EcsCapacityProvider, type Ec2CapacityConfig } from "../../resources/aws/compute/ecs.js";
|
|
10
11
|
import type { EcsServiceAlarmThresholds } from "../../resources/aws/monitoring/index.js";
|
|
11
12
|
import { type SecretImport } from "../../resources/aws/secrets/index.js";
|
|
13
|
+
import type { DockerBuild } from "@fjall/util/manifest/schemas";
|
|
12
14
|
export type { RemoteConnectionSpec };
|
|
13
15
|
export { ScalingType };
|
|
14
16
|
export type { EcsCapacityProvider, Ec2CapacityConfig };
|
|
@@ -21,6 +23,22 @@ export interface EcsCapacityProviderConfig {
|
|
|
21
23
|
/** Whether this runs on EC2 instances (vs serverless Fargate) */
|
|
22
24
|
usesEc2Instances: boolean;
|
|
23
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* A dependency on another container in the same task definition.
|
|
28
|
+
* Maps directly to ECS `ContainerDependency` and the `addContainerDependencies`
|
|
29
|
+
* CDK API. `condition` corresponds to ECS's `ContainerDependencyCondition`:
|
|
30
|
+
*
|
|
31
|
+
* - `START` — dependency must have entered the running state
|
|
32
|
+
* - `COMPLETE` — dependency must have exited (any code); only valid for non-essential containers
|
|
33
|
+
* - `SUCCESS` — dependency must have exited 0; only valid for non-essential containers
|
|
34
|
+
* - `HEALTHY` — dependency must have passed its health check
|
|
35
|
+
*
|
|
36
|
+
* Public-facing alias for the canonical resource-layer `EcsContainerDependency`.
|
|
37
|
+
* Re-exported here so factory consumers can import it from the patterns barrel.
|
|
38
|
+
*
|
|
39
|
+
* @see https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDependency.html
|
|
40
|
+
*/
|
|
41
|
+
export type ContainerDependency = EcsContainerDependency;
|
|
24
42
|
/**
|
|
25
43
|
* Configuration for a container in an ECS task.
|
|
26
44
|
*
|
|
@@ -38,9 +56,20 @@ export interface EcsCapacityProviderConfig {
|
|
|
38
56
|
* { name: "app", port: 3000 }, // Primary - receives ALB traffic
|
|
39
57
|
* { name: "datadog", image: "datadog/agent" } // Sidecar - monitoring
|
|
40
58
|
* ]
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // Init container with explicit dependsOn
|
|
62
|
+
* containers: [
|
|
63
|
+
* { name: "migrate", essential: false, command: ["npx", "payload", "migrate"] },
|
|
64
|
+
* { name: "app", port: 3000, dependsOn: [{ container: "migrate", condition: "SUCCESS" }] }
|
|
65
|
+
* ]
|
|
41
66
|
*/
|
|
42
67
|
export interface EcsContainerConfig {
|
|
43
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Container name. Optional for single-container services.
|
|
70
|
+
* Required when this container is referenced by another's `dependsOn`,
|
|
71
|
+
* or when the `migrations` sugar would otherwise collide with this name.
|
|
72
|
+
*/
|
|
44
73
|
name?: string;
|
|
45
74
|
/**
|
|
46
75
|
* Container image. Options:
|
|
@@ -90,19 +119,383 @@ export interface EcsContainerConfig {
|
|
|
90
119
|
retries?: number;
|
|
91
120
|
startPeriod?: number;
|
|
92
121
|
};
|
|
122
|
+
/**
|
|
123
|
+
* Containers in the same service that must reach a given state before this
|
|
124
|
+
* container starts. Resolved at synth time — referenced container names must
|
|
125
|
+
* match another container's `name` field in the same service.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* dependsOn: [{ container: "migrate", condition: "SUCCESS" }]
|
|
129
|
+
*/
|
|
130
|
+
dependsOn?: ContainerDependency[];
|
|
131
|
+
/**
|
|
132
|
+
* Multi-port containers. CDK `PortMapping[]` verbatim. Mutually exclusive
|
|
133
|
+
* with `port` — supplying both throws a synth-time error (AC30).
|
|
134
|
+
*/
|
|
135
|
+
portMappings?: PortMapping[];
|
|
136
|
+
/**
|
|
137
|
+
* Host-bind volumes mounted into this container. Each entry produces a
|
|
138
|
+
* matching `taskDefinition.addVolume(...)` + `container.addMountPoints(...)`
|
|
139
|
+
* pair (AC31).
|
|
140
|
+
*/
|
|
141
|
+
volumes?: ContainerVolume[];
|
|
142
|
+
/**
|
|
143
|
+
* Time (seconds) ECS waits for the container to exit gracefully after
|
|
144
|
+
* sending SIGTERM before sending SIGKILL. Range: 1–120.
|
|
145
|
+
*
|
|
146
|
+
* Stateful containers (databases, queues mid-flush, anything with on-disk
|
|
147
|
+
* state) generally need longer than the CDK default (30s) to flush buffers,
|
|
148
|
+
* close connections, and persist state. Raise this when SIGTERM-to-SIGKILL
|
|
149
|
+
* inside the default window risks data loss or corruption (e.g. ClickHouse
|
|
150
|
+
* draining merges, Postgres flushing WAL).
|
|
151
|
+
*
|
|
152
|
+
* @default 30 (ECS default; CDK omits the field when unset)
|
|
153
|
+
*/
|
|
154
|
+
stopTimeout?: number;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* How the migration command is executed during deployment.
|
|
158
|
+
*
|
|
159
|
+
* - `"init-container"` (default) — synthesises a non-essential init container
|
|
160
|
+
* in the service's task definition that runs to completion before any other
|
|
161
|
+
* container starts. Every replica task pays the migration startup cost, but
|
|
162
|
+
* the migration runs inside the same task family so the deployment cannot
|
|
163
|
+
* move forward until migrations succeed. Recommended for ≤10-replica
|
|
164
|
+
* services and any service whose `migrations.command` does work other than
|
|
165
|
+
* migrations (seeding, cache warming, environment validation).
|
|
166
|
+
* - `"lifecycle-hook"` — runs the migration once per deployment via an ECS
|
|
167
|
+
* `PRE_SCALE_UP` deployment lifecycle hook (AWS, September 2025). The hook
|
|
168
|
+
* invokes a Lambda that launches the migration as a one-off task; the new
|
|
169
|
+
* replica tasks scale up only after the hook reports `SUCCEEDED`. Cuts
|
|
170
|
+
* per-replica startup latency at the cost of an extra Lambda + IAM role
|
|
171
|
+
* per service. Suitable for high-replica services where the init-container
|
|
172
|
+
* tax dominates rollout time.
|
|
173
|
+
*
|
|
174
|
+
* @see aiDocs/decisions/2026-04-29-ecs-init-container-over-runtask.md
|
|
175
|
+
* @see aiDocs/plans/2026-04-29-ecs-factory-hardening.md § 4.3.4 — threshold
|
|
176
|
+
* guidance for choosing between modes.
|
|
177
|
+
* @see https://aws.amazon.com/blogs/containers/announcing-amazon-ecs-deployment-lifecycle-hooks/
|
|
178
|
+
*/
|
|
179
|
+
export type EcsMigrationsMode = "init-container" | "lifecycle-hook" | "post-deploy";
|
|
180
|
+
/**
|
|
181
|
+
* Shorthand for the canonical "run migrations before the app starts" pattern.
|
|
182
|
+
*
|
|
183
|
+
* Default mode (`"init-container"`) synthesises a non-essential init container
|
|
184
|
+
* that runs to completion before any other container in the service starts.
|
|
185
|
+
* Optional `mode: "lifecycle-hook"` shifts the migration to an ECS deployment
|
|
186
|
+
* lifecycle hook — see {@link EcsMigrationsMode} for the trade-off.
|
|
187
|
+
*
|
|
188
|
+
* Defaults inherit from the primary container (first container with a `port`,
|
|
189
|
+
* or the first container if none have a port):
|
|
190
|
+
*
|
|
191
|
+
* - `image` → primary's `image`
|
|
192
|
+
* - `environment` → primary's `environment`
|
|
193
|
+
* - `secrets` → primary's `secrets` (SSM Parameter Store)
|
|
194
|
+
* - `secretsImport` → primary's `secretsImport` (Secrets Manager)
|
|
195
|
+
*
|
|
196
|
+
* Idempotency is the migration tool's responsibility — Payload, Prisma, Drizzle,
|
|
197
|
+
* Rails, Django, and Flyway are all idempotent by default.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* migrations: { command: ["npx", "payload", "migrate"] }
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* migrations: {
|
|
204
|
+
* command: ["prisma", "migrate", "deploy"],
|
|
205
|
+
* timeoutSeconds: 600
|
|
206
|
+
* }
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* // High-replica service: shift migration off the per-task startup path
|
|
210
|
+
* migrations: {
|
|
211
|
+
* command: ["npx", "payload", "migrate"],
|
|
212
|
+
* mode: "lifecycle-hook"
|
|
213
|
+
* }
|
|
214
|
+
*
|
|
215
|
+
* @see aiDocs/decisions/2026-04-29-ecs-init-container-over-runtask.md
|
|
216
|
+
*/
|
|
217
|
+
/**
|
|
218
|
+
* Discriminated on `mode`. The init-container variant keeps its narrow surface
|
|
219
|
+
* (no risk of authors setting CPU/memory/IAM overrides that would silently
|
|
220
|
+
* apply to the per-replica path). The lifecycle-hook variant carries `entryPoint?`
|
|
221
|
+
* and an opt-in `separateTaskDef?` sub-object for cross-cutting migrations
|
|
222
|
+
* that need permissions the service doesn't (e.g. RDS snapshot grants,
|
|
223
|
+
* cross-service Secrets Manager reads).
|
|
224
|
+
*
|
|
225
|
+
* Setting `separateTaskDef` on the init-container variant — or any
|
|
226
|
+
* lifecycle-hook-only field — is a typecheck error. This protects against
|
|
227
|
+
* the Pitfall-5 trap (silent field drift across union variants).
|
|
228
|
+
*
|
|
229
|
+
* @see aiDocs/designs/2026-05-12-migration-runner-abstraction-choice.md
|
|
230
|
+
* @see .claude/rules/typescript-standards.md § "Pitfall 5"
|
|
231
|
+
*/
|
|
232
|
+
export type EcsMigrationsConfig = EcsInitContainerMigrationsConfig | EcsLifecycleHookMigrationsConfig | EcsPostDeployMigrationsConfig;
|
|
233
|
+
/**
|
|
234
|
+
* Union of the two lambda-driven deployment hook variants. Internal helper
|
|
235
|
+
* type — narrows from `EcsMigrationsConfig` once `expandMigrationsSugar` has
|
|
236
|
+
* established the migration runs out-of-band via a lifecycle hook (vs as an
|
|
237
|
+
* init container).
|
|
238
|
+
*/
|
|
239
|
+
export type EcsHookMigrationsConfig = EcsLifecycleHookMigrationsConfig | EcsPostDeployMigrationsConfig;
|
|
240
|
+
/**
|
|
241
|
+
* Type-narrowing predicate for the two lambda-driven hook variants. Returns
|
|
242
|
+
* true for `"lifecycle-hook"` (PRE_SCALE_UP) and `"post-deploy"` (POST_SCALE_UP).
|
|
243
|
+
* Narrows the whole `EcsMigrationsConfig` to the hook-variant union, not just
|
|
244
|
+
* the `mode` property, so callers can read `separateTaskDef` / `entryPoint`
|
|
245
|
+
* etc. on the narrowed object.
|
|
246
|
+
*/
|
|
247
|
+
export declare function isHookMigrations(config: EcsMigrationsConfig): config is EcsHookMigrationsConfig;
|
|
248
|
+
/**
|
|
249
|
+
* `mode: "init-container"` variant — migration runs as a non-essential init
|
|
250
|
+
* container inside each replica's task, dependsOn `COMPLETE` before main starts.
|
|
251
|
+
* `entryPoint` and `separateTaskDef` are intentionally absent — the per-replica
|
|
252
|
+
* init-container path has no separate IAM role to grant against.
|
|
253
|
+
*/
|
|
254
|
+
export interface EcsInitContainerMigrationsConfig {
|
|
255
|
+
/**
|
|
256
|
+
* Where the migration command runs during deployment. Defaults to
|
|
257
|
+
* `"init-container"`. Either omit (defaults) or set explicitly.
|
|
258
|
+
*/
|
|
259
|
+
mode?: "init-container";
|
|
260
|
+
/** Migration command, e.g. `["npx", "payload", "migrate"]`. Required. */
|
|
261
|
+
command: string[];
|
|
262
|
+
/** Override timeout in seconds. Defaults to 300 (5 min). */
|
|
263
|
+
timeoutSeconds?: number;
|
|
264
|
+
/** Override image. Defaults to inheriting from the primary container. */
|
|
265
|
+
image?: string | Repository;
|
|
266
|
+
/** Override environment. Defaults to inheriting from the primary container. */
|
|
267
|
+
environment?: Record<string, string>;
|
|
268
|
+
/** Override Secrets-Manager imports. Defaults to inheriting from the primary container. */
|
|
269
|
+
secretsImport?: Record<string, SecretImport>;
|
|
270
|
+
/** Override SSM secret keys. Defaults to inheriting from the primary container. */
|
|
271
|
+
secrets?: string[];
|
|
272
|
+
/**
|
|
273
|
+
* Synthetic container name. Defaults to `"migrate"`.
|
|
274
|
+
* Override when a service container is already named `migrate`.
|
|
275
|
+
*/
|
|
276
|
+
name?: string;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* `mode: "lifecycle-hook"` variant — migration runs out-of-band via an ECS
|
|
280
|
+
* deployment lifecycle hook (PRE_SCALE_UP). The service rollout BLOCKS until
|
|
281
|
+
* the migration succeeds; one task per deploy.
|
|
282
|
+
*
|
|
283
|
+
* When `separateTaskDef` is present, `wireLifecycleHookMigrations` synthesises
|
|
284
|
+
* a SEPARATE migration task definition (its own IAM role, log group, runtime
|
|
285
|
+
* platform) instead of using `ContainerOverrides` on the service task def.
|
|
286
|
+
* Required when migrations need permissions the service doesn't.
|
|
287
|
+
*/
|
|
288
|
+
export interface EcsLifecycleHookMigrationsConfig {
|
|
289
|
+
/** Required for the lifecycle-hook variant. */
|
|
290
|
+
mode: "lifecycle-hook";
|
|
291
|
+
/** Migration command, e.g. `["node", "scripts/migration-runner.mjs"]`. Required. */
|
|
292
|
+
command: string[];
|
|
293
|
+
/** Override timeout in seconds. Defaults to 300 (5 min). Capped at 900s per Lambda invocation; longer migrations use the IN_PROGRESS callback chain. */
|
|
294
|
+
timeoutSeconds?: number;
|
|
295
|
+
/**
|
|
296
|
+
* Override image URI (string only). CDK `Repository` constructs cannot be
|
|
297
|
+
* JSON-serialised into the runner Lambda's `MIGRATE_CONFIG` env var; synth
|
|
298
|
+
* throws if a `Repository` is passed in lifecycle-hook mode.
|
|
299
|
+
*/
|
|
300
|
+
image?: string;
|
|
301
|
+
/** Override environment. */
|
|
302
|
+
environment?: Record<string, string>;
|
|
303
|
+
/** Secrets-Manager imports for the migration container. */
|
|
304
|
+
secretsImport?: Record<string, SecretImport>;
|
|
305
|
+
/** SSM Parameter Store secret keys. */
|
|
306
|
+
secrets?: string[];
|
|
307
|
+
/** Synthetic container name. Defaults to `"migrate"`. */
|
|
308
|
+
name?: string;
|
|
309
|
+
/**
|
|
310
|
+
* Container entrypoint. Defaults to inheriting from the image. Set to
|
|
311
|
+
* `["/usr/bin/tini", "--"]` (or similar) to keep PID-1 signalling clean
|
|
312
|
+
* inside long-running migration containers.
|
|
313
|
+
*/
|
|
314
|
+
entryPoint?: string[];
|
|
315
|
+
/**
|
|
316
|
+
* When present, synthesise a SEPARATE migration task definition (its own
|
|
317
|
+
* IAM role, log group, runtime platform) instead of using `ContainerOverrides`
|
|
318
|
+
* on the service task def. Required when migrations need permissions the
|
|
319
|
+
* service doesn't (e.g. `rds:CreateDBSnapshot`, cross-service Secrets Manager
|
|
320
|
+
* reads) — preserves least-privilege on the service task role.
|
|
321
|
+
*
|
|
322
|
+
* When absent, the lifecycle-hook runner uses the service's task def via
|
|
323
|
+
* ContainerOverrides — existing behaviour, unchanged.
|
|
324
|
+
*/
|
|
325
|
+
separateTaskDef?: EcsLifecycleHookMigrationsSeparateTaskDef;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* `mode: "post-deploy"` variant — runs out-of-band via an ECS deployment
|
|
329
|
+
* lifecycle hook on the POST_SCALE_UP stage. Fires AFTER the new task revision
|
|
330
|
+
* has scaled up and is healthy. A `FAILED` return from the hook triggers ECS
|
|
331
|
+
* deployment circuit-breaker rollback to the previous revision.
|
|
332
|
+
*
|
|
333
|
+
* Use cases: post-deploy data backfills that should run against the new code
|
|
334
|
+
* (not gate the rollout), cache warming, smoke tests that exercise the live
|
|
335
|
+
* service, sanity-check migrations that don't need to block traffic shift.
|
|
336
|
+
* Do NOT use for schema migrations that the new code depends on — use the
|
|
337
|
+
* pre-deploy `mode: "lifecycle-hook"` variant for those.
|
|
338
|
+
*
|
|
339
|
+
* Identical input shape to the lifecycle-hook variant; the only difference is
|
|
340
|
+
* the stage at which AWS fires the hook.
|
|
341
|
+
*/
|
|
342
|
+
export interface EcsPostDeployMigrationsConfig {
|
|
343
|
+
/** Required for the post-deploy variant. */
|
|
344
|
+
mode: "post-deploy";
|
|
345
|
+
/** Migration/backfill command. Required. */
|
|
346
|
+
command: string[];
|
|
347
|
+
/** Override timeout in seconds. Defaults to 300 (5 min). Capped at 900s per Lambda invocation. */
|
|
348
|
+
timeoutSeconds?: number;
|
|
349
|
+
/** Override image URI (string only). */
|
|
350
|
+
image?: string;
|
|
351
|
+
/** Override environment. */
|
|
352
|
+
environment?: Record<string, string>;
|
|
353
|
+
/** Secrets-Manager imports for the migration container. */
|
|
354
|
+
secretsImport?: Record<string, SecretImport>;
|
|
355
|
+
/** SSM Parameter Store secret keys. */
|
|
356
|
+
secrets?: string[];
|
|
357
|
+
/** Synthetic container name. Defaults to `"migrate"`. */
|
|
358
|
+
name?: string;
|
|
359
|
+
/** Container entrypoint. Defaults to inheriting from the image. */
|
|
360
|
+
entryPoint?: string[];
|
|
361
|
+
/**
|
|
362
|
+
* When present, synthesise a SEPARATE migration task definition. Same
|
|
363
|
+
* semantics as `EcsLifecycleHookMigrationsConfig.separateTaskDef`.
|
|
364
|
+
*/
|
|
365
|
+
separateTaskDef?: EcsLifecycleHookMigrationsSeparateTaskDef;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Sub-config for `EcsLifecycleHookMigrationsConfig.separateTaskDef`. The
|
|
369
|
+
* migration container is parameterised exactly like every other container via
|
|
370
|
+
* the same `<ServiceName>ImageTag` CfnParameter — task-def revisions roll over
|
|
371
|
+
* whenever the parameter value changes.
|
|
372
|
+
*/
|
|
373
|
+
export interface EcsLifecycleHookMigrationsSeparateTaskDef {
|
|
374
|
+
/** Fargate task CPU (256, 512, 1024, 2048, 4096, 8192, 16384). */
|
|
375
|
+
cpu: number;
|
|
376
|
+
/** Task memory in MiB — must be compatible with `cpu` per the AWS Fargate task-size matrix. */
|
|
377
|
+
memoryLimitMiB: number;
|
|
378
|
+
/** Extra IAM statements appended to the migration task role only. */
|
|
379
|
+
taskRolePolicies?: PolicyStatement[];
|
|
380
|
+
/**
|
|
381
|
+
* Extra SG egress for the migration task. Omit to reuse the service's
|
|
382
|
+
* security group(s). Use this when the migration reaches a peer the
|
|
383
|
+
* service itself doesn't talk to.
|
|
384
|
+
*/
|
|
385
|
+
egressTo?: Array<{
|
|
386
|
+
peer: IPeer;
|
|
387
|
+
port: Port;
|
|
388
|
+
description: string;
|
|
389
|
+
}>;
|
|
390
|
+
/**
|
|
391
|
+
* Runtime Secrets Manager reads — typed sugar that grants the migration task
|
|
392
|
+
* role `secretsmanager:GetSecretValue` on the named secrets, scoped to the
|
|
393
|
+
* specific ARNs (never `*`).
|
|
394
|
+
*
|
|
395
|
+
* Different from `secretsImport`: `secretsImport` mounts a secret value as
|
|
396
|
+
* an env var at container start via the ECS agent (execution role permission).
|
|
397
|
+
* `extraSecretReads` is for migrations that fetch secret values dynamically
|
|
398
|
+
* at runtime via the AWS SDK — e.g. when the secret name is computed inside
|
|
399
|
+
* the migration script, or when the migration writes back into Secrets
|
|
400
|
+
* Manager after rotation.
|
|
401
|
+
*
|
|
402
|
+
* Equivalent to passing the same statement via `taskRolePolicies`; this form
|
|
403
|
+
* is preferred for readability.
|
|
404
|
+
*/
|
|
405
|
+
extraSecretReads?: Array<{
|
|
406
|
+
/** Secrets Manager secret name or ARN. */
|
|
407
|
+
secretName: string;
|
|
408
|
+
/** Optional human-facing description used in IAM statement Sid. */
|
|
409
|
+
description?: string;
|
|
410
|
+
}>;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Deployment circuit breaker policy for an ECS service.
|
|
414
|
+
*
|
|
415
|
+
* The circuit breaker watches a new deployment and, on detecting persistent
|
|
416
|
+
* task launch failures, marks the deployment as failed. With `rollback: true`
|
|
417
|
+
* the service automatically returns to the previous stable task definition.
|
|
418
|
+
*
|
|
419
|
+
* Defaults to `{ rollback: true }` when omitted — matches every example in
|
|
420
|
+
* AWS's own circuit-breaker documentation. CDK's default is `rollback: false`;
|
|
421
|
+
* we override to the safer shape.
|
|
422
|
+
*
|
|
423
|
+
* Set `circuitBreaker: false` to disable the breaker entirely (not recommended
|
|
424
|
+
* for production services).
|
|
425
|
+
*
|
|
426
|
+
* Set `circuitBreaker: { rollback: false }` to enable detection without
|
|
427
|
+
* automatic rollback — useful for first deploys where there is no prior
|
|
428
|
+
* baseline to roll back to.
|
|
429
|
+
*
|
|
430
|
+
* @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-circuit-breaker.html
|
|
431
|
+
*/
|
|
432
|
+
export interface EcsCircuitBreakerConfig {
|
|
433
|
+
/**
|
|
434
|
+
* Roll back to the previous stable deployment when the circuit breaker
|
|
435
|
+
* trips. Defaults to `true`.
|
|
436
|
+
*/
|
|
437
|
+
rollback?: boolean;
|
|
93
438
|
}
|
|
94
439
|
/**
|
|
95
440
|
* ECS scaling configuration.
|
|
96
|
-
* - Omit: enabled
|
|
97
|
-
* - `{}`:
|
|
98
|
-
* - `{ minCapacity: 2, maxCapacity: 10 }`: custom scaling
|
|
441
|
+
* - Omit: enabled, `minCapacity` tracks `desiredCount`, `maxCapacity` defaults to `Math.max(desiredCount + 1, 3)`
|
|
442
|
+
* - `{}`: same as omit
|
|
443
|
+
* - `{ minCapacity: 2, maxCapacity: 10 }`: custom scaling (explicit values win)
|
|
99
444
|
* - `false`: explicitly disabled
|
|
445
|
+
*
|
|
446
|
+
* Setting `minCapacity > 0` while `desiredCount: 0` throws at synth — Application
|
|
447
|
+
* Auto Scaling would immediately scale the service back up, defeating the toggle.
|
|
100
448
|
*/
|
|
101
449
|
export interface EcsScalingConfig {
|
|
102
450
|
minCapacity?: number;
|
|
103
451
|
maxCapacity?: number;
|
|
104
452
|
scalingType?: ScalingType;
|
|
105
453
|
}
|
|
454
|
+
/**
|
|
455
|
+
* Host-bind volume mounted into one or more containers in the same task.
|
|
456
|
+
* Maps to ECS `Volume` + `MountPoint` pairs — see AC29 + AC31.
|
|
457
|
+
*/
|
|
458
|
+
export interface ContainerVolume {
|
|
459
|
+
/** Volume name. Used as `sourceVolume` on the container's mount point. */
|
|
460
|
+
name: string;
|
|
461
|
+
/**
|
|
462
|
+
* Host path bound into the container. Omit for an empty Docker volume that
|
|
463
|
+
* lives only for the task's lifetime (no host directory mount).
|
|
464
|
+
*/
|
|
465
|
+
hostSourcePath?: string;
|
|
466
|
+
/** Path inside the container the volume is mounted at. */
|
|
467
|
+
mountPath: string;
|
|
468
|
+
/** Mount the volume read-only. Default: false. */
|
|
469
|
+
readOnly?: boolean;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Scheduled-task entry on the cluster. Each entry produces one
|
|
473
|
+
* `Ec2TaskDefinition` registered under the synthetic key `name` in
|
|
474
|
+
* `EcsCompute`'s task-definition map (collision-checked against steady-state
|
|
475
|
+
* service names) and an `app.addSchedule(...)` invocation. See AC27 + AC34.
|
|
476
|
+
*/
|
|
477
|
+
export interface EcsScheduledTaskConfig {
|
|
478
|
+
/** Synthetic name. Must not collide with any steady-state `serviceName`. */
|
|
479
|
+
name: string;
|
|
480
|
+
/** Cron or rate expression — passed verbatim to `app.addSchedule`. */
|
|
481
|
+
schedule: string;
|
|
482
|
+
/** CDK `ContainerImage` — typically `ContainerImage.fromRegistry(...)`. */
|
|
483
|
+
image: ContainerImage;
|
|
484
|
+
cpu: number;
|
|
485
|
+
memoryLimitMiB: number;
|
|
486
|
+
command?: string[];
|
|
487
|
+
/** Container secrets (Secrets Manager / SSM) — same shape as ECS `secrets`. */
|
|
488
|
+
secrets?: Record<string, EcsSecret>;
|
|
489
|
+
/** Pre-existing CDK log group. Mutually exclusive with `logRetention`. */
|
|
490
|
+
logGroup?: ILogGroup;
|
|
491
|
+
/** When `logGroup` is omitted, the awsLogs driver creates one with this retention. */
|
|
492
|
+
logRetention?: RetentionDays;
|
|
493
|
+
securityGroups?: ISecurityGroup[];
|
|
494
|
+
subnetSelection?: SubnetSelection;
|
|
495
|
+
networkMode?: NetworkMode;
|
|
496
|
+
/** Host-bind volumes mounted into the task's container. */
|
|
497
|
+
volumes?: ContainerVolume[];
|
|
498
|
+
}
|
|
106
499
|
/**
|
|
107
500
|
* Cluster-level configuration.
|
|
108
501
|
* Controls the shared ALB for all services in this cluster.
|
|
@@ -133,6 +526,19 @@ export interface EcsClusterConfig {
|
|
|
133
526
|
* Allows for multi-region deployments with advanced DNS routing.
|
|
134
527
|
*/
|
|
135
528
|
domainConfig?: DomainConfig;
|
|
529
|
+
/**
|
|
530
|
+
* Externally-supplied security group for the cluster's EC2 capacity. When
|
|
531
|
+
* provided, the ECS service factory wires this SG onto the underlying
|
|
532
|
+
* `Ec2Instance` instead of creating its own. Used by stateful workloads
|
|
533
|
+
* (e.g. ClickHouseDatabase) that own their security group lifecycle.
|
|
534
|
+
*/
|
|
535
|
+
securityGroup?: ISecurityGroup;
|
|
536
|
+
/**
|
|
537
|
+
* Scheduled tasks materialised into `Ec2TaskDefinition`s and registered via
|
|
538
|
+
* `app.addSchedule(...)` against the existing `EcsScheduleTarget` shape
|
|
539
|
+
* ({ ecs, serviceName, taskCount }). See AC34.
|
|
540
|
+
*/
|
|
541
|
+
scheduledTasks?: EcsScheduledTaskConfig[];
|
|
136
542
|
}
|
|
137
543
|
export type { EcsRoutingConfig };
|
|
138
544
|
/**
|
|
@@ -207,21 +613,14 @@ export interface EcsServiceConfig {
|
|
|
207
613
|
*/
|
|
208
614
|
scaling?: EcsScalingConfig | false;
|
|
209
615
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
|
|
213
|
-
dockerfilePath?: string;
|
|
214
|
-
/**
|
|
215
|
-
* Docker build target stage for multi-stage Dockerfiles.
|
|
216
|
-
* When specified, the CLI builds with `--target <dockerTarget>`.
|
|
217
|
-
* The image tag suffix is also updated: `<service>-<target>-latest`.
|
|
616
|
+
* Dockerfile build configuration for this service. Carries the path
|
|
617
|
+
* (absolute or relative), an optional build `context` for monorepo
|
|
618
|
+
* layouts, and an optional multi-stage `target`.
|
|
218
619
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* { name: "api", dockerTarget: "api" } // builds: myapp-api-api-latest
|
|
222
|
-
* { name: "worker", dockerTarget: "worker" } // builds: myapp-worker-worker-latest
|
|
620
|
+
* Tagged image suffix when `target` is set: `<service>-<target>-latest`.
|
|
621
|
+
* Mutually exclusive with `image` (pre-built URI).
|
|
223
622
|
*/
|
|
224
|
-
|
|
623
|
+
docker?: DockerBuild;
|
|
225
624
|
/**
|
|
226
625
|
* Additional inline policies for this service's task role.
|
|
227
626
|
* Added on top of the default ECS Exec permissions.
|
|
@@ -259,6 +658,21 @@ export interface EcsServiceConfig {
|
|
|
259
658
|
* ]
|
|
260
659
|
*/
|
|
261
660
|
connections?: ConnectionSpec[];
|
|
661
|
+
/**
|
|
662
|
+
* Schema-version gate opt-out. Defaults `true`.
|
|
663
|
+
*
|
|
664
|
+
* When any database in `connections` carries a `migrations` block, every
|
|
665
|
+
* container in this service receives `EXPECTED_SCHEMA_VERSION` resolved
|
|
666
|
+
* from that database's migration tool at synth time. Set `false` to skip
|
|
667
|
+
* the injection — intended for sidecars that intentionally tolerate
|
|
668
|
+
* schema drift or one-shot maintenance tasks.
|
|
669
|
+
*
|
|
670
|
+
* Named opt-out is auditable: grep-recoverable across the monorepo. Note
|
|
671
|
+
* the spelling collision with `@fjall/generator`'s codemod pipeline gate
|
|
672
|
+
* at `validationGate/gates/schema.ts` — different surface, different
|
|
673
|
+
* concept.
|
|
674
|
+
*/
|
|
675
|
+
schemaGate?: boolean;
|
|
262
676
|
/**
|
|
263
677
|
* Cross-app resources reachable via VPC peering. Each entry resolves the
|
|
264
678
|
* peered app's exposed resource at synth time (SSM `valueForStringParameter`
|
|
@@ -309,6 +723,96 @@ export interface EcsServiceConfig {
|
|
|
309
723
|
* - object: override specific thresholds
|
|
310
724
|
*/
|
|
311
725
|
alarms?: EcsServiceAlarmThresholds | false;
|
|
726
|
+
/**
|
|
727
|
+
* Run an init container before any other container in this service starts.
|
|
728
|
+
* Synthesises a non-essential container with the given migration command,
|
|
729
|
+
* inherits image / env / secrets from the primary container, and auto-wires
|
|
730
|
+
* every other container to wait on `SUCCESS`.
|
|
731
|
+
*
|
|
732
|
+
* @example
|
|
733
|
+
* migrations: { command: ["npx", "payload", "migrate"] }
|
|
734
|
+
*/
|
|
735
|
+
migrations?: EcsMigrationsConfig;
|
|
736
|
+
/**
|
|
737
|
+
* Deployment circuit breaker policy. Omit for the safe default
|
|
738
|
+
* `{ enable: true, rollback: true }` — failed deployments automatically
|
|
739
|
+
* roll back to the previous stable task definition.
|
|
740
|
+
*
|
|
741
|
+
* Set to `false` to disable the breaker entirely. Set to
|
|
742
|
+
* `{ rollback: false }` for detection without automatic rollback (useful
|
|
743
|
+
* for first deploys where there is no prior baseline).
|
|
744
|
+
*
|
|
745
|
+
* @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/deployment-circuit-breaker.html
|
|
746
|
+
*/
|
|
747
|
+
circuitBreaker?: false | EcsCircuitBreakerConfig;
|
|
748
|
+
/**
|
|
749
|
+
* Rolling-deploy capacity bounds (percent of `desiredCount`).
|
|
750
|
+
*
|
|
751
|
+
* - `minHealthyPercent` (0–100): floor of healthy tasks during a deploy.
|
|
752
|
+
* `0` allows full task drain before the new task starts (recreate
|
|
753
|
+
* semantics — required for singletons backed by an EBS volume that only
|
|
754
|
+
* one task can attach to at a time, e.g. ClickHouse).
|
|
755
|
+
* - `maxHealthyPercent` (100–200): ceiling of running tasks during a
|
|
756
|
+
* deploy. `100` forbids overlap (matches the singleton/recreate shape).
|
|
757
|
+
* The default `200` allows a fresh task to start before the old one
|
|
758
|
+
* drains (rolling shape — fits stateless services).
|
|
759
|
+
*
|
|
760
|
+
* Both must satisfy `min <= max`, and they cannot both be `100`
|
|
761
|
+
* (a no-op deploy that can't drain or expand).
|
|
762
|
+
*
|
|
763
|
+
* @default `{ minHealthyPercent: 100, maxHealthyPercent: 200 }` (CDK default)
|
|
764
|
+
*/
|
|
765
|
+
deployment?: {
|
|
766
|
+
minHealthyPercent?: number;
|
|
767
|
+
maxHealthyPercent?: number;
|
|
768
|
+
};
|
|
769
|
+
/**
|
|
770
|
+
* Cloud Map service discovery for this service. When provided, the pattern
|
|
771
|
+
* registers the service against the application-level Cloud Map namespace
|
|
772
|
+
* (`app.getNamespace().registerService({ name })`) and threads the resulting
|
|
773
|
+
* `IService` to the resources layer, which calls `associateCloudMapService`
|
|
774
|
+
* after service construction. The namespace is `<appName>.local` and is
|
|
775
|
+
* lazily created on first registration — no cluster-level configuration.
|
|
776
|
+
*
|
|
777
|
+
* `dnsRecordType` defaults to `"A"` (paired with the AWS_VPC networkMode
|
|
778
|
+
* default). Set to `"SRV"` only when explicitly overriding `networkMode` to
|
|
779
|
+
* `HOST` or `BRIDGE` — CDK's `Ec2Service.associateCloudMapService(...)`
|
|
780
|
+
* rejects A records under those modes (the task shares the host's ENI IP,
|
|
781
|
+
* so the published port must travel with the record).
|
|
782
|
+
*/
|
|
783
|
+
serviceDiscovery?: {
|
|
784
|
+
name: string;
|
|
785
|
+
dnsRecordType?: "A" | "SRV";
|
|
786
|
+
};
|
|
787
|
+
/**
|
|
788
|
+
* Override the task definition's `NetworkMode`. Defaults:
|
|
789
|
+
* - EC2 services: `AWS_VPC` (per-task ENI → per-task SG, A-record service
|
|
790
|
+
* discovery works, current AWS recommendation for new workloads).
|
|
791
|
+
* - EC2 services with `cluster.directAccess: true`: `HOST` (direct port
|
|
792
|
+
* binding to the instance, required for ECS Exec → host-port flows).
|
|
793
|
+
* - Fargate services: `AWS_VPC` (CDK requirement, not overridable).
|
|
794
|
+
*
|
|
795
|
+
* Cloud Map service discovery works under all three modes:
|
|
796
|
+
* - `AWS_VPC`: A records (default `serviceDiscovery.dnsRecordType`).
|
|
797
|
+
* - `HOST` / `BRIDGE`: SRV records — set
|
|
798
|
+
* `serviceDiscovery.dnsRecordType: "SRV"` so the published port travels
|
|
799
|
+
* with the record.
|
|
800
|
+
*
|
|
801
|
+
* ENI quota: each task under `AWS_VPC` attaches an ENI to the host
|
|
802
|
+
* instance. Instance ENI limits cap tasks-per-instance (e.g. t4g.medium
|
|
803
|
+
* → 2 tasks). For scale beyond the limit, enable ENI trunking at the
|
|
804
|
+
* account+instance level, pick larger instances, or override to `BRIDGE`.
|
|
805
|
+
*/
|
|
806
|
+
networkMode?: NetworkMode;
|
|
807
|
+
/**
|
|
808
|
+
* Pre-existing security groups attached to this service's task ENIs (AWS_VPC
|
|
809
|
+
* mode). When omitted, CDK auto-creates a default service SG. Stateful
|
|
810
|
+
* patterns that own a wrapper SG (e.g. `ClickHouseDatabase`) set this so
|
|
811
|
+
* `this.connections.securityGroups[0]` is honest — the SG it points at is
|
|
812
|
+
* the SG the task ENI actually wears, not a CDK-autogenerated sibling that
|
|
813
|
+
* arbitrates no traffic.
|
|
814
|
+
*/
|
|
815
|
+
securityGroups?: ISecurityGroup[];
|
|
312
816
|
}
|
|
313
817
|
/**
|
|
314
818
|
* ECS compute configuration.
|
|
@@ -371,11 +875,10 @@ export interface EcsComputeProps {
|
|
|
371
875
|
*/
|
|
372
876
|
ecrRepository?: Repository | RepositoryImage;
|
|
373
877
|
/**
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
* not used during CDK synthesis.
|
|
878
|
+
* Cluster-level Dockerfile build configuration. Used when no service-level
|
|
879
|
+
* `docker` is set. Metadata for the CLI build process; not used during synth.
|
|
377
880
|
*/
|
|
378
|
-
|
|
881
|
+
docker?: DockerBuild;
|
|
379
882
|
/**
|
|
380
883
|
* SNS topic for alarm notifications. Resolved to ITopic and passed to EcsCluster.
|
|
381
884
|
* Accepts either an ITopic directly or a topic ARN string (resolved internally).
|
|
@@ -1,2 +1,12 @@
|
|
|
1
1
|
import { ScalingType } from "../../resources/aws/compute/ecs.js";
|
|
2
2
|
export { ScalingType };
|
|
3
|
+
/**
|
|
4
|
+
* Type-narrowing predicate for the two lambda-driven hook variants. Returns
|
|
5
|
+
* true for `"lifecycle-hook"` (PRE_SCALE_UP) and `"post-deploy"` (POST_SCALE_UP).
|
|
6
|
+
* Narrows the whole `EcsMigrationsConfig` to the hook-variant union, not just
|
|
7
|
+
* the `mode` property, so callers can read `separateTaskDef` / `entryPoint`
|
|
8
|
+
* etc. on the narrowed object.
|
|
9
|
+
*/
|
|
10
|
+
export function isHookMigrations(config) {
|
|
11
|
+
return config.mode === "lifecycle-hook" || config.mode === "post-deploy";
|
|
12
|
+
}
|
|
@@ -106,11 +106,6 @@ interface BaseLambdaProps {
|
|
|
106
106
|
* ]
|
|
107
107
|
*/
|
|
108
108
|
connections?: ConnectionSpec[];
|
|
109
|
-
/**
|
|
110
|
-
* EventBridge schedule expression for scheduled Lambda invocations.
|
|
111
|
-
* Uses cron or rate syntax: "rate(1 hour)" or "cron(0 12 * * ? *)".
|
|
112
|
-
*/
|
|
113
|
-
scheduleExpression?: string;
|
|
114
109
|
}
|
|
115
110
|
/**
|
|
116
111
|
* Container-based Lambda using ECR image.
|
|
@@ -68,7 +68,6 @@ export class LambdaCompute extends Construct {
|
|
|
68
68
|
functionUrlAuthType,
|
|
69
69
|
functionUrlCors,
|
|
70
70
|
functionUrlInvokeMode,
|
|
71
|
-
scheduleExpression: props.scheduleExpression,
|
|
72
71
|
ephemeralStorageSize: props.ephemeralStorageSize,
|
|
73
72
|
secrets: props.secrets,
|
|
74
73
|
ssmSecretsPath: props.ssmSecretsPath,
|
|
@@ -96,7 +95,7 @@ export class LambdaCompute extends Construct {
|
|
|
96
95
|
);
|
|
97
96
|
}
|
|
98
97
|
catch (error) {
|
|
99
|
-
throw new Error(`Failed to process connections for Lambda '${id}': ${error instanceof Error ? error.message : String(error)}
|
|
98
|
+
throw new Error(`Failed to process connections for Lambda '${id}': ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
100
99
|
}
|
|
101
100
|
}
|
|
102
101
|
}
|