@fjall/components-infrastructure 0.95.0 → 0.99.1
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 +90 -107
- package/dist/lib/app.js +149 -139
- 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 +7 -8
- 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 +172 -0
- package/dist/lib/patterns/aws/clickhouseDatabase.js +600 -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 +95 -396
- package/dist/lib/patterns/aws/computeEcs.js +880 -46
- package/dist/lib/patterns/aws/computeEcsTypes.d.ts +889 -0
- package/dist/lib/patterns/aws/computeEcsTypes.js +12 -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 +8 -7
- package/dist/lib/patterns/aws/index.d.ts +3 -0
- package/dist/lib/patterns/aws/index.js +3 -0
- package/dist/lib/patterns/aws/interfaces/compute.d.ts +13 -1
- package/dist/lib/patterns/aws/interfaces/connector.d.ts +1 -1
- package/dist/lib/patterns/aws/interfaces/connector.js +1 -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 +4 -2
- package/dist/lib/patterns/aws/interfaces/index.js +4 -2
- 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/interfaces/vpcPeer.d.ts +7 -0
- package/dist/lib/patterns/aws/interfaces/vpcPeer.js +1 -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 +24 -5
- 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.d.ts +34 -0
- package/dist/lib/patterns/aws/vpcPeer.js +38 -0
- package/dist/lib/patterns/aws/vpcPeerAccepter.d.ts +29 -0
- package/dist/lib/patterns/aws/vpcPeerAccepter.js +196 -0
- package/dist/lib/resources/aws/analytics/clickhouse.js +25 -7
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.d.ts +49 -0
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.js +140 -0
- package/dist/lib/resources/aws/analytics/clickhouseConstants.d.ts +4 -4
- package/dist/lib/resources/aws/analytics/clickhouseConstants.js +6 -4
- package/dist/lib/resources/aws/analytics/clickhouseTypes.d.ts +12 -0
- package/dist/lib/resources/aws/analytics/clickhouseUserData.d.ts +1 -0
- package/dist/lib/resources/aws/analytics/clickhouseUserData.js +56 -5
- package/dist/lib/resources/aws/analytics/index.d.ts +2 -0
- package/dist/lib/resources/aws/analytics/index.js +1 -0
- 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/ecsRemoteConnections.d.ts +38 -0
- package/dist/lib/resources/aws/compute/ecsRemoteConnections.js +80 -0
- 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 +110 -6
- package/dist/lib/resources/aws/compute/ecsTypes.d.ts +180 -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 +157 -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 +12 -5
- 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 -3
- package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.d.ts +40 -0
- package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.js +158 -0
- package/dist/lib/resources/aws/networking/dnsRecord/dnsRecordBase.js +7 -4
- package/dist/lib/resources/aws/networking/domainCertificate.d.ts +2 -2
- package/dist/lib/resources/aws/networking/domainCertificate.js +6 -3
- package/dist/lib/resources/aws/networking/hostedZone.js +6 -4
- package/dist/lib/resources/aws/networking/index.d.ts +3 -0
- package/dist/lib/resources/aws/networking/index.js +3 -0
- 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 +10 -3
- package/dist/lib/resources/aws/networking/vpcPeeringAccepterRole.d.ts +18 -0
- package/dist/lib/resources/aws/networking/vpcPeeringAccepterRole.js +61 -0
- package/dist/lib/resources/aws/networking/vpcPeeringConnection.d.ts +49 -0
- package/dist/lib/resources/aws/networking/vpcPeeringConnection.js +106 -0
- 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/bastionFactory.d.ts +10 -0
- package/dist/lib/utils/bastionFactory.js +29 -0
- package/dist/lib/utils/capitaliseString.d.ts +1 -1
- package/dist/lib/utils/capitaliseString.js +1 -1
- package/dist/lib/utils/cdkContext.d.ts +10 -0
- package/dist/lib/utils/cdkContext.js +13 -0
- package/dist/lib/utils/connections.d.ts +7 -1
- package/dist/lib/utils/connections.js +21 -0
- package/dist/lib/utils/connector.d.ts +30 -2
- package/dist/lib/utils/connector.js +6 -1
- package/dist/lib/utils/costAllocationTags.d.ts +15 -0
- package/dist/lib/utils/costAllocationTags.js +16 -0
- 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 +4 -0
- package/dist/lib/utils/index.js +4 -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/dist/lib/utils/vpcPeerInterface.d.ts +22 -0
- package/dist/lib/utils/vpcPeerInterface.js +1 -0
- package/package.json +22 -18
|
@@ -0,0 +1,889 @@
|
|
|
1
|
+
import { type Repository } from "aws-cdk-lib/aws-ecr";
|
|
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";
|
|
6
|
+
import type { ITopic } from "aws-cdk-lib/aws-sns";
|
|
7
|
+
import { type ConnectionSpec } from "./interfaces/connector.js";
|
|
8
|
+
import { type RemoteConnectionSpec } from "../../resources/aws/compute/ecsRemoteConnections.js";
|
|
9
|
+
import { type EcsRoutingConfig, type EcsContainerDependency } from "../../resources/aws/compute/ecsTypes.js";
|
|
10
|
+
import { ScalingType, type DomainConfig, type EcsCapacityProvider, type Ec2CapacityConfig } from "../../resources/aws/compute/ecs.js";
|
|
11
|
+
import type { EcsServiceAlarmThresholds } from "../../resources/aws/monitoring/index.js";
|
|
12
|
+
import { type SecretImport } from "../../resources/aws/secrets/index.js";
|
|
13
|
+
import type { DockerBuild } from "@fjall/util/manifest/schemas";
|
|
14
|
+
export type { RemoteConnectionSpec };
|
|
15
|
+
export { ScalingType };
|
|
16
|
+
export type { EcsCapacityProvider, Ec2CapacityConfig };
|
|
17
|
+
/**
|
|
18
|
+
* Configuration for ECS capacity providers.
|
|
19
|
+
*/
|
|
20
|
+
export interface EcsCapacityProviderConfig {
|
|
21
|
+
/** Whether this uses Spot pricing */
|
|
22
|
+
usesSpot: boolean;
|
|
23
|
+
/** Whether this runs on EC2 instances (vs serverless Fargate) */
|
|
24
|
+
usesEc2Instances: boolean;
|
|
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;
|
|
42
|
+
/**
|
|
43
|
+
* Configuration for a container in an ECS task.
|
|
44
|
+
*
|
|
45
|
+
* For single-container services, `name` is optional and defaults to `${serviceName}Container`.
|
|
46
|
+
* For multi-container tasks, the first container with a `port` is the **primary container**
|
|
47
|
+
* that receives load balancer traffic.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Single container (name auto-generated)
|
|
51
|
+
* containers: [{ port: 3000 }]
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Multi-container with sidecars
|
|
55
|
+
* containers: [
|
|
56
|
+
* { name: "app", port: 3000 }, // Primary - receives ALB traffic
|
|
57
|
+
* { name: "datadog", image: "datadog/agent" } // Sidecar - monitoring
|
|
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
|
+
* ]
|
|
66
|
+
*/
|
|
67
|
+
export interface EcsContainerConfig {
|
|
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
|
+
*/
|
|
73
|
+
name?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Container image. Options:
|
|
76
|
+
* - Omit: Uses app's default ECR repository (primary container only)
|
|
77
|
+
* - string: ECR repository name or public image URL
|
|
78
|
+
* - Repository: CDK ECR Repository construct
|
|
79
|
+
*/
|
|
80
|
+
image?: string | Repository;
|
|
81
|
+
/**
|
|
82
|
+
* Port the container listens on.
|
|
83
|
+
* The first container with a port becomes the **primary container**
|
|
84
|
+
* and is registered with the load balancer.
|
|
85
|
+
*/
|
|
86
|
+
port?: number;
|
|
87
|
+
/** Environment variables */
|
|
88
|
+
environment?: Record<string, string>;
|
|
89
|
+
/**
|
|
90
|
+
* Secrets from AWS SSM Parameter Store.
|
|
91
|
+
* Array of secret names that will be fetched from the service's SSM namespace.
|
|
92
|
+
* The namespace path is auto-determined from app/cluster/service names.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* // Secrets at /myapp/api-cluster/users/API_KEY and /myapp/api-cluster/users/DB_PASSWORD
|
|
96
|
+
* secrets: ["API_KEY", "DB_PASSWORD"]
|
|
97
|
+
*/
|
|
98
|
+
secrets?: string[];
|
|
99
|
+
/** Secrets imported from other CDK resources (AWS Secrets Manager) */
|
|
100
|
+
secretsImport?: Record<string, SecretImport>;
|
|
101
|
+
/** Command to run in the container */
|
|
102
|
+
command?: string[];
|
|
103
|
+
/** Entry point for the container */
|
|
104
|
+
entryPoint?: string[];
|
|
105
|
+
/**
|
|
106
|
+
* Whether this container is essential.
|
|
107
|
+
* If an essential container stops, all containers in the task stop.
|
|
108
|
+
* Default: true
|
|
109
|
+
*/
|
|
110
|
+
essential?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Health check configuration.
|
|
113
|
+
* Default: For primary container with port, uses curl health check.
|
|
114
|
+
*/
|
|
115
|
+
healthCheck?: {
|
|
116
|
+
command: string[];
|
|
117
|
+
interval?: number;
|
|
118
|
+
timeout?: number;
|
|
119
|
+
retries?: number;
|
|
120
|
+
startPeriod?: number;
|
|
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;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* ECS scaling configuration.
|
|
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)
|
|
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.
|
|
448
|
+
*/
|
|
449
|
+
export interface EcsScalingConfig {
|
|
450
|
+
minCapacity?: number;
|
|
451
|
+
maxCapacity?: number;
|
|
452
|
+
scalingType?: ScalingType;
|
|
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
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Cluster-level configuration.
|
|
501
|
+
* Controls the shared ALB for all services in this cluster.
|
|
502
|
+
*/
|
|
503
|
+
export interface EcsClusterConfig {
|
|
504
|
+
/**
|
|
505
|
+
* Domain for HTTPS access.
|
|
506
|
+
* - Omit: ALB created with default DNS (*.elb.amazonaws.com)
|
|
507
|
+
* - Specified: Creates ACM certificate + Route53 DNS A record
|
|
508
|
+
*/
|
|
509
|
+
domain?: string;
|
|
510
|
+
/**
|
|
511
|
+
* Load balancer configuration.
|
|
512
|
+
* - Omit or "public": Internet-facing ALB (default)
|
|
513
|
+
* - "internal": VPC-only ALB
|
|
514
|
+
* - false: No ALB (for workers/background processors)
|
|
515
|
+
*/
|
|
516
|
+
loadBalancer?: false | "public" | "internal";
|
|
517
|
+
/**
|
|
518
|
+
* Enable direct EC2 access without ALB.
|
|
519
|
+
* Uses host network mode for predictable ports.
|
|
520
|
+
* Access via EC2 public IP at container port.
|
|
521
|
+
*/
|
|
522
|
+
directAccess?: boolean;
|
|
523
|
+
/**
|
|
524
|
+
* Advanced domain configuration for routing policies (latency, weighted, geo).
|
|
525
|
+
* Only used when domain is specified.
|
|
526
|
+
* Allows for multi-region deployments with advanced DNS routing.
|
|
527
|
+
*/
|
|
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[];
|
|
542
|
+
}
|
|
543
|
+
export type { EcsRoutingConfig };
|
|
544
|
+
/**
|
|
545
|
+
* Configuration for a service in an ECS cluster.
|
|
546
|
+
* Each service gets its own task definition, scaling config, and target group.
|
|
547
|
+
*
|
|
548
|
+
* @example
|
|
549
|
+
* // Simple service
|
|
550
|
+
* { name: "api", containers: [{ port: 3000 }] }
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* // Service with routing (for multi-service clusters)
|
|
554
|
+
* { name: "users", containers: [{ port: 3000 }], routing: { path: "/users/*", priority: 100 } }
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* // Service with multiple routing rules (same target group)
|
|
558
|
+
* { name: "web", containers: [{ port: 3000 }], routing: [
|
|
559
|
+
* { path: "/api/v2/*", priority: 50 },
|
|
560
|
+
* { path: "/*", priority: 200 },
|
|
561
|
+
* ]}
|
|
562
|
+
*
|
|
563
|
+
* @example
|
|
564
|
+
* // Service with sidecars
|
|
565
|
+
* {
|
|
566
|
+
* name: "api",
|
|
567
|
+
* containers: [
|
|
568
|
+
* { name: "app", port: 3000 },
|
|
569
|
+
* { name: "datadog", image: "datadog/agent" }
|
|
570
|
+
* ]
|
|
571
|
+
* }
|
|
572
|
+
*/
|
|
573
|
+
export interface EcsServiceConfig {
|
|
574
|
+
/** Service name (unique within cluster) */
|
|
575
|
+
name: string;
|
|
576
|
+
/**
|
|
577
|
+
* Container image for this service (applies to first container without explicit image).
|
|
578
|
+
* - Omit: Uses app's default ECR repository
|
|
579
|
+
* - string: ECR repository name or public image URL
|
|
580
|
+
* - Repository: CDK ECR Repository construct
|
|
581
|
+
*/
|
|
582
|
+
image?: string | Repository;
|
|
583
|
+
/**
|
|
584
|
+
* Container configuration(s) for this service.
|
|
585
|
+
* For single-container services, container name is optional and auto-generated.
|
|
586
|
+
* For multi-container services, the first container with a port is the primary container.
|
|
587
|
+
*/
|
|
588
|
+
containers?: EcsContainerConfig[];
|
|
589
|
+
/**
|
|
590
|
+
* Routing rules for this service on the cluster's ALB.
|
|
591
|
+
* Required when cluster has multiple services with ports.
|
|
592
|
+
* Optional for single service (gets /* automatically).
|
|
593
|
+
* Can be a single rule or an array of rules pointing to the same target group.
|
|
594
|
+
*
|
|
595
|
+
* @example
|
|
596
|
+
* // Multiple routes for the same service
|
|
597
|
+
* routing: [
|
|
598
|
+
* { path: "/api/v2/*", priority: 50 },
|
|
599
|
+
* { path: "/*", priority: 200 },
|
|
600
|
+
* ]
|
|
601
|
+
*/
|
|
602
|
+
routing?: EcsRoutingConfig | EcsRoutingConfig[];
|
|
603
|
+
/** CPU units for this service's tasks (256-4096) */
|
|
604
|
+
cpu?: number;
|
|
605
|
+
/** Memory in MiB for this service's tasks (512-30720) */
|
|
606
|
+
memoryLimitMiB?: number;
|
|
607
|
+
/** Desired number of tasks. Default: 2 */
|
|
608
|
+
desiredCount?: number;
|
|
609
|
+
/**
|
|
610
|
+
* Scaling configuration.
|
|
611
|
+
* - Omit: enabled with defaults
|
|
612
|
+
* - false: disabled
|
|
613
|
+
*/
|
|
614
|
+
scaling?: EcsScalingConfig | false;
|
|
615
|
+
/**
|
|
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`.
|
|
619
|
+
*
|
|
620
|
+
* Tagged image suffix when `target` is set: `<service>-<target>-latest`.
|
|
621
|
+
* Mutually exclusive with `image` (pre-built URI).
|
|
622
|
+
*/
|
|
623
|
+
docker?: DockerBuild;
|
|
624
|
+
/**
|
|
625
|
+
* Additional inline policies for this service's task role.
|
|
626
|
+
* Added on top of the default ECS Exec permissions.
|
|
627
|
+
* Use for service-specific AWS permissions (S3, DynamoDB, SQS, etc.).
|
|
628
|
+
*/
|
|
629
|
+
taskRoleInlinePolicies?: Record<string, PolicyDocument>;
|
|
630
|
+
/**
|
|
631
|
+
* Additional managed policies for this service's task role.
|
|
632
|
+
* Added on top of the default ECS Exec permissions.
|
|
633
|
+
*/
|
|
634
|
+
taskRoleManagedPolicies?: IManagedPolicy[];
|
|
635
|
+
/**
|
|
636
|
+
* Resources this service needs to connect to (e.g., databases, S3 buckets, SQS queues).
|
|
637
|
+
* Creates security group rules for IConnectable resources and IAM grants for IAM resources.
|
|
638
|
+
* Follows least-privilege - only this service gets access, not all services in the cluster.
|
|
639
|
+
*
|
|
640
|
+
* Supports:
|
|
641
|
+
* - IConnectable: Security group resources (RDS, ECS, etc.)
|
|
642
|
+
* - IStorageConnector: S3 buckets (IAM grants)
|
|
643
|
+
* - IDynamoDBConnector: DynamoDB tables (IAM grants)
|
|
644
|
+
* - IQueueConnector: SQS queues (IAM grants)
|
|
645
|
+
* - ConnectionConfig: Explicit access level configuration
|
|
646
|
+
*
|
|
647
|
+
* @example
|
|
648
|
+
* // Simple connections (default permissions)
|
|
649
|
+
* connections: [database, bucket, cache, queue]
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* // Explicit access levels
|
|
653
|
+
* connections: [
|
|
654
|
+
* database, // Security group (RDS)
|
|
655
|
+
* { resource: cache, access: "read" }, // Read-only DynamoDB
|
|
656
|
+
* { resource: bucket, access: "write" }, // Write-only S3
|
|
657
|
+
* { resource: queue, access: "consume" } // Consume-only SQS
|
|
658
|
+
* ]
|
|
659
|
+
*/
|
|
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;
|
|
676
|
+
/**
|
|
677
|
+
* Cross-app resources reachable via VPC peering. Each entry resolves the
|
|
678
|
+
* peered app's exposed resource at synth time (SSM `valueForStringParameter`
|
|
679
|
+
* reads) and injects `${PREFIX}_HOST` + `${PREFIX}_PORT` env vars into every
|
|
680
|
+
* container in this service's task definition.
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* remoteConnections: [
|
|
684
|
+
* { peer, resource: "MainDatabase" },
|
|
685
|
+
* { peer, resource: "CoreApi", envPrefix: "DATA_PLATFORM_API" }
|
|
686
|
+
* ]
|
|
687
|
+
*/
|
|
688
|
+
remoteConnections?: RemoteConnectionSpec[];
|
|
689
|
+
/**
|
|
690
|
+
* Capacity provider for this service. REQUIRED.
|
|
691
|
+
* Each service specifies its own capacity provider.
|
|
692
|
+
*
|
|
693
|
+
* @example
|
|
694
|
+
* // Mixed FARGATE and EC2 services in same cluster
|
|
695
|
+
* {
|
|
696
|
+
* services: [
|
|
697
|
+
* { name: "api", capacityProvider: "FARGATE" },
|
|
698
|
+
* { name: "worker", capacityProvider: "EC2", ec2Config: { instanceType: "t4g.micro" } }
|
|
699
|
+
* ]
|
|
700
|
+
* }
|
|
701
|
+
*/
|
|
702
|
+
capacityProvider: EcsCapacityProvider;
|
|
703
|
+
/**
|
|
704
|
+
* EC2 capacity configuration for this service.
|
|
705
|
+
* Only used when service capacityProvider is "EC2".
|
|
706
|
+
* Services with matching ec2Config share an ASG for efficiency.
|
|
707
|
+
*/
|
|
708
|
+
ec2Config?: Ec2CapacityConfig;
|
|
709
|
+
/**
|
|
710
|
+
* SSM Parameter Store path for secrets.
|
|
711
|
+
* If not specified, secrets are fetched from /<app>/<cluster>/<service>.
|
|
712
|
+
* Use this to override the default convention.
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* // Override default path
|
|
716
|
+
* ssmSecretsPath: "/custom/path/to/secrets"
|
|
717
|
+
*/
|
|
718
|
+
ssmSecretsPath?: string;
|
|
719
|
+
/**
|
|
720
|
+
* Per-service alarm configuration.
|
|
721
|
+
* - undefined: use defaults (CPU, memory, running tasks, 5xx if ALB)
|
|
722
|
+
* - false: disable alarms for this service
|
|
723
|
+
* - object: override specific thresholds
|
|
724
|
+
*/
|
|
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[];
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* ECS compute configuration.
|
|
819
|
+
* Creates an ECS cluster with one or more services sharing a load balancer.
|
|
820
|
+
*
|
|
821
|
+
* @example
|
|
822
|
+
* // Single service
|
|
823
|
+
* app.addCompute(ComputeFactory.build("WebApp", {
|
|
824
|
+
* type: "ecs",
|
|
825
|
+
* cluster: { domain: "app.example.com" },
|
|
826
|
+
* services: [{ name: "web", containers: [{ port: 3000 }] }]
|
|
827
|
+
* }));
|
|
828
|
+
*
|
|
829
|
+
* @example
|
|
830
|
+
* // Multi-service cluster with routing
|
|
831
|
+
* app.addCompute(ComputeFactory.build("ApiCluster", {
|
|
832
|
+
* type: "ecs",
|
|
833
|
+
* cluster: { domain: "api.example.com" },
|
|
834
|
+
* services: [
|
|
835
|
+
* { name: "users", containers: [{ port: 3000 }], routing: { path: "/users/*" } },
|
|
836
|
+
* { name: "orders", containers: [{ port: 3001 }], routing: { path: "/orders/*" } }
|
|
837
|
+
* ]
|
|
838
|
+
* }));
|
|
839
|
+
*
|
|
840
|
+
* @example
|
|
841
|
+
* // Internal workers (no ALB)
|
|
842
|
+
* app.addCompute(ComputeFactory.build("Workers", {
|
|
843
|
+
* type: "ecs",
|
|
844
|
+
* cluster: { loadBalancer: false },
|
|
845
|
+
* services: [{ name: "processor" }, { name: "emailer" }]
|
|
846
|
+
* }));
|
|
847
|
+
*/
|
|
848
|
+
export interface EcsComputeProps {
|
|
849
|
+
type: "ecs";
|
|
850
|
+
vpc?: IVpc;
|
|
851
|
+
/**
|
|
852
|
+
* Application name for SSM secrets namespace.
|
|
853
|
+
* When containers use secrets, the path is derived as: /<appName>/<clusterName>/<serviceName>
|
|
854
|
+
* Auto-derived from App.getName() if not specified.
|
|
855
|
+
*/
|
|
856
|
+
appName?: string;
|
|
857
|
+
/**
|
|
858
|
+
* Cluster configuration.
|
|
859
|
+
* Controls the shared ALB for all services in this cluster.
|
|
860
|
+
* - Omit: ALB created with default settings
|
|
861
|
+
* - `{ domain: "..." }`: ALB with HTTPS + DNS
|
|
862
|
+
* - `{ loadBalancer: false }`: No ALB (internal workers)
|
|
863
|
+
*/
|
|
864
|
+
cluster?: EcsClusterConfig;
|
|
865
|
+
/**
|
|
866
|
+
* Services in this cluster.
|
|
867
|
+
* Each service gets its own task definition, scaling, and target group.
|
|
868
|
+
* Each service MUST specify its own capacityProvider.
|
|
869
|
+
* All services share the cluster's ALB (unless disabled).
|
|
870
|
+
*/
|
|
871
|
+
services: EcsServiceConfig[];
|
|
872
|
+
/**
|
|
873
|
+
* ECR repository for all services (default image).
|
|
874
|
+
* Individual services can override with their own `image` property.
|
|
875
|
+
*/
|
|
876
|
+
ecrRepository?: Repository | RepositoryImage;
|
|
877
|
+
/**
|
|
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.
|
|
880
|
+
*/
|
|
881
|
+
docker?: DockerBuild;
|
|
882
|
+
/**
|
|
883
|
+
* SNS topic for alarm notifications. Resolved to ITopic and passed to EcsCluster.
|
|
884
|
+
* Accepts either an ITopic directly or a topic ARN string (resolved internally).
|
|
885
|
+
*/
|
|
886
|
+
alertsTopic?: ITopic | string;
|
|
887
|
+
/** Application ID for alarm tagging (used by webhook to map alarms to applications). */
|
|
888
|
+
applicationId?: string;
|
|
889
|
+
}
|