@glicogh/healthcare-cdk 0.1.88 → 0.1.90
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/.env.example +2 -0
- package/README.md +76 -2
- package/dist/@types/common.d.ts +1 -1
- package/dist/@types/common.js +2 -1
- package/dist/constructs/legacy-s3-backups-bus.d.ts +23 -0
- package/dist/constructs/legacy-s3-backups-bus.js +111 -0
- package/dist/constructs/migration-scripts-runner.d.ts +20 -0
- package/dist/constructs/migration-scripts-runner.js +59 -0
- package/dist/constructs/migration-state-machine.d.ts +48 -0
- package/dist/constructs/migration-state-machine.js +399 -0
- package/dist/lib/microservice-migration.js +114 -4
- package/dist/scripts/post-deployment-clickhouse.sh +5 -0
- package/dist/scripts/post-deployment-policy-service.sh +5 -13
- package/dist/util/constants.d.ts +3 -1
- package/dist/util/constants.js +3 -1
- package/dist/util/initBuildConfig.js +8 -1
- package/dist/util/initCdkStack.js +34 -19
- package/dist/util/migration.d.ts +5 -1
- package/dist/util/migration.js +58 -42
- package/package.json +2 -1
- package/scripts/post-deployment-clickhouse.sh +5 -0
- package/scripts/post-deployment-policy-service.sh +5 -13
package/.env.example
CHANGED
|
@@ -5,6 +5,8 @@ COMPANY_NAME=glico
|
|
|
5
5
|
AWS_REGION=eu-west-2
|
|
6
6
|
AWS_ACCOUNT_ID=825765383017
|
|
7
7
|
|
|
8
|
+
# Optional local overrides go in .env.local (gitignored), e.g. MIGRATION_REPO_PATH=/path/to/migration
|
|
9
|
+
|
|
8
10
|
EC2_REDIS_INSTANCE_TYPE=t4g.nano
|
|
9
11
|
EC2_REDIS_INSTANCE_STORAGE_SIZE=
|
|
10
12
|
EC2_REDIS_INSTANCE_STORAGE_TYPE=gp3
|
package/README.md
CHANGED
|
@@ -91,13 +91,87 @@ The following stack are meant to be deployed once and shared across the microser
|
|
|
91
91
|
- MicroserviceRedis
|
|
92
92
|
- MicroserviceMySQL
|
|
93
93
|
- MicroserviceClickHouse
|
|
94
|
+
- MicroserviceMigration
|
|
94
95
|
|
|
95
|
-
The only required option for these
|
|
96
|
+
The only required option for these stacks is `env`. To deploy a single shared stack, pass its `service` value:
|
|
97
|
+
|
|
98
|
+
| Stack | `service` |
|
|
99
|
+
| ---------------------- | ------------ |
|
|
100
|
+
| MicroserviceNetwork | `network` |
|
|
101
|
+
| MicroserviceInfraAuth | `infra-auth` |
|
|
102
|
+
| MicroserviceRedis | `redis` |
|
|
103
|
+
| MicroserviceMySQL | `mysql` |
|
|
104
|
+
| MicroserviceClickHouse | `clickhouse` |
|
|
105
|
+
| MicroserviceMigration | `migration` |
|
|
106
|
+
|
|
107
|
+
For example, to deploy `MicroserviceNetwork` in the UAT environment, you would run the command
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
cdk --profile glicogh-uat --context env=uat --context service=network deploy
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Only the selected stack is synthesized, so unrelated stacks (and their code assets, such as the migration Lambdas) are not bundled. Omitting `service` synthesizes and deploys all shared stacks. Alternatively, when deploying by stack name (`cdk --context env=uat deploy MicroserviceNetwork`), pass `--exclusively` to `synth`/`deploy`/`diff` to skip bundling unrelated stacks.
|
|
114
|
+
|
|
115
|
+
### Migration orchestrator (MicroserviceMigration)
|
|
116
|
+
|
|
117
|
+
`MicroserviceMigration` bundles the migration producer/consumer Lambdas (from the sibling `migration/lambdas` directory), the `migration-queue.fifo` queue, a `migration-verifier` Lambda, an S3 artifacts bucket, a one-shot ECS Fargate scripts runner, and the `migration-orchestrator` Step Function (`cdk/constructs/migration-state-machine.ts`). Invoking the state machine runs the migration runbook end-to-end:
|
|
118
|
+
|
|
119
|
+
The stack also provisions the `legacy-s3-backups` EventBridge bus (`cdk/constructs/legacy-s3-backups-bus.ts`) for legacy S3 backup events forwarded from the main account (`169555392631`, see `legacyS3BackupsMainAccountId`). The bus allows `events:PutEvents` from that account, has CloudWatch logging enabled at TRACE/FULL detail delivered through vended logs to `/aws/vendedlogs/events/event-bus/legacy-s3-backups`, and a rule that logs every event payload to the `legacy-s3-backups` log group. The bus ARN is exported as the `legacy-s3-backups-arn` output.
|
|
120
|
+
|
|
121
|
+
The bus also auto-starts the migration orchestrator from source archives landing in `s3://glicogh-pether-backup` (`legacyBackupBucketName`, read cross-account by the ECS scripts task role). Triggers are declared once in CDK as `MIGRATION_TRIGGERS` (`{ name, prefix, options, once }`) and passed to the `migration-runner` Lambda; the `legacy-s3-backups-migration-runner` rule forwards every event on the bus to it, and the runner applies the trigger policy itself. Today: `daily_backups/*.tar.gz` starts a delta run (`restoreMode: 'delta', affected: true, precomputeMode: 'incremental'`), and the first `weekly_backups/*.tar.gz` ever starts a fresh full run (`resetTracking: true, precomputeMode: 'full'`, `once: true`) — later weekly events are skipped until the SSM marker `/<env>/microservices/migration/triggers/weekly` is deleted. Every trigger also skips while an orchestrator execution is already RUNNING, and derives the execution name from the object key for dedupe.
|
|
122
|
+
|
|
123
|
+
Daily runs are **deltas**: the payload adds `restoreMode: 'delta', affected: true`, so `s1-restore-delta` inserts the changed rows into the persistent legacy tables (no DROP/CREATE, duplicate key updates the row) and skips `s2-migrations`; `s4b-resolve-affected` then maps the changed rows (`migration_affected_source`) to resource ids (`migration_affected`, including claim `batch_key`s via `claim_batches.sibling_claim_ids`), and each resource step runs a targeted pass with `skipMigrated: false` so the target APIs receive updates, followed by `migration-clear-affected` for that resource. Weekly runs keep the full restore → schema → `skipMigrated` top-up path. Daily precompute is incremental (`precomputeMode: 'incremental'`): `s3-disease-lookups` and `s4-claim-batches` update only the batches/disease mappings touched by `migration_affected_source`, instead of truncating and rescanning; weekly/full runs use `precomputeMode: 'full'`. The restore ECS task downloads the archive, extracts it (top-level CSV folder or flat), and runs `restore-legacy-backup`.
|
|
124
|
+
|
|
125
|
+
- **Scripts (runbook Steps 1–4)** run as one-shot ECS Fargate tasks from the migration repo's `Dockerfile` (entrypoint dispatches `restore` / `migrations` / `diseases` / `claim-batches` / `reset`). The restore task syncs the legacy dump from S3 first; no 15-minute Lambda cap. The precompute steps (`diseases`, `claim-batches`) always run when a restore runs; without one they only run when selected via `runPrecompute`. Their mode comes from `precomputeMode` (`incremental` updates only the delta's changed rows; `full` truncates and rebuilds).
|
|
126
|
+
- **Migratables (Steps 5–16)** loop the producer Lambda until the response reports `endReached: true`, then wait for the SQS queue to drain (`ApproximateNumberOfMessages` + `NotVisible` = 0) before the next dependency step. Tier 0 (users, providers, insured, tpa, plans) runs as a `Parallel`.
|
|
127
|
+
- **Every resource gets a retry pass** (`fromStart: true, skipMigrated: true`) after the first pass + drain, recovering records dropped by transient service failures.
|
|
128
|
+
- **Verification** invokes the verifier Lambda, which writes `runs/<execution-name>/summary.json` (migrated counts, source counts, API totals) to the artifacts bucket.
|
|
129
|
+
|
|
130
|
+
**Prerequisites**: deploy the shared stacks (the migration stack alone with `cdk --profile glicogh-uat --context env=uat --context service=migration deploy`); upload the legacy dump to the artifacts bucket (`glicogh-healthcare-migration-<env>-<account>`):
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
aws s3 sync data/legacy-backup s3://glicogh-healthcare-migration-uat-825765383017/backups/<runId>/
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Start an execution** (all input fields are optional; defaults shown):
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"backupS3Uri": "s3://glicogh-healthcare-migration-uat-825765383017/backups/<runId>/",
|
|
141
|
+
"resetTracking": false,
|
|
142
|
+
"restore": true,
|
|
143
|
+
"runPrecompute": [],
|
|
144
|
+
"skipMigrated": true,
|
|
145
|
+
"refresh": false,
|
|
146
|
+
"ignoreProgress": false,
|
|
147
|
+
"fromStep": ""
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
- `backupS3Uri` is required only when the restore step runs (omit it with `restore: false` or a `fromStep` past restore).
|
|
152
|
+
- `resetTracking: true` truncates `migrated`/`disease_lookup`/`claim_batches` and clears the Redis cursors before restoring; it cannot be combined with `restore: false`.
|
|
153
|
+
- `restore: false` runs against the existing legacy DB (skips the reset/restore steps).
|
|
154
|
+
- `runPrecompute` selects which precompute steps (`"diseases"`, `"claim-batches"`) run when `restore` is false; `true` means all, `[]`/`false` means none (default `[]`). A restore always runs both precomputes. `precomputeMode` (`"full"` default, or `"incremental"`) selects their mode independently of `restoreMode`.
|
|
155
|
+
- `skipMigrated: true` (default) publishes only records without a `migrated` row — a completed step ends immediately and advances its cursor; `skipMigrated: false` publishes from the cursor onward (existing records are PUT-updated).
|
|
156
|
+
- `refresh: true` (requires `skipMigrated: false`) republishes every record from the start, so migrated records are PUT-updated; combine with `fromStep` to scope it to one step.
|
|
157
|
+
- `ignoreProgress: true` clears the recorded progress marker and re-evaluates the start point (`resetTracking`/`restore`).
|
|
158
|
+
- `fromStep` jumps to a step and records the step before it as the progress baseline.
|
|
96
159
|
|
|
97
160
|
```
|
|
98
|
-
|
|
161
|
+
aws stepfunctions start-execution \
|
|
162
|
+
--state-machine-arn <state-machine-arn> \
|
|
163
|
+
--name <runId> \
|
|
164
|
+
--input file://input.json
|
|
99
165
|
```
|
|
100
166
|
|
|
167
|
+
Step ids for `fromStep`: `fresh-reset`, `restore`, `migrations`, `diseases`, `claim-batches`, `product-sources`, `product-categories`, `products`, `categories`, `coverage-groups`, `tier0`, `product-pricing`, `policies`, `benefits`, `plans-rewire`, `beneficiaries-principals`, `beneficiaries-dependants`, `beneficiary-photos`, `claims`.
|
|
168
|
+
|
|
169
|
+
**Pause/resume**: the state machine records the last completed step in the SSM parameter `/<env>/microservices/migration/orchestrator/progress` (imported by name, not managed by CloudFormation; holds the last completed step id, or `none` when cleared). Stop the execution and re-invoke with the same input — it resumes at the step after the recorded one (skipped precompute steps are recorded too, so a resume continues past them). `ignoreProgress: true` clears the marker and re-evaluates the start point; `fromStep` jumps explicitly and writes the preceding step as the baseline. Every step is idempotent and cursor-backed; with the default `skipMigrated: true` a fully-migrated step returns immediately (`endReached`, cursor advanced). Guards fail the execution instead of looping forever: 2,000 producer invocations per pass, 4,000 drain checks (30-second interval). Execution timeout 7 days.
|
|
170
|
+
|
|
171
|
+
**Monitoring**: Step Functions execution history; state-machine logs at `/aws/vendedlogs/states/migration-orchestrator`; ECS task logs under `/aws/ecs/migration-scripts`; the verifier summary in S3.
|
|
172
|
+
|
|
173
|
+
**Notes**: the consumer's reserved concurrency is set to `max(50, MIGRATION_QUEUE_SHARDS)` so claims FIFO shards run in parallel. `resetTracking: true` truncates `migrated`/`disease_lookup`/`claim_batches` and clears the `glico_healthcare_migration:*` Redis cursors before restoring; the restore task re-imports all tables per run (container-local tracking). Secure envs (`DB_PASSWORD`, `MIGRATION_API_KEY`) are injected into the ECS task from SSM.
|
|
174
|
+
|
|
101
175
|
### Pipeline-based stack
|
|
102
176
|
|
|
103
177
|
The following stack on the other hand, are meant to deploy a new set of resources on each CDK deployment. These can also be thought of as the stack that have a GIT repository.
|
package/dist/@types/common.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type BuildConfig = {
|
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
export type Microservice = 'account' | 'plan' | 'policy' | 'claims' | 'notification' | 'reporting';
|
|
19
|
-
export type OtherCDKService = 'network' | 'api-gateway' | 'redis' | 'mysql' | 'clickhouse' | 'portal' | 'migration';
|
|
19
|
+
export type OtherCDKService = 'network' | 'infra-auth' | 'api-gateway' | 'redis' | 'mysql' | 'clickhouse' | 'portal' | 'migration';
|
|
20
20
|
export declare const MicroserviceEnum: Record<Microservice, Microservice>;
|
|
21
21
|
export declare const MicroserviceList: Microservice[];
|
|
22
22
|
export declare const LaravelBasedServiceList: ("account" | "plan" | "policy" | "claims" | "reporting")[];
|
package/dist/@types/common.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.MicroserviceList = Object.values(exports.MicroserviceEnum);
|
|
|
13
13
|
exports.LaravelBasedServiceList = exports.MicroserviceList.filter((i) => i !== 'notification');
|
|
14
14
|
exports.OtherCDKServiceEnum = {
|
|
15
15
|
network: 'network',
|
|
16
|
+
'infra-auth': 'infra-auth',
|
|
16
17
|
'api-gateway': 'api-gateway',
|
|
17
18
|
redis: 'redis',
|
|
18
19
|
mysql: 'mysql',
|
|
@@ -21,4 +22,4 @@ exports.OtherCDKServiceEnum = {
|
|
|
21
22
|
migration: 'migration',
|
|
22
23
|
};
|
|
23
24
|
exports.OtherCDKServiceList = Object.values(exports.OtherCDKServiceEnum);
|
|
24
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vQHR5cGVzL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFxQmEsUUFBQSxnQkFBZ0IsR0FBdUM7SUFDbEUsT0FBTyxFQUFFLFNBQVM7SUFDbEIsSUFBSSxFQUFFLE1BQU07SUFDWixNQUFNLEVBQUUsUUFBUTtJQUNoQixZQUFZLEVBQUUsY0FBYztJQUM1QixTQUFTLEVBQUUsV0FBVztJQUN0QixNQUFNLEVBQUUsUUFBUTtDQUNqQixDQUFDO0FBRVcsUUFBQSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLHdCQUFnQixDQUFDLENBQUM7QUFFbkQsUUFBQSx1QkFBdUIsR0FBRyx3QkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxjQUFjLENBQUMsQ0FBQztBQUUvRSxRQUFBLG1CQUFtQixHQUE2QztJQUMzRSxPQUFPLEVBQUUsU0FBUztJQUNsQixZQUFZLEVBQUUsWUFBWTtJQUMxQixhQUFhLEVBQUUsYUFBYTtJQUM1QixLQUFLLEVBQUUsT0FBTztJQUNkLEtBQUssRUFBRSxPQUFPO0lBQ2QsVUFBVSxFQUFFLFlBQVk7SUFDeEIsTUFBTSxFQUFFLFFBQVE7SUFDaEIsU0FBUyxFQUFFLFdBQVc7Q0FDdkIsQ0FBQztBQUVXLFFBQUEsbUJBQW1CLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQywyQkFBbUIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgRW52TmFtZSA9ICd1YXQnIHwgJ3Byb2QnO1xuZXhwb3J0IHR5cGUgUmVwb0JyYW5jaCA9ICdtYXN0ZXInIHwgJ3JlbGVhc2UnO1xuZXhwb3J0IHR5cGUgQnVpbGRDb25maWcgPSB7XG4gIGFwcE5hbWU6IHN0cmluZztcbiAgYXBwVmVyc2lvbjogc3RyaW5nO1xuICBidWlsZElkOiBzdHJpbmc7XG4gIGZvcm1hdHRlZEJ1aWxkSWQ6IHN0cmluZztcbiAgZW52TmFtZTogRW52TmFtZTtcbiAgZW52UGF0aDogc3RyaW5nO1xuICBzZXJ2aWNlTmFtZTogTWljcm9zZXJ2aWNlIHwgT3RoZXJDREtTZXJ2aWNlO1xuICBicmFuY2g/OiBzdHJpbmc7XG4gIGNvbXBhbnlOYW1lOiBzdHJpbmc7XG4gIGF3czoge1xuICAgIGFjY291bnQ6IHN0cmluZztcbiAgICByZWdpb246IHN0cmluZztcbiAgfTtcbn07XG5leHBvcnQgdHlwZSBNaWNyb3NlcnZpY2UgPSAnYWNjb3VudCcgfCAncGxhbicgfCAncG9saWN5JyB8ICdjbGFpbXMnIHwgJ25vdGlmaWNhdGlvbicgfCAncmVwb3J0aW5nJztcblxuZXhwb3J0IHR5cGUgT3RoZXJDREtTZXJ2aWNlID0gJ25ldHdvcmsnIHwgJ2luZnJhLWF1dGgnIHwgJ2FwaS1nYXRld2F5JyB8ICdyZWRpcycgfCAnbXlzcWwnIHwgJ2NsaWNraG91c2UnIHwgJ3BvcnRhbCcgfCAnbWlncmF0aW9uJztcblxuZXhwb3J0IGNvbnN0IE1pY3Jvc2VydmljZUVudW06IFJlY29yZDxNaWNyb3NlcnZpY2UsIE1pY3Jvc2VydmljZT4gPSB7XG4gIGFjY291bnQ6ICdhY2NvdW50JyxcbiAgcGxhbjogJ3BsYW4nLFxuICBwb2xpY3k6ICdwb2xpY3knLFxuICBub3RpZmljYXRpb246ICdub3RpZmljYXRpb24nLFxuICByZXBvcnRpbmc6ICdyZXBvcnRpbmcnLFxuICBjbGFpbXM6ICdjbGFpbXMnLFxufTtcblxuZXhwb3J0IGNvbnN0IE1pY3Jvc2VydmljZUxpc3QgPSBPYmplY3QudmFsdWVzKE1pY3Jvc2VydmljZUVudW0pO1xuXG5leHBvcnQgY29uc3QgTGFyYXZlbEJhc2VkU2VydmljZUxpc3QgPSBNaWNyb3NlcnZpY2VMaXN0LmZpbHRlcigoaSkgPT4gaSAhPT0gJ25vdGlmaWNhdGlvbicpO1xuXG5leHBvcnQgY29uc3QgT3RoZXJDREtTZXJ2aWNlRW51bTogUmVjb3JkPE90aGVyQ0RLU2VydmljZSwgT3RoZXJDREtTZXJ2aWNlPiA9IHtcbiAgbmV0d29yazogJ25ldHdvcmsnLFxuICAnaW5mcmEtYXV0aCc6ICdpbmZyYS1hdXRoJyxcbiAgJ2FwaS1nYXRld2F5JzogJ2FwaS1nYXRld2F5JyxcbiAgcmVkaXM6ICdyZWRpcycsXG4gIG15c3FsOiAnbXlzcWwnLFxuICBjbGlja2hvdXNlOiAnY2xpY2tob3VzZScsXG4gIHBvcnRhbDogJ3BvcnRhbCcsXG4gIG1pZ3JhdGlvbjogJ21pZ3JhdGlvbicsXG59O1xuXG5leHBvcnQgY29uc3QgT3RoZXJDREtTZXJ2aWNlTGlzdCA9IE9iamVjdC52YWx1ZXMoT3RoZXJDREtTZXJ2aWNlRW51bSk7XG5cbmV4cG9ydCB0eXBlIFJlcG9VcmxzID0geyBba2V5IGluIEJ1aWxkQ29uZmlnWydzZXJ2aWNlTmFtZSddXT86IHN0cmluZyB9O1xuZXhwb3J0IHR5cGUgUmVwb0JyYW5jaGVzID0geyBba2V5IGluIEVudk5hbWVdOiBSZXBvQnJhbmNoIH07XG4iXX0=
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as events from 'aws-cdk-lib/aws-events';
|
|
2
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
3
|
+
import * as logs from 'aws-cdk-lib/aws-logs';
|
|
4
|
+
import { Construct } from 'constructs';
|
|
5
|
+
export interface LegacyS3BackupsBusProps {
|
|
6
|
+
readonly busName: string;
|
|
7
|
+
readonly allowedAccountIds: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface MigrationTrigger {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly prefix: string;
|
|
12
|
+
readonly options: Record<string, unknown>;
|
|
13
|
+
readonly once?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare class LegacyS3BackupsBus extends Construct {
|
|
16
|
+
readonly bus: events.EventBus;
|
|
17
|
+
readonly ruleLogGroup: logs.LogGroup;
|
|
18
|
+
readonly vendedLogGroup: logs.LogGroup;
|
|
19
|
+
private readonly busName;
|
|
20
|
+
constructor(scope: Construct, id: string, props: LegacyS3BackupsBusProps);
|
|
21
|
+
addMigrationRunner(target: lambda.IFunction): void;
|
|
22
|
+
private configureVendedLogDelivery;
|
|
23
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LegacyS3BackupsBus = void 0;
|
|
4
|
+
const cdk = require("aws-cdk-lib");
|
|
5
|
+
const events = require("aws-cdk-lib/aws-events");
|
|
6
|
+
const eventsTargets = require("aws-cdk-lib/aws-events-targets");
|
|
7
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
8
|
+
const logs = require("aws-cdk-lib/aws-logs");
|
|
9
|
+
const constructs_1 = require("constructs");
|
|
10
|
+
class LegacyS3BackupsBus extends constructs_1.Construct {
|
|
11
|
+
constructor(scope, id, props) {
|
|
12
|
+
super(scope, id);
|
|
13
|
+
this.busName = props.busName;
|
|
14
|
+
this.ruleLogGroup = new logs.LogGroup(this, 'RuleLogGroup', {
|
|
15
|
+
logGroupName: props.busName,
|
|
16
|
+
retention: logs.RetentionDays.THREE_MONTHS,
|
|
17
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
18
|
+
});
|
|
19
|
+
this.vendedLogGroup = new logs.LogGroup(this, 'VendedLogGroup', {
|
|
20
|
+
logGroupName: `/aws/vendedlogs/events/event-bus/${props.busName}`,
|
|
21
|
+
retention: logs.RetentionDays.THREE_MONTHS,
|
|
22
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
23
|
+
});
|
|
24
|
+
this.bus = new events.EventBus(this, 'EventBus', {
|
|
25
|
+
eventBusName: props.busName,
|
|
26
|
+
logConfig: {
|
|
27
|
+
level: events.Level.TRACE,
|
|
28
|
+
includeDetail: events.IncludeDetail.FULL,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
this.bus.addToResourcePolicy(new iam.PolicyStatement({
|
|
32
|
+
sid: 'AllowMainAccountPutEvents',
|
|
33
|
+
effect: iam.Effect.ALLOW,
|
|
34
|
+
principals: props.allowedAccountIds.map((accountId) => new iam.AccountPrincipal(accountId)),
|
|
35
|
+
actions: ['events:PutEvents'],
|
|
36
|
+
resources: [this.bus.eventBusArn],
|
|
37
|
+
}));
|
|
38
|
+
new events.Rule(this, 'LogAllEventsRule', {
|
|
39
|
+
ruleName: `${props.busName}-log-all-events`,
|
|
40
|
+
description: `Logs every event published to the ${props.busName} event bus to the ${props.busName} CloudWatch log group`,
|
|
41
|
+
eventBus: this.bus,
|
|
42
|
+
eventPattern: { source: events.Match.exists() },
|
|
43
|
+
targets: [new eventsTargets.CloudWatchLogGroup(this.ruleLogGroup)],
|
|
44
|
+
});
|
|
45
|
+
this.configureVendedLogDelivery(props.busName);
|
|
46
|
+
}
|
|
47
|
+
// Catch-all: the bus policy already restricts senders to the allowed
|
|
48
|
+
// accounts, and the migration runner applies the MIGRATION_TRIGGERS policy
|
|
49
|
+
// (bucket, archive suffix, size, prefix, once) to every forwarded event.
|
|
50
|
+
addMigrationRunner(target) {
|
|
51
|
+
new events.Rule(this, 'MigrationRunnerRule', {
|
|
52
|
+
ruleName: `${this.busName}-migration-runner`,
|
|
53
|
+
description: 'Starts the migration orchestrator from source-archive events forwarded to the bus',
|
|
54
|
+
eventBus: this.bus,
|
|
55
|
+
eventPattern: { source: events.Match.exists() },
|
|
56
|
+
targets: [new eventsTargets.LambdaFunction(target)],
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
configureVendedLogDelivery(busName) {
|
|
60
|
+
const stack = cdk.Stack.of(this);
|
|
61
|
+
const { account, region, partition } = stack;
|
|
62
|
+
const deliveryPolicy = new logs.CfnResourcePolicy(this, 'LogDeliveryResourcePolicy', {
|
|
63
|
+
policyName: `${busName}-log-delivery`,
|
|
64
|
+
policyDocument: stack.toJsonString({
|
|
65
|
+
Version: '2012-10-17',
|
|
66
|
+
Statement: [
|
|
67
|
+
{
|
|
68
|
+
Sid: 'AWSLogDeliveryWrite',
|
|
69
|
+
Effect: 'Allow',
|
|
70
|
+
Principal: { Service: 'delivery.logs.amazonaws.com' },
|
|
71
|
+
Action: ['logs:CreateLogStream', 'logs:PutLogEvents'],
|
|
72
|
+
Resource: `${this.vendedLogGroup.logGroupArn}:log-stream:*`,
|
|
73
|
+
Condition: {
|
|
74
|
+
StringEquals: { 'aws:SourceAccount': account },
|
|
75
|
+
ArnLike: { 'aws:SourceArn': `arn:${partition}:logs:${region}:${account}:delivery-source:*` },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
}),
|
|
80
|
+
});
|
|
81
|
+
const destination = new logs.CfnDeliveryDestination(this, 'LogDeliveryDestination', {
|
|
82
|
+
name: `${busName}-logs`,
|
|
83
|
+
destinationResourceArn: this.vendedLogGroup.logGroupArn,
|
|
84
|
+
});
|
|
85
|
+
const logTypes = [
|
|
86
|
+
{ logType: 'INFO_LOGS', id: 'Info', suffix: 'info' },
|
|
87
|
+
{ logType: 'ERROR_LOGS', id: 'Error', suffix: 'error' },
|
|
88
|
+
{ logType: 'TRACE_LOGS', id: 'Trace', suffix: 'trace' },
|
|
89
|
+
];
|
|
90
|
+
let previousDelivery;
|
|
91
|
+
for (const { logType, id, suffix } of logTypes) {
|
|
92
|
+
const source = new logs.CfnDeliverySource(this, `DeliverySource${id}`, {
|
|
93
|
+
name: `${busName}-${suffix}`,
|
|
94
|
+
logType,
|
|
95
|
+
resourceArn: this.bus.eventBusArn,
|
|
96
|
+
});
|
|
97
|
+
const delivery = new logs.CfnDelivery(this, `Delivery${id}`, {
|
|
98
|
+
deliverySourceName: source.name,
|
|
99
|
+
deliveryDestinationArn: destination.attrArn,
|
|
100
|
+
});
|
|
101
|
+
delivery.addDependency(deliveryPolicy);
|
|
102
|
+
delivery.addDependency(source);
|
|
103
|
+
if (previousDelivery) {
|
|
104
|
+
delivery.addDependency(previousDelivery);
|
|
105
|
+
}
|
|
106
|
+
previousDelivery = delivery;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.LegacyS3BackupsBus = LegacyS3BackupsBus;
|
|
111
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVnYWN5LXMzLWJhY2t1cHMtYnVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vY29uc3RydWN0cy9sZWdhY3ktczMtYmFja3Vwcy1idXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQW1DO0FBQ25DLGlEQUFpRDtBQUNqRCxnRUFBZ0U7QUFDaEUsMkNBQTJDO0FBRTNDLDZDQUE2QztBQUM3QywyQ0FBdUM7QUFpQnZDLE1BQWEsa0JBQW1CLFNBQVEsc0JBQVM7SUFPL0MsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE4QjtRQUN0RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUU3QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFO1lBQzFELFlBQVksRUFBRSxLQUFLLENBQUMsT0FBTztZQUMzQixTQUFTLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZO1lBQzFDLGFBQWEsRUFBRSxHQUFHLENBQUMsYUFBYSxDQUFDLE9BQU87U0FDekMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFO1lBQzlELFlBQVksRUFBRSxvQ0FBb0MsS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUNqRSxTQUFTLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZO1lBQzFDLGFBQWEsRUFBRSxHQUFHLENBQUMsYUFBYSxDQUFDLE9BQU87U0FDekMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRTtZQUMvQyxZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU87WUFDM0IsU0FB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QWtCLEVBQUUsTUFBTSxDQUFDLElBQUk7Z0JBQy9CLHNCQUFzQixFQUFFLFdBQVcsQ0FBQyxPQUFPO2FBQzVDLENBQUMsQ0FBQztZQUVILFFBQVEsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDdkMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMvQixJQUFJLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3JCLFFBQVEsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUMzQyxDQUFDO1lBQ0QsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDO1FBQzlCLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUEzSEQsZ0RBMkhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZXZlbnRzJztcbmltcG9ydCAqIGFzIGV2ZW50c1RhcmdldHMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWV2ZW50cy10YXJnZXRzJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGVnYWN5UzNCYWNrdXBzQnVzUHJvcHMge1xuICByZWFkb25seSBidXNOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGFsbG93ZWRBY2NvdW50SWRzOiBzdHJpbmdbXTtcbn1cblxuLy8gT25lIG1pZ3JhdGlvbiB0cmlnZ2VyOiBhIHNvdXJjZS1hcmNoaXZlIHByZWZpeCBwbHVzIHRoZSBvcmNoZXN0cmF0b3IgaW5wdXRcbi8vIG9wdGlvbnMgaXQgbWFwcyB0by4gVGhlIG1pZ3JhdGlvbiBydW5uZXIgYXBwbGllcyB0aGlzIGxpc3QgdG8gZXZlcnkgZXZlbnRcbi8vIHRoZSBidXMgZm9yd2FyZHMuXG5leHBvcnQgaW50ZXJmYWNlIE1pZ3JhdGlvblRyaWdnZXIge1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHByZWZpeDogc3RyaW5nO1xuICByZWFkb25seSBvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgcmVhZG9ubHkgb25jZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBMZWdhY3lTM0JhY2t1cHNCdXMgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwdWJsaWMgcmVhZG9ubHkgYnVzOiBldmVudHMuRXZlbnRCdXM7XG4gIHB1YmxpYyByZWFkb25seSBydWxlTG9nR3JvdXA6IGxvZ3MuTG9nR3JvdXA7XG4gIHB1YmxpYyByZWFkb25seSB2ZW5kZWRMb2dHcm91cDogbG9ncy5Mb2dHcm91cDtcblxuICBwcml2YXRlIHJlYWRvbmx5IGJ1c05hbWU6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTGVnYWN5UzNCYWNrdXBzQnVzUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy5idXNOYW1lID0gcHJvcHMuYnVzTmFtZTtcblxuICAgIHRoaXMucnVsZUxvZ0dyb3VwID0gbmV3IGxvZ3MuTG9nR3JvdXAodGhpcywgJ1J1bGVMb2dHcm91cCcsIHtcbiAgICAgIGxvZ0dyb3VwTmFtZTogcHJvcHMuYnVzTmFtZSxcbiAgICAgIHJldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLlRIUkVFX01PTlRIUyxcbiAgICAgIHJlbW92YWxQb2xpY3k6IGNkay5SZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgfSk7XG5cbiAgICB0aGlzLnZlbmRlZExvZ0dyb3VwID0gbmV3IGxvZ3MuTG9nR3JvdXAodGhpcywgJ1ZlbmRlZExvZ0dyb3VwJywge1xuICAgICAgbG9nR3JvdXBOYW1lOiBgL2F3cy92ZW5kZWRsb2dzL2V2ZW50cy9ldmVudC1idXMvJHtwcm9wcy5idXNOYW1lfWAsXG4gICAgICByZXRlbnRpb246IGxvZ3MuUmV0ZW50aW9uRGF5cy5USFJFRV9NT05USFMsXG4gICAgICByZW1vdmFsUG9saWN5OiBjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgIH0pO1xuXG4gICAgdGhpcy5idXMgPSBuZXcgZXZlbnRzLkV2ZW50QnVzKHRoaXMsICdFdmVudEJ1cycsIHtcbiAgICAgIGV2ZW50QnVzTmFtZTogcHJvcHMuYnVzTmFtZSxcbiAgICAgIGxvZ0NvbmZpZzoge1xuICAgICAgICBsZXZlbDogZXZlbnRzLkxldmVsLlRSQUNFLFxuICAgICAgICBpbmNsdWRlRGV0YWlsOiBldmVudHMuSW5jbHVkZURldGFpbC5GVUxMLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuYnVzLmFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIHNpZDogJ0FsbG93TWFpbkFjY291bnRQdXRFdmVudHMnLFxuICAgICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICAgIHByaW5jaXBhbHM6IHByb3BzLmFsbG93ZWRBY2NvdW50SWRzLm1hcCgoYWNjb3VudElkKSA9PiBuZXcgaWFtLkFjY291bnRQcmluY2lwYWwoYWNjb3VudElkKSksXG4gICAgICAgIGFjdGlvbnM6IFsnZXZlbnRzOlB1dEV2ZW50cyddLFxuICAgICAgICByZXNvdXJjZXM6IFt0aGlzLmJ1cy5ldmVudEJ1c0Fybl0sXG4gICAgICB9KVxuICAgICk7XG5cbiAgICBuZXcgZXZlbnRzLlJ1bGUodGhpcywgJ0xvZ0FsbEV2ZW50c1J1bGUnLCB7XG4gICAgICBydWxlTmFtZTogYCR7cHJvcHMuYnVzTmFtZX0tbG9nLWFsbC1ldmVudHNgLFxuICAgICAgZGVzY3JpcHRpb246IGBMb2dzIGV2ZXJ5IGV2ZW50IHB1Ymxpc2hlZCB0byB0aGUgJHtwcm9wcy5idXNOYW1lfSBldmVudCBidXMgdG8gdGhlICR7cHJvcHMuYnVzTmFtZX0gQ2xvdWRXYXRjaCBsb2cgZ3JvdXBgLFxuICAgICAgZXZlbnRCdXM6IHRoaXMuYnVzLFxuICAgICAgZXZlbnRQYXR0ZXJuOiB7IHNvdXJjZTogZXZlbnRzLk1hdGNoLmV4aXN0cygpIH0sXG4gICAgICB0YXJnZXRzOiBbbmV3IGV2ZW50c1RhcmdldHMuQ2xvdWRXYXRjaExvZ0dyb3VwKHRoaXMucnVsZUxvZ0dyb3VwKV0sXG4gICAgfSk7XG5cbiAgICB0aGlzLmNvbmZpZ3VyZVZlbmRlZExvZ0RlbGl2ZXJ5KHByb3BzLmJ1c05hbWUpO1xuICB9XG5cbiAgLy8gQ2F0Y2gtYWxsOiB0aGUgYnVzIHBvbGljeSBhbHJlYWR5IHJlc3RyaWN0cyBzZW5kZXJzIHRvIHRoZSBhbGxvd2VkXG4gIC8vIGFjY291bnRzLCBhbmQgdGhlIG1pZ3JhdGlvbiBydW5uZXIgYXBwbGllcyB0aGUgTUlHUkFUSU9OX1RSSUdHRVJTIHBvbGljeVxuICAvLyAoYnVja2V0LCBhcmNoaXZlIHN1ZmZpeCwgc2l6ZSwgcHJlZml4LCBvbmNlKSB0byBldmVyeSBmb3J3YXJkZWQgZXZlbnQuXG4gIHB1YmxpYyBhZGRNaWdyYXRpb25SdW5uZXIodGFyZ2V0OiBsYW1iZGEuSUZ1bmN0aW9uKTogdm9pZCB7XG4gICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsICdNaWdyYXRpb25SdW5uZXJSdWxlJywge1xuICAgICAgcnVsZU5hbWU6IGAke3RoaXMuYnVzTmFtZX0tbWlncmF0aW9uLXJ1bm5lcmAsXG4gICAgICBkZXNjcmlwdGlvbjogJ1N0YXJ0cyB0aGUgbWlncmF0aW9uIG9yY2hlc3RyYXRvciBmcm9tIHNvdXJjZS1hcmNoaXZlIGV2ZW50cyBmb3J3YXJkZWQgdG8gdGhlIGJ1cycsXG4gICAgICBldmVudEJ1czogdGhpcy5idXMsXG4gICAgICBldmVudFBhdHRlcm46IHsgc291cmNlOiBldmVudHMuTWF0Y2guZXhpc3RzKCkgfSxcbiAgICAgIHRhcmdldHM6IFtuZXcgZXZlbnRzVGFyZ2V0cy5MYW1iZGFGdW5jdGlvbih0YXJnZXQpXSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY29uZmlndXJlVmVuZGVkTG9nRGVsaXZlcnkoYnVzTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhY2sgPSBjZGsuU3RhY2sub2YodGhpcyk7XG4gICAgY29uc3QgeyBhY2NvdW50LCByZWdpb24sIHBhcnRpdGlvbiB9ID0gc3RhY2s7XG5cbiAgICBjb25zdCBkZWxpdmVyeVBvbGljeSA9IG5ldyBsb2dzLkNmblJlc291cmNlUG9saWN5KHRoaXMsICdMb2dEZWxpdmVyeVJlc291cmNlUG9saWN5Jywge1xuICAgICAgcG9saWN5TmFtZTogYCR7YnVzTmFtZX0tbG9nLWRlbGl2ZXJ5YCxcbiAgICAgIHBvbGljeURvY3VtZW50OiBzdGFjay50b0pzb25TdHJpbmcoe1xuICAgICAgICBWZXJzaW9uOiAnMjAxMi0xMC0xNycsXG4gICAgICAgIFN0YXRlbWVudDogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFNpZDogJ0FXU0xvZ0RlbGl2ZXJ5V3JpdGUnLFxuICAgICAgICAgICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgICAgICAgICAgUHJpbmNpcGFsOiB7IFNlcnZpY2U6ICdkZWxpdmVyeS5sb2dzLmFtYXpvbmF3cy5jb20nIH0sXG4gICAgICAgICAgICBBY3Rpb246IFsnbG9nczpDcmVhdGVMb2dTdHJlYW0nLCAnbG9nczpQdXRMb2dFdmVudHMnXSxcbiAgICAgICAgICAgIFJlc291cmNlOiBgJHt0aGlzLnZlbmRlZExvZ0dyb3VwLmxvZ0dyb3VwQXJufTpsb2ctc3RyZWFtOipgLFxuICAgICAgICAgICAgQ29uZGl0aW9uOiB7XG4gICAgICAgICAgICAgIFN0cmluZ0VxdWFsczogeyAnYXdzOlNvdXJjZUFjY291bnQnOiBhY2NvdW50IH0sXG4gICAgICAgICAgICAgIEFybkxpa2U6IHsgJ2F3czpTb3VyY2VBcm4nOiBgYXJuOiR7cGFydGl0aW9ufTpsb2dzOiR7cmVnaW9ufToke2FjY291bnR9OmRlbGl2ZXJ5LXNvdXJjZToqYCB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBjb25zdCBkZXN0aW5hdGlvbiA9IG5ldyBsb2dzLkNmbkRlbGl2ZXJ5RGVzdGluYXRpb24odGhpcywgJ0xvZ0RlbGl2ZXJ5RGVzdGluYXRpb24nLCB7XG4gICAgICBuYW1lOiBgJHtidXNOYW1lfS1sb2dzYCxcbiAgICAgIGRlc3RpbmF0aW9uUmVzb3VyY2VBcm46IHRoaXMudmVuZGVkTG9nR3JvdXAubG9nR3JvdXBBcm4sXG4gICAgfSk7XG5cbiAgICBjb25zdCBsb2dUeXBlcyA9IFtcbiAgICAgIHsgbG9nVHlwZTogJ0lORk9fTE9HUycsIGlkOiAnSW5mbycsIHN1ZmZpeDogJ2luZm8nIH0sXG4gICAgICB7IGxvZ1R5cGU6ICdFUlJPUl9MT0dTJywgaWQ6ICdFcnJvcicsIHN1ZmZpeDogJ2Vycm9yJyB9LFxuICAgICAgeyBsb2dUeXBlOiAnVFJBQ0VfTE9HUycsIGlkOiAnVHJhY2UnLCBzdWZmaXg6ICd0cmFjZScgfSxcbiAgICBdO1xuXG4gICAgbGV0IHByZXZpb3VzRGVsaXZlcnk6IGxvZ3MuQ2ZuRGVsaXZlcnkgfCB1bmRlZmluZWQ7XG5cbiAgICBmb3IgKGNvbnN0IHsgbG9nVHlwZSwgaWQsIHN1ZmZpeCB9IG9mIGxvZ1R5cGVzKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBuZXcgbG9ncy5DZm5EZWxpdmVyeVNvdXJjZSh0aGlzLCBgRGVsaXZlcnlTb3VyY2Uke2lkfWAsIHtcbiAgICAgICAgbmFtZTogYCR7YnVzTmFtZX0tJHtzdWZmaXh9YCxcbiAgICAgICAgbG9nVHlwZSxcbiAgICAgICAgcmVzb3VyY2VBcm46IHRoaXMuYnVzLmV2ZW50QnVzQXJuLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGRlbGl2ZXJ5ID0gbmV3IGxvZ3MuQ2ZuRGVsaXZlcnkodGhpcywgYERlbGl2ZXJ5JHtpZH1gLCB7XG4gICAgICAgIGRlbGl2ZXJ5U291cmNlTmFtZTogc291cmNlLm5hbWUsXG4gICAgICAgIGRlbGl2ZXJ5RGVzdGluYXRpb25Bcm46IGRlc3RpbmF0aW9uLmF0dHJBcm4sXG4gICAgICB9KTtcblxuICAgICAgZGVsaXZlcnkuYWRkRGVwZW5kZW5jeShkZWxpdmVyeVBvbGljeSk7XG4gICAgICBkZWxpdmVyeS5hZGREZXBlbmRlbmN5KHNvdXJjZSk7XG4gICAgICBpZiAocHJldmlvdXNEZWxpdmVyeSkge1xuICAgICAgICBkZWxpdmVyeS5hZGREZXBlbmRlbmN5KHByZXZpb3VzRGVsaXZlcnkpO1xuICAgICAgfVxuICAgICAgcHJldmlvdXNEZWxpdmVyeSA9IGRlbGl2ZXJ5O1xuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
2
|
+
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
3
|
+
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
4
|
+
import { Construct } from 'constructs';
|
|
5
|
+
export interface MigrationScriptsRunnerProps {
|
|
6
|
+
vpc: ec2.IVpc;
|
|
7
|
+
artifactsBucket: s3.IBucket;
|
|
8
|
+
migrationRepoPath?: string;
|
|
9
|
+
backupPrefix?: string;
|
|
10
|
+
cpu?: number;
|
|
11
|
+
memoryLimitMiB?: number;
|
|
12
|
+
ephemeralStorageGiB?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare class MigrationScriptsRunner extends Construct {
|
|
15
|
+
readonly cluster: ecs.Cluster;
|
|
16
|
+
readonly securityGroup: ec2.SecurityGroup;
|
|
17
|
+
readonly taskDefinition: ecs.FargateTaskDefinition;
|
|
18
|
+
readonly container: ecs.ContainerDefinition;
|
|
19
|
+
constructor(scope: Construct, id: string, props: MigrationScriptsRunnerProps);
|
|
20
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MigrationScriptsRunner = void 0;
|
|
4
|
+
const cdk = require("aws-cdk-lib");
|
|
5
|
+
const ec2 = require("aws-cdk-lib/aws-ec2");
|
|
6
|
+
const ecrAssets = require("aws-cdk-lib/aws-ecr-assets");
|
|
7
|
+
const ecs = require("aws-cdk-lib/aws-ecs");
|
|
8
|
+
const logs = require("aws-cdk-lib/aws-logs");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
const constructs_1 = require("constructs");
|
|
11
|
+
const migration_1 = require("../util/migration");
|
|
12
|
+
// One-shot Fargate tasks that run the migration scripts (restore, migrations,
|
|
13
|
+
// precompute-diseases, precompute-claim-batches, reset) unchanged. The state
|
|
14
|
+
// machine overrides the container command per step.
|
|
15
|
+
class MigrationScriptsRunner extends constructs_1.Construct {
|
|
16
|
+
constructor(scope, id, props) {
|
|
17
|
+
super(scope, id);
|
|
18
|
+
this.cluster = new ecs.Cluster(this, 'Cluster', {
|
|
19
|
+
vpc: props.vpc,
|
|
20
|
+
clusterName: 'migration-scripts',
|
|
21
|
+
});
|
|
22
|
+
this.securityGroup = new ec2.SecurityGroup(this, 'SecurityGroup', {
|
|
23
|
+
vpc: props.vpc,
|
|
24
|
+
securityGroupName: 'Migration-Scripts-SG',
|
|
25
|
+
description: 'Migration scripts ECS tasks',
|
|
26
|
+
allowAllOutbound: true,
|
|
27
|
+
});
|
|
28
|
+
this.taskDefinition = new ecs.FargateTaskDefinition(this, 'TaskDefinition', {
|
|
29
|
+
family: 'migration-scripts',
|
|
30
|
+
cpu: props.cpu ?? 4096,
|
|
31
|
+
memoryLimitMiB: props.memoryLimitMiB ?? 8192,
|
|
32
|
+
ephemeralStorageGiB: props.ephemeralStorageGiB ?? 21,
|
|
33
|
+
runtimePlatform: {
|
|
34
|
+
cpuArchitecture: ecs.CpuArchitecture.X86_64,
|
|
35
|
+
operatingSystemFamily: ecs.OperatingSystemFamily.LINUX,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
const { environment, secrets } = (0, migration_1.getEcsEnvs)(cdk.Stack.of(this));
|
|
39
|
+
this.container = this.taskDefinition.addContainer('scripts', {
|
|
40
|
+
containerName: 'scripts',
|
|
41
|
+
// The task definition runs X86_64 Fargate; pin the image platform so a
|
|
42
|
+
// build from an arm64 host (e.g. a Mac) does not produce a mismatched
|
|
43
|
+
// image (exec format error on the entrypoint).
|
|
44
|
+
image: ecs.ContainerImage.fromAsset(props.migrationRepoPath ?? path.resolve('../../migration'), {
|
|
45
|
+
file: 'Dockerfile',
|
|
46
|
+
platform: ecrAssets.Platform.LINUX_AMD64,
|
|
47
|
+
}),
|
|
48
|
+
environment,
|
|
49
|
+
secrets,
|
|
50
|
+
logging: ecs.LogDrivers.awsLogs({
|
|
51
|
+
streamPrefix: 'migration-scripts',
|
|
52
|
+
logRetention: logs.RetentionDays.ONE_MONTH,
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
props.artifactsBucket.grantRead(this.taskDefinition.taskRole, `${props.backupPrefix ?? 'backups'}/*`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.MigrationScriptsRunner = MigrationScriptsRunner;
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0aW9uLXNjcmlwdHMtcnVubmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vY29uc3RydWN0cy9taWdyYXRpb24tc2NyaXB0cy1ydW5uZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQyx3REFBd0Q7QUFDeEQsMkNBQTJDO0FBQzNDLDZDQUE2QztBQUU3Qyw2QkFBNkI7QUFDN0IsMkNBQXVDO0FBQ3ZDLGlEQUErQztBQVkvQyw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLG9EQUFvRDtBQUNwRCxNQUFhLHNCQUF1QixTQUFRLHNCQUFTO0lBTW5ELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBa0M7UUFDMUUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO1lBQzlDLEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRztZQUNkLFdBQVcsRUFBRSxtQkFBbUI7U0FDakMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRTtZQUNoRSxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7WUFDZCxpQkFBaUIsRUFBRSxzQkFBc0I7WUFDekMsV0FBVyxFQUFFLDZCQUE2QjtZQUMxQyxnQkFBZ0IsRUFBRSxJQUFJO1NBQ3ZCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxHQUFHLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFO1lBQzFFLE1BQU0sRUFBRSxtQkFBbUI7WUFDM0IsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLElBQUksSUFBSTtZQUN0QixjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWMsSUFBSSxJQUFJO1lBQzVDLG1CQUFtQixFQUFFLEtBQUssQ0FBQyxtQkFBbUIsSUFBSSxFQUFFO1lBQ3BELGVBQWUsRUFBRTtnQkFDZixlQUFlLEVBQUUsR0FBRyxDQUFDLGVBQWUsQ0FBQyxNQUFNO2dCQUMzQyxxQkFBcUIsRUFBRSxHQUFHLENBQUMscUJBQXFCLENBQUMsS0FBSzthQUN2RDtTQUNGLENBQUMsQ0FBQztRQUVILE1BQU0sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBQSxzQkFBVSxFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFaEUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUU7WUFDM0QsYUFBYSxFQUFFLFNBQVM7WUFDeEIsdUVBQXVFO1lBQ3ZFLHNFQUFzRTtZQUN0RSwrQ0FBK0M7WUFDL0MsS0FBSyxFQUFFLEdBQUcsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEVBQUU7Z0JBQzlGLElBQUksRUFBRSxZQUFZO2dCQUNsQixRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVEsQ0FBQyxXQUFXO2FBQ3pDLENBQUM7WUFDRixXQUFXO1lBQ1gsT0FBTztZQUNQLE9BQU8sRUFBRSxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQztnQkFDOUIsWUFBWSxFQUFFLG1CQUFtQjtnQkFDakMsWUFBWSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUzthQUMzQyxDQUFDO1NBQ0gsQ0FBQyxDQUFDO1FBRUgsS0FBSyxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxLQUFLLENBQUMsWUFBWSxJQUFJLFNBQVMsSUFBSSxDQUFDLENBQUM7SUFDeEcsQ0FBQztDQUNGO0FBckRELHdEQXFEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBlYzIgZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgKiBhcyBlY3JBc3NldHMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjci1hc3NldHMnO1xuaW1wb3J0ICogYXMgZWNzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3MnO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBzMyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgZ2V0RWNzRW52cyB9IGZyb20gJy4uL3V0aWwvbWlncmF0aW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBNaWdyYXRpb25TY3JpcHRzUnVubmVyUHJvcHMge1xuICB2cGM6IGVjMi5JVnBjO1xuICBhcnRpZmFjdHNCdWNrZXQ6IHMzLklCdWNrZXQ7XG4gIG1pZ3JhdGlvblJlcG9QYXRoPzogc3RyaW5nO1xuICBiYWNrdXBQcmVmaXg/OiBzdHJpbmc7XG4gIGNwdT86IG51bWJlcjtcbiAgbWVtb3J5TGltaXRNaUI/OiBudW1iZXI7XG4gIGVwaGVtZXJhbFN0b3JhZ2VHaUI/OiBudW1iZXI7XG59XG5cbi8vIE9uZS1zaG90IEZhcmdhdGUgdGFza3MgdGhhdCBydW4gdGhlIG1pZ3JhdGlvbiBzY3JpcHRzIChyZXN0b3JlLCBtaWdyYXRpb25zLFxuLy8gcHJlY29tcHV0ZS1kaXNlYXNlcywgcHJlY29tcHV0ZS1jbGFpbS1iYXRjaGVzLCByZXNldCkgdW5jaGFuZ2VkLiBUaGUgc3RhdGVcbi8vIG1hY2hpbmUgb3ZlcnJpZGVzIHRoZSBjb250YWluZXIgY29tbWFuZCBwZXIgc3RlcC5cbmV4cG9ydCBjbGFzcyBNaWdyYXRpb25TY3JpcHRzUnVubmVyIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcHVibGljIHJlYWRvbmx5IGNsdXN0ZXI6IGVjcy5DbHVzdGVyO1xuICBwdWJsaWMgcmVhZG9ubHkgc2VjdXJpdHlHcm91cDogZWMyLlNlY3VyaXR5R3JvdXA7XG4gIHB1YmxpYyByZWFkb25seSB0YXNrRGVmaW5pdGlvbjogZWNzLkZhcmdhdGVUYXNrRGVmaW5pdGlvbjtcbiAgcHVibGljIHJlYWRvbmx5IGNvbnRhaW5lcjogZWNzLkNvbnRhaW5lckRlZmluaXRpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE1pZ3JhdGlvblNjcmlwdHNSdW5uZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLmNsdXN0ZXIgPSBuZXcgZWNzLkNsdXN0ZXIodGhpcywgJ0NsdXN0ZXInLCB7XG4gICAgICB2cGM6IHByb3BzLnZwYyxcbiAgICAgIGNsdXN0ZXJOYW1lOiAnbWlncmF0aW9uLXNjcmlwdHMnLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zZWN1cml0eUdyb3VwID0gbmV3IGVjMi5TZWN1cml0eUdyb3VwKHRoaXMsICdTZWN1cml0eUdyb3VwJywge1xuICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICBzZWN1cml0eUdyb3VwTmFtZTogJ01pZ3JhdGlvbi1TY3JpcHRzLVNHJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnTWlncmF0aW9uIHNjcmlwdHMgRUNTIHRhc2tzJyxcbiAgICAgIGFsbG93QWxsT3V0Ym91bmQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLnRhc2tEZWZpbml0aW9uID0gbmV3IGVjcy5GYXJnYXRlVGFza0RlZmluaXRpb24odGhpcywgJ1Rhc2tEZWZpbml0aW9uJywge1xuICAgICAgZmFtaWx5OiAnbWlncmF0aW9uLXNjcmlwdHMnLFxuICAgICAgY3B1OiBwcm9wcy5jcHUgPz8gNDA5NixcbiAgICAgIG1lbW9yeUxpbWl0TWlCOiBwcm9wcy5tZW1vcnlMaW1pdE1pQiA/PyA4MTkyLFxuICAgICAgZXBoZW1lcmFsU3RvcmFnZUdpQjogcHJvcHMuZXBoZW1lcmFsU3RvcmFnZUdpQiA/PyAyMSxcbiAgICAgIHJ1bnRpbWVQbGF0Zm9ybToge1xuICAgICAgICBjcHVBcmNoaXRlY3R1cmU6IGVjcy5DcHVBcmNoaXRlY3R1cmUuWDg2XzY0LFxuICAgICAgICBvcGVyYXRpbmdTeXN0ZW1GYW1pbHk6IGVjcy5PcGVyYXRpbmdTeXN0ZW1GYW1pbHkuTElOVVgsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgeyBlbnZpcm9ubWVudCwgc2VjcmV0cyB9ID0gZ2V0RWNzRW52cyhjZGsuU3RhY2sub2YodGhpcykpO1xuXG4gICAgdGhpcy5jb250YWluZXIgPSB0aGlzLnRhc2tEZWZpbml0aW9uLmFkZENvbnRhaW5lcignc2NyaXB0cycsIHtcbiAgICAgIGNvbnRhaW5lck5hbWU6ICdzY3JpcHRzJyxcbiAgICAgIC8vIFRoZSB0YXNrIGRlZmluaXRpb24gcnVucyBYODZfNjQgRmFyZ2F0ZTsgcGluIHRoZSBpbWFnZSBwbGF0Zm9ybSBzbyBhXG4gICAgICAvLyBidWlsZCBmcm9tIGFuIGFybTY0IGhvc3QgKGUuZy4gYSBNYWMpIGRvZXMgbm90IHByb2R1Y2UgYSBtaXNtYXRjaGVkXG4gICAgICAvLyBpbWFnZSAoZXhlYyBmb3JtYXQgZXJyb3Igb24gdGhlIGVudHJ5cG9pbnQpLlxuICAgICAgaW1hZ2U6IGVjcy5Db250YWluZXJJbWFnZS5mcm9tQXNzZXQocHJvcHMubWlncmF0aW9uUmVwb1BhdGggPz8gcGF0aC5yZXNvbHZlKCcuLi8uLi9taWdyYXRpb24nKSwge1xuICAgICAgICBmaWxlOiAnRG9ja2VyZmlsZScsXG4gICAgICAgIHBsYXRmb3JtOiBlY3JBc3NldHMuUGxhdGZvcm0uTElOVVhfQU1ENjQsXG4gICAgICB9KSxcbiAgICAgIGVudmlyb25tZW50LFxuICAgICAgc2VjcmV0cyxcbiAgICAgIGxvZ2dpbmc6IGVjcy5Mb2dEcml2ZXJzLmF3c0xvZ3Moe1xuICAgICAgICBzdHJlYW1QcmVmaXg6ICdtaWdyYXRpb24tc2NyaXB0cycsXG4gICAgICAgIGxvZ1JldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLk9ORV9NT05USCxcbiAgICAgIH0pLFxuICAgIH0pO1xuXG4gICAgcHJvcHMuYXJ0aWZhY3RzQnVja2V0LmdyYW50UmVhZCh0aGlzLnRhc2tEZWZpbml0aW9uLnRhc2tSb2xlLCBgJHtwcm9wcy5iYWNrdXBQcmVmaXggPz8gJ2JhY2t1cHMnfS8qYCk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
|
2
|
+
import * as ecs from 'aws-cdk-lib/aws-ecs';
|
|
3
|
+
import * as lambda from 'aws-cdk-lib/aws-lambda';
|
|
4
|
+
import * as s3 from 'aws-cdk-lib/aws-s3';
|
|
5
|
+
import * as sqs from 'aws-cdk-lib/aws-sqs';
|
|
6
|
+
import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
|
|
7
|
+
import { Construct } from 'constructs';
|
|
8
|
+
export interface MigrationStateMachineProps {
|
|
9
|
+
producer: lambda.IFunction;
|
|
10
|
+
verifier: lambda.IFunction;
|
|
11
|
+
clearAffected: lambda.IFunction;
|
|
12
|
+
queue: sqs.IQueue;
|
|
13
|
+
cluster: ecs.ICluster;
|
|
14
|
+
taskDefinition: ecs.TaskDefinition;
|
|
15
|
+
container: ecs.ContainerDefinition;
|
|
16
|
+
securityGroup: ec2.ISecurityGroup;
|
|
17
|
+
artifactsBucket: s3.IBucket;
|
|
18
|
+
progressParameterName: string;
|
|
19
|
+
maxInvocations?: number;
|
|
20
|
+
drainMaxChecks?: number;
|
|
21
|
+
loopWaitSeconds?: number;
|
|
22
|
+
drainWaitSeconds?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare class MigrationStateMachine extends Construct {
|
|
25
|
+
readonly stateMachine: sfn.StateMachine;
|
|
26
|
+
private readonly producer;
|
|
27
|
+
private readonly verifier;
|
|
28
|
+
private readonly clearAffected;
|
|
29
|
+
private readonly queue;
|
|
30
|
+
private readonly cluster;
|
|
31
|
+
private readonly taskDefinition;
|
|
32
|
+
private readonly container;
|
|
33
|
+
private readonly securityGroup;
|
|
34
|
+
private readonly artifactsBucket;
|
|
35
|
+
private readonly progressParameterName;
|
|
36
|
+
private readonly progressParameterArn;
|
|
37
|
+
private readonly maxInvocations;
|
|
38
|
+
private readonly drainMaxChecks;
|
|
39
|
+
private readonly loopWaitSeconds;
|
|
40
|
+
private readonly drainWaitSeconds;
|
|
41
|
+
constructor(scope: Construct, id: string, props: MigrationStateMachineProps);
|
|
42
|
+
private previousStep;
|
|
43
|
+
private precomputeEnabled;
|
|
44
|
+
private markStep;
|
|
45
|
+
private producerPass;
|
|
46
|
+
private resourceStep;
|
|
47
|
+
private ecsStep;
|
|
48
|
+
}
|