@go-to-k/cdkd 0.46.1 → 0.48.0
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/cli.js +178 -72
- package/dist/cli.js.map +2 -2
- package/dist/go-to-k-cdkd-0.48.0.tgz +0 -0
- package/dist/index.js +96 -6
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.46.1.tgz +0 -0
package/dist/cli.js
CHANGED
|
@@ -629,6 +629,10 @@ var deployOptions = [
|
|
|
629
629
|
new Option("--dry-run", "Show changes without applying").default(false),
|
|
630
630
|
new Option("--skip-assets", "Skip asset publishing").default(false),
|
|
631
631
|
new Option("--no-rollback", "Skip rollback on deployment failure"),
|
|
632
|
+
new Option(
|
|
633
|
+
"--no-capture-observed-state",
|
|
634
|
+
"Skip capturing AWS-current properties after each create/update (adds a fire-and-forget readCurrentState per resource so cdkd drift can compare against the real deploy-time AWS snapshot instead of the template). On by default. Disable when deploy speed matters more than rich drift detection \u2014 falls back to comparing against template properties (the pre-v3 behavior)."
|
|
635
|
+
),
|
|
632
636
|
noWaitOption,
|
|
633
637
|
aggressiveVpcParallelOption,
|
|
634
638
|
new Option(
|
|
@@ -1351,6 +1355,16 @@ function resolveApp(cliApp) {
|
|
|
1351
1355
|
const cdkJson = loadCdkJson();
|
|
1352
1356
|
return cdkJson?.app ?? void 0;
|
|
1353
1357
|
}
|
|
1358
|
+
function resolveCaptureObservedState(cliValue) {
|
|
1359
|
+
if (cliValue === false)
|
|
1360
|
+
return false;
|
|
1361
|
+
const cdkJson = loadCdkJson();
|
|
1362
|
+
const cdkdContext = cdkJson?.context?.["cdkd"];
|
|
1363
|
+
const v = cdkdContext?.["captureObservedState"];
|
|
1364
|
+
if (typeof v === "boolean")
|
|
1365
|
+
return v;
|
|
1366
|
+
return true;
|
|
1367
|
+
}
|
|
1354
1368
|
function resolveStateBucketWithSource(cliBucket) {
|
|
1355
1369
|
if (cliBucket)
|
|
1356
1370
|
return { bucket: cliBucket, source: "cli-flag" };
|
|
@@ -3727,8 +3741,8 @@ import {
|
|
|
3727
3741
|
} from "@aws-sdk/client-s3";
|
|
3728
3742
|
|
|
3729
3743
|
// src/types/state.ts
|
|
3730
|
-
var
|
|
3731
|
-
var
|
|
3744
|
+
var STATE_SCHEMA_VERSION_CURRENT = 3;
|
|
3745
|
+
var STATE_SCHEMA_VERSIONS_READABLE = [1, 2, 3];
|
|
3732
3746
|
|
|
3733
3747
|
// src/utils/aws-region-resolver.ts
|
|
3734
3748
|
import { GetBucketLocationCommand, S3Client as S3Client3 } from "@aws-sdk/client-s3";
|
|
@@ -4237,9 +4251,9 @@ var S3StateBackend = class {
|
|
|
4237
4251
|
);
|
|
4238
4252
|
}
|
|
4239
4253
|
const v = parsed.version;
|
|
4240
|
-
if (v !==
|
|
4254
|
+
if (v !== void 0 && !STATE_SCHEMA_VERSIONS_READABLE.includes(v)) {
|
|
4241
4255
|
throw new StateError(
|
|
4242
|
-
`Unsupported state schema version ${String(v)} for stack '${stackName}'. This cdkd binary supports versions ${
|
|
4256
|
+
`Unsupported state schema version ${String(v)} for stack '${stackName}'. This cdkd binary supports versions ${STATE_SCHEMA_VERSIONS_READABLE.join(", ")}. Upgrade cdkd to a version that supports schema ${String(v)}.`
|
|
4243
4257
|
);
|
|
4244
4258
|
}
|
|
4245
4259
|
return parsed;
|
|
@@ -9167,8 +9181,7 @@ var IAMRoleProvider = class {
|
|
|
9167
9181
|
marker = tagsResp.Marker;
|
|
9168
9182
|
}
|
|
9169
9183
|
const tags = normalizeAwsTagsToCfn(collected);
|
|
9170
|
-
|
|
9171
|
-
result["Tags"] = tags;
|
|
9184
|
+
result["Tags"] = tags;
|
|
9172
9185
|
} catch (err) {
|
|
9173
9186
|
if (!(err instanceof NoSuchEntityException))
|
|
9174
9187
|
throw err;
|
|
@@ -12191,8 +12204,7 @@ var S3BucketProvider = class {
|
|
|
12191
12204
|
try {
|
|
12192
12205
|
const resp = await this.s3Client.send(new GetBucketTaggingCommand({ Bucket: physicalId }));
|
|
12193
12206
|
const tags = normalizeAwsTagsToCfn(resp.TagSet);
|
|
12194
|
-
|
|
12195
|
-
result["Tags"] = tags;
|
|
12207
|
+
result["Tags"] = tags;
|
|
12196
12208
|
} catch (err) {
|
|
12197
12209
|
const e = err;
|
|
12198
12210
|
if (e.name !== "NoSuchTagSet") {
|
|
@@ -12878,8 +12890,7 @@ var SQSQueueProvider = class {
|
|
|
12878
12890
|
new ListQueueTagsCommand({ QueueUrl: physicalId })
|
|
12879
12891
|
);
|
|
12880
12892
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
12881
|
-
|
|
12882
|
-
result["Tags"] = tags;
|
|
12893
|
+
result["Tags"] = tags;
|
|
12883
12894
|
} catch (err) {
|
|
12884
12895
|
if (err instanceof QueueDoesNotExist)
|
|
12885
12896
|
return void 0;
|
|
@@ -13571,8 +13582,7 @@ var SNSTopicProvider = class {
|
|
|
13571
13582
|
new ListTagsForResourceCommand({ ResourceArn: physicalId })
|
|
13572
13583
|
);
|
|
13573
13584
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
13574
|
-
|
|
13575
|
-
result["Tags"] = tags;
|
|
13585
|
+
result["Tags"] = tags;
|
|
13576
13586
|
} catch (err) {
|
|
13577
13587
|
if (err instanceof NotFoundException)
|
|
13578
13588
|
return void 0;
|
|
@@ -14858,8 +14868,7 @@ var LambdaFunctionProvider = class {
|
|
|
14858
14868
|
result["VpcConfig"] = vpc;
|
|
14859
14869
|
}
|
|
14860
14870
|
const tags = normalizeAwsTagsToCfn(resp.Tags);
|
|
14861
|
-
|
|
14862
|
-
result["Tags"] = tags;
|
|
14871
|
+
result["Tags"] = tags;
|
|
14863
14872
|
return result;
|
|
14864
14873
|
} catch (err) {
|
|
14865
14874
|
if (err instanceof ResourceNotFoundException)
|
|
@@ -16431,8 +16440,7 @@ var DynamoDBTableProvider = class {
|
|
|
16431
16440
|
new ListTagsOfResourceCommand({ ResourceArn: table.TableArn })
|
|
16432
16441
|
);
|
|
16433
16442
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
16434
|
-
|
|
16435
|
-
result["Tags"] = tags;
|
|
16443
|
+
result["Tags"] = tags;
|
|
16436
16444
|
} catch (err) {
|
|
16437
16445
|
if (err instanceof ResourceNotFoundException6)
|
|
16438
16446
|
return void 0;
|
|
@@ -16797,8 +16805,7 @@ var LogsLogGroupProvider = class {
|
|
|
16797
16805
|
new ListTagsForResourceCommand2({ resourceArn: arnForTags })
|
|
16798
16806
|
);
|
|
16799
16807
|
const tags = normalizeAwsTagsToCfn(tagsResp.tags);
|
|
16800
|
-
|
|
16801
|
-
result["Tags"] = tags;
|
|
16808
|
+
result["Tags"] = tags;
|
|
16802
16809
|
} catch (err) {
|
|
16803
16810
|
if (err instanceof ResourceNotFoundException7)
|
|
16804
16811
|
return void 0;
|
|
@@ -17180,8 +17187,7 @@ var CloudWatchAlarmProvider = class {
|
|
|
17180
17187
|
new ListTagsForResourceCommand3({ ResourceARN: alarm.AlarmArn })
|
|
17181
17188
|
);
|
|
17182
17189
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
17183
|
-
|
|
17184
|
-
result["Tags"] = tags;
|
|
17190
|
+
result["Tags"] = tags;
|
|
17185
17191
|
} catch (err) {
|
|
17186
17192
|
this.logger.debug(
|
|
17187
17193
|
`CloudWatch ListTagsForResource(${alarm.AlarmArn}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -17555,8 +17561,7 @@ var SecretsManagerSecretProvider = class {
|
|
|
17555
17561
|
});
|
|
17556
17562
|
}
|
|
17557
17563
|
const tags = normalizeAwsTagsToCfn(resp.Tags);
|
|
17558
|
-
|
|
17559
|
-
result["Tags"] = tags;
|
|
17564
|
+
result["Tags"] = tags;
|
|
17560
17565
|
return result;
|
|
17561
17566
|
} catch (err) {
|
|
17562
17567
|
if (err instanceof ResourceNotFoundException8)
|
|
@@ -17918,8 +17923,7 @@ var SSMParameterProvider = class {
|
|
|
17918
17923
|
})
|
|
17919
17924
|
);
|
|
17920
17925
|
const tags = normalizeAwsTagsToCfn(tagsResp.TagList);
|
|
17921
|
-
|
|
17922
|
-
result["Tags"] = tags;
|
|
17926
|
+
result["Tags"] = tags;
|
|
17923
17927
|
} catch {
|
|
17924
17928
|
}
|
|
17925
17929
|
return result;
|
|
@@ -18331,8 +18335,7 @@ var EventBridgeRuleProvider = class {
|
|
|
18331
18335
|
new ListTagsForResourceCommand5({ ResourceARN: physicalId })
|
|
18332
18336
|
);
|
|
18333
18337
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
18334
|
-
|
|
18335
|
-
result["Tags"] = tags;
|
|
18338
|
+
result["Tags"] = tags;
|
|
18336
18339
|
} catch (err) {
|
|
18337
18340
|
if (!(err instanceof ResourceNotFoundException9)) {
|
|
18338
18341
|
throw err;
|
|
@@ -18748,8 +18751,7 @@ var EventBridgeBusProvider = class {
|
|
|
18748
18751
|
new ListTagsForResourceCommand6({ ResourceARN: resp.Arn })
|
|
18749
18752
|
);
|
|
18750
18753
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
18751
|
-
|
|
18752
|
-
result["Tags"] = tags;
|
|
18754
|
+
result["Tags"] = tags;
|
|
18753
18755
|
} catch (err) {
|
|
18754
18756
|
if (err instanceof ResourceNotFoundException10)
|
|
18755
18757
|
return void 0;
|
|
@@ -23055,8 +23057,7 @@ var ApiGatewayV2Provider = class {
|
|
|
23055
23057
|
if (resp.CorsConfiguration)
|
|
23056
23058
|
result["CorsConfiguration"] = resp.CorsConfiguration;
|
|
23057
23059
|
const tags = normalizeAwsTagsToCfn(resp.Tags);
|
|
23058
|
-
|
|
23059
|
-
result["Tags"] = tags;
|
|
23060
|
+
result["Tags"] = tags;
|
|
23060
23061
|
return result;
|
|
23061
23062
|
} catch (err) {
|
|
23062
23063
|
if (err instanceof NotFoundException4)
|
|
@@ -24582,8 +24583,7 @@ var StepFunctionsProvider = class {
|
|
|
24582
24583
|
new ListTagsForResourceCommand8({ resourceArn: physicalId })
|
|
24583
24584
|
);
|
|
24584
24585
|
const tags = normalizeAwsTagsToCfn(tagsResp.tags);
|
|
24585
|
-
|
|
24586
|
-
result["Tags"] = tags;
|
|
24586
|
+
result["Tags"] = tags;
|
|
24587
24587
|
} catch (err) {
|
|
24588
24588
|
if (!(err instanceof StateMachineDoesNotExist))
|
|
24589
24589
|
throw err;
|
|
@@ -25475,8 +25475,7 @@ var ECSProvider = class {
|
|
|
25475
25475
|
}));
|
|
25476
25476
|
}
|
|
25477
25477
|
const tags = normalizeAwsTagsToCfn(c.tags);
|
|
25478
|
-
|
|
25479
|
-
result["Tags"] = tags;
|
|
25478
|
+
result["Tags"] = tags;
|
|
25480
25479
|
return result;
|
|
25481
25480
|
}
|
|
25482
25481
|
async readCurrentStateService(physicalId) {
|
|
@@ -25546,8 +25545,7 @@ var ECSProvider = class {
|
|
|
25546
25545
|
result["ServiceRegistries"] = s.serviceRegistries;
|
|
25547
25546
|
}
|
|
25548
25547
|
const tags = normalizeAwsTagsToCfn(s.tags);
|
|
25549
|
-
|
|
25550
|
-
result["Tags"] = tags;
|
|
25548
|
+
result["Tags"] = tags;
|
|
25551
25549
|
return result;
|
|
25552
25550
|
}
|
|
25553
25551
|
async readCurrentStateTaskDefinition(physicalId) {
|
|
@@ -25598,8 +25596,7 @@ var ECSProvider = class {
|
|
|
25598
25596
|
result["ContainerDefinitions"] = td.containerDefinitions;
|
|
25599
25597
|
}
|
|
25600
25598
|
const tags = normalizeAwsTagsToCfn(resp.tags);
|
|
25601
|
-
|
|
25602
|
-
result["Tags"] = tags;
|
|
25599
|
+
result["Tags"] = tags;
|
|
25603
25600
|
return result;
|
|
25604
25601
|
}
|
|
25605
25602
|
/**
|
|
@@ -26389,8 +26386,7 @@ var ELBv2Provider = class {
|
|
|
26389
26386
|
const resp = await this.getClient().send(new DescribeTagsCommand({ ResourceArns: [arn] }));
|
|
26390
26387
|
const tagDesc = resp.TagDescriptions?.[0];
|
|
26391
26388
|
const tags = normalizeAwsTagsToCfn(tagDesc?.Tags);
|
|
26392
|
-
|
|
26393
|
-
result["Tags"] = tags;
|
|
26389
|
+
result["Tags"] = tags;
|
|
26394
26390
|
} catch (err) {
|
|
26395
26391
|
this.logger.debug(
|
|
26396
26392
|
`ELBv2 DescribeTags(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -27302,8 +27298,7 @@ var RDSProvider = class {
|
|
|
27302
27298
|
new ListTagsForResourceCommand10({ ResourceName: arn })
|
|
27303
27299
|
);
|
|
27304
27300
|
const tags = normalizeAwsTagsToCfn(tagsResp.TagList);
|
|
27305
|
-
|
|
27306
|
-
result["Tags"] = tags;
|
|
27301
|
+
result["Tags"] = tags;
|
|
27307
27302
|
} catch (err) {
|
|
27308
27303
|
this.logger.debug(
|
|
27309
27304
|
`RDS ListTagsForResource(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -28601,8 +28596,7 @@ var WAFv2WebACLProvider = class {
|
|
|
28601
28596
|
new ListTagsForResourceCommand12({ ResourceARN: physicalId })
|
|
28602
28597
|
);
|
|
28603
28598
|
const tags = normalizeAwsTagsToCfn(tagsResp.TagInfoForResource?.TagList);
|
|
28604
|
-
|
|
28605
|
-
result["Tags"] = tags;
|
|
28599
|
+
result["Tags"] = tags;
|
|
28606
28600
|
} catch (err) {
|
|
28607
28601
|
this.logger.debug(
|
|
28608
28602
|
`WAFv2 ListTagsForResource(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -29733,8 +29727,7 @@ var ElastiCacheProvider = class {
|
|
|
29733
29727
|
new ListTagsForResourceCommand14({ ResourceName: arn })
|
|
29734
29728
|
);
|
|
29735
29729
|
const tags = normalizeAwsTagsToCfn(tagsResp.TagList);
|
|
29736
|
-
|
|
29737
|
-
result["Tags"] = tags;
|
|
29730
|
+
result["Tags"] = tags;
|
|
29738
29731
|
} catch (err) {
|
|
29739
29732
|
this.logger.debug(
|
|
29740
29733
|
`ElastiCache ListTagsForResource(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -30307,8 +30300,7 @@ var ServiceDiscoveryProvider = class {
|
|
|
30307
30300
|
new ListTagsForResourceCommand15({ ResourceARN: arn })
|
|
30308
30301
|
);
|
|
30309
30302
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
30310
|
-
|
|
30311
|
-
result["Tags"] = tags;
|
|
30303
|
+
result["Tags"] = tags;
|
|
30312
30304
|
} catch (err) {
|
|
30313
30305
|
this.logger.debug(
|
|
30314
30306
|
`ServiceDiscovery ListTagsForResource(${arn}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -31032,8 +31024,7 @@ var AppSyncProvider = class {
|
|
|
31032
31024
|
result["LogConfig"] = log;
|
|
31033
31025
|
}
|
|
31034
31026
|
const tags = normalizeAwsTagsToCfn(api.tags);
|
|
31035
|
-
|
|
31036
|
-
result["Tags"] = tags;
|
|
31027
|
+
result["Tags"] = tags;
|
|
31037
31028
|
return result;
|
|
31038
31029
|
}
|
|
31039
31030
|
async readDataSource(physicalId) {
|
|
@@ -32332,8 +32323,7 @@ var KMSProvider = class {
|
|
|
32332
32323
|
new ListResourceTagsCommand({ KeyId: md.KeyId })
|
|
32333
32324
|
);
|
|
32334
32325
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
32335
|
-
|
|
32336
|
-
result["Tags"] = tags;
|
|
32326
|
+
result["Tags"] = tags;
|
|
32337
32327
|
} catch (err) {
|
|
32338
32328
|
if (err instanceof NotFoundException5)
|
|
32339
32329
|
return void 0;
|
|
@@ -32777,8 +32767,7 @@ var KinesisStreamProvider = class {
|
|
|
32777
32767
|
new ListTagsForStreamCommand({ StreamName: physicalId })
|
|
32778
32768
|
);
|
|
32779
32769
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
32780
|
-
|
|
32781
|
-
result["Tags"] = tags;
|
|
32770
|
+
result["Tags"] = tags;
|
|
32782
32771
|
} catch (err) {
|
|
32783
32772
|
if (err instanceof ResourceNotFoundException13)
|
|
32784
32773
|
return void 0;
|
|
@@ -33978,8 +33967,7 @@ var FirehoseProvider = class {
|
|
|
33978
33967
|
new ListTagsForDeliveryStreamCommand({ DeliveryStreamName: physicalId })
|
|
33979
33968
|
);
|
|
33980
33969
|
const tags = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
33981
|
-
|
|
33982
|
-
result["Tags"] = tags;
|
|
33970
|
+
result["Tags"] = tags;
|
|
33983
33971
|
} catch (err) {
|
|
33984
33972
|
if (err instanceof ResourceNotFoundException14)
|
|
33985
33973
|
return void 0;
|
|
@@ -34396,8 +34384,7 @@ var CloudTrailProvider = class {
|
|
|
34396
34384
|
new ListTagsCommand3({ ResourceIdList: [trail.TrailARN] })
|
|
34397
34385
|
);
|
|
34398
34386
|
const tags = normalizeAwsTagsToCfn(tagsResp.ResourceTagList?.[0]?.TagsList);
|
|
34399
|
-
|
|
34400
|
-
result["Tags"] = tags;
|
|
34387
|
+
result["Tags"] = tags;
|
|
34401
34388
|
} catch (err) {
|
|
34402
34389
|
this.logger.debug(
|
|
34403
34390
|
`CloudTrail ListTags(${trail.TrailARN}) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -34861,8 +34848,7 @@ var CodeBuildProvider = class {
|
|
|
34861
34848
|
result["Environment"] = env;
|
|
34862
34849
|
}
|
|
34863
34850
|
const tags = normalizeAwsTagsToCfn(project.tags);
|
|
34864
|
-
|
|
34865
|
-
result["Tags"] = tags;
|
|
34851
|
+
result["Tags"] = tags;
|
|
34866
34852
|
return result;
|
|
34867
34853
|
}
|
|
34868
34854
|
async import(input) {
|
|
@@ -36457,8 +36443,7 @@ var ECRProvider = class {
|
|
|
36457
36443
|
new ListTagsForResourceCommand18({ resourceArn: r.repositoryArn })
|
|
36458
36444
|
);
|
|
36459
36445
|
const tags = normalizeAwsTagsToCfn(tagsResp.tags);
|
|
36460
|
-
|
|
36461
|
-
result["Tags"] = tags;
|
|
36446
|
+
result["Tags"] = tags;
|
|
36462
36447
|
} catch (err) {
|
|
36463
36448
|
if (!(err instanceof RepositoryNotFoundException))
|
|
36464
36449
|
throw err;
|
|
@@ -36947,10 +36932,23 @@ var DeployEngine = class {
|
|
|
36947
36932
|
this.options.noRollback = options.noRollback ?? false;
|
|
36948
36933
|
this.options.resourceWarnAfterMs = options.resourceWarnAfterMs ?? DEFAULT_RESOURCE_WARN_AFTER_MS;
|
|
36949
36934
|
this.options.resourceTimeoutMs = options.resourceTimeoutMs ?? DEFAULT_RESOURCE_TIMEOUT_MS;
|
|
36935
|
+
this.options.captureObservedState = options.captureObservedState ?? true;
|
|
36950
36936
|
}
|
|
36951
36937
|
logger = getLogger().child("DeployEngine");
|
|
36952
36938
|
resolver;
|
|
36953
36939
|
interrupted = false;
|
|
36940
|
+
/**
|
|
36941
|
+
* In-flight `provider.readCurrentState` promises kicked off after a
|
|
36942
|
+
* successful CREATE / UPDATE. The deploy critical path does NOT
|
|
36943
|
+
* `await` these; instead they're drained at the end of `doDeploy`
|
|
36944
|
+
* (success path only) and the resolved values are merged into
|
|
36945
|
+
* `ResourceState.observedProperties` before the final state save.
|
|
36946
|
+
*
|
|
36947
|
+
* Each Promise resolves to the AWS-current snapshot, or `undefined`
|
|
36948
|
+
* if the provider does not implement `readCurrentState` or the call
|
|
36949
|
+
* threw — never rejects, so an unhandled-rejection cannot escape.
|
|
36950
|
+
*/
|
|
36951
|
+
observedCaptureTasks = /* @__PURE__ */ new Map();
|
|
36954
36952
|
/**
|
|
36955
36953
|
* Target region for this stack. Required — load-bearing for the
|
|
36956
36954
|
* region-prefixed S3 state key and recorded in state.json for
|
|
@@ -36963,6 +36961,61 @@ var DeployEngine = class {
|
|
|
36963
36961
|
async deploy(stackName, template) {
|
|
36964
36962
|
return withStackName(stackName, () => this.doDeploy(stackName, template));
|
|
36965
36963
|
}
|
|
36964
|
+
/**
|
|
36965
|
+
* Kick off `provider.readCurrentState` for a freshly-created/updated
|
|
36966
|
+
* resource without blocking the deploy critical path. The promise
|
|
36967
|
+
* lands in `observedCaptureTasks` keyed by `logicalId`; the deploy's
|
|
36968
|
+
* success-path drain (`drainObservedCaptures`) awaits the full set
|
|
36969
|
+
* and merges the resolved values into `ResourceState.observedProperties`
|
|
36970
|
+
* before the final state save.
|
|
36971
|
+
*
|
|
36972
|
+
* Errors are swallowed at the Promise level — readCurrentState
|
|
36973
|
+
* failing must not fail the deploy. The map entry resolves to
|
|
36974
|
+
* `undefined` for failures and for providers without
|
|
36975
|
+
* `readCurrentState`; both translate to "no observedProperties" at
|
|
36976
|
+
* the merge step, which is fine: drift falls back to comparing
|
|
36977
|
+
* against `properties`.
|
|
36978
|
+
*/
|
|
36979
|
+
kickOffObservedCapture(provider, logicalId, physicalId, resourceType, resolvedProps) {
|
|
36980
|
+
if (this.options.captureObservedState !== true)
|
|
36981
|
+
return;
|
|
36982
|
+
if (!provider.readCurrentState)
|
|
36983
|
+
return;
|
|
36984
|
+
const promise = provider.readCurrentState(physicalId, logicalId, resourceType, resolvedProps).catch((err) => {
|
|
36985
|
+
this.logger.debug(
|
|
36986
|
+
`observedProperties capture for ${logicalId} (${resourceType}) failed: ${err instanceof Error ? err.message : String(err)} \u2014 drift will fall back to template properties for this resource until the next successful deploy.`
|
|
36987
|
+
);
|
|
36988
|
+
return void 0;
|
|
36989
|
+
});
|
|
36990
|
+
this.observedCaptureTasks.set(logicalId, promise);
|
|
36991
|
+
}
|
|
36992
|
+
/**
|
|
36993
|
+
* Wait for every in-flight `readCurrentState` promise from the
|
|
36994
|
+
* deploy's success path, then merge each resolved snapshot into the
|
|
36995
|
+
* matching `ResourceState.observedProperties`. After this runs the
|
|
36996
|
+
* map is drained so a subsequent deploy starts fresh.
|
|
36997
|
+
*
|
|
36998
|
+
* Called from `doDeploy` immediately before the final `saveState`.
|
|
36999
|
+
* The rollback / failure paths intentionally do NOT call this — a
|
|
37000
|
+
* failed deploy's partial state is already inconsistent, and waiting
|
|
37001
|
+
* on potentially many in-flight reads would slow down the rollback
|
|
37002
|
+
* itself.
|
|
37003
|
+
*/
|
|
37004
|
+
async drainObservedCaptures(stateResources) {
|
|
37005
|
+
if (this.observedCaptureTasks.size === 0)
|
|
37006
|
+
return;
|
|
37007
|
+
const entries = Array.from(this.observedCaptureTasks.entries());
|
|
37008
|
+
this.observedCaptureTasks.clear();
|
|
37009
|
+
const resolved = await Promise.all(entries.map(([, p]) => p));
|
|
37010
|
+
for (let i = 0; i < entries.length; i++) {
|
|
37011
|
+
const logicalId = entries[i][0];
|
|
37012
|
+
const observed = resolved[i];
|
|
37013
|
+
const target = stateResources[logicalId];
|
|
37014
|
+
if (target && observed !== void 0) {
|
|
37015
|
+
target.observedProperties = observed;
|
|
37016
|
+
}
|
|
37017
|
+
}
|
|
37018
|
+
}
|
|
36966
37019
|
async doDeploy(stackName, template) {
|
|
36967
37020
|
const startTime = Date.now();
|
|
36968
37021
|
this.logger.debug(`Starting deployment for stack: ${stackName}`);
|
|
@@ -37079,6 +37132,7 @@ var DeployEngine = class {
|
|
|
37079
37132
|
progress,
|
|
37080
37133
|
migrationPending
|
|
37081
37134
|
);
|
|
37135
|
+
await this.drainObservedCaptures(newState.resources);
|
|
37082
37136
|
const newEtag = await this.stateBackend.saveState(stackName, this.stackRegion, newState);
|
|
37083
37137
|
this.logger.debug(`State saved (ETag: ${newEtag})`);
|
|
37084
37138
|
const durationMs = Date.now() - startTime;
|
|
@@ -37094,6 +37148,7 @@ var DeployEngine = class {
|
|
|
37094
37148
|
} finally {
|
|
37095
37149
|
renderer.stop();
|
|
37096
37150
|
process.removeListener("SIGINT", sigintHandler);
|
|
37151
|
+
this.observedCaptureTasks.clear();
|
|
37097
37152
|
try {
|
|
37098
37153
|
await this.lockManager.releaseLock(stackName, this.stackRegion);
|
|
37099
37154
|
this.logger.debug("Lock released");
|
|
@@ -37647,6 +37702,13 @@ var DeployEngine = class {
|
|
|
37647
37702
|
...result.attributes && { attributes: result.attributes },
|
|
37648
37703
|
...dependencies && dependencies.length > 0 && { dependencies }
|
|
37649
37704
|
};
|
|
37705
|
+
this.kickOffObservedCapture(
|
|
37706
|
+
provider,
|
|
37707
|
+
logicalId,
|
|
37708
|
+
result.physicalId,
|
|
37709
|
+
resourceType,
|
|
37710
|
+
resolvedProps
|
|
37711
|
+
);
|
|
37650
37712
|
if (counts)
|
|
37651
37713
|
counts.created++;
|
|
37652
37714
|
if (progress)
|
|
@@ -37725,6 +37787,13 @@ var DeployEngine = class {
|
|
|
37725
37787
|
...createResult.attributes && { attributes: createResult.attributes },
|
|
37726
37788
|
...dependencies && dependencies.length > 0 && { dependencies }
|
|
37727
37789
|
};
|
|
37790
|
+
this.kickOffObservedCapture(
|
|
37791
|
+
provider,
|
|
37792
|
+
logicalId,
|
|
37793
|
+
createResult.physicalId,
|
|
37794
|
+
resourceType,
|
|
37795
|
+
resolvedProps
|
|
37796
|
+
);
|
|
37728
37797
|
if (counts)
|
|
37729
37798
|
counts.updated++;
|
|
37730
37799
|
if (progress)
|
|
@@ -37803,6 +37872,13 @@ var DeployEngine = class {
|
|
|
37803
37872
|
...result.attributes && { attributes: result.attributes },
|
|
37804
37873
|
...dependencies && dependencies.length > 0 && { dependencies }
|
|
37805
37874
|
};
|
|
37875
|
+
this.kickOffObservedCapture(
|
|
37876
|
+
provider,
|
|
37877
|
+
logicalId,
|
|
37878
|
+
result.physicalId,
|
|
37879
|
+
resourceType,
|
|
37880
|
+
resolvedProps
|
|
37881
|
+
);
|
|
37806
37882
|
if (counts)
|
|
37807
37883
|
counts.updated++;
|
|
37808
37884
|
if (progress)
|
|
@@ -38281,6 +38357,7 @@ Deploying stack: ${stackInfo.stackName}${stackRegion !== baseRegion ? ` (region:
|
|
|
38281
38357
|
concurrency: options.concurrency,
|
|
38282
38358
|
dryRun: options.dryRun,
|
|
38283
38359
|
noRollback: !options.rollback,
|
|
38360
|
+
captureObservedState: resolveCaptureObservedState(options.captureObservedState),
|
|
38284
38361
|
...options.resourceWarnAfter?.globalMs !== void 0 && {
|
|
38285
38362
|
resourceWarnAfterMs: options.resourceWarnAfter.globalMs
|
|
38286
38363
|
},
|
|
@@ -38984,7 +39061,8 @@ async function runDriftForStack(stackName, region, stateBackend, providerRegistr
|
|
|
38984
39061
|
continue;
|
|
38985
39062
|
}
|
|
38986
39063
|
const ignorePaths = provider.getDriftUnknownPaths ? provider.getDriftUnknownPaths(resource.resourceType) : [];
|
|
38987
|
-
const
|
|
39064
|
+
const baseline = resource.observedProperties ?? resource.properties ?? {};
|
|
39065
|
+
const changes = calculateResourceDrift(baseline, aws, { ignorePaths });
|
|
38988
39066
|
if (changes.length === 0) {
|
|
38989
39067
|
outcomes.push({ kind: "clean", logicalId, resourceType: resource.resourceType });
|
|
38990
39068
|
} else {
|
|
@@ -39056,14 +39134,13 @@ async function runAccept(reports, stateBackend, stateConfig, awsClients, options
|
|
|
39056
39134
|
const existing = resources[outcome.logicalId];
|
|
39057
39135
|
if (!existing)
|
|
39058
39136
|
continue;
|
|
39059
|
-
const
|
|
39137
|
+
const hasObserved = existing.observedProperties !== void 0;
|
|
39138
|
+
const baselineSource = hasObserved ? existing.observedProperties : existing.properties ?? {};
|
|
39139
|
+
const newBaseline = JSON.parse(JSON.stringify(baselineSource));
|
|
39060
39140
|
for (const change of outcome.changes) {
|
|
39061
|
-
setAtPath(
|
|
39141
|
+
setAtPath(newBaseline, change.path, change.awsValue);
|
|
39062
39142
|
}
|
|
39063
|
-
resources[outcome.logicalId] = {
|
|
39064
|
-
...existing,
|
|
39065
|
-
properties: newProperties
|
|
39066
|
-
};
|
|
39143
|
+
resources[outcome.logicalId] = hasObserved ? { ...existing, observedProperties: newBaseline } : { ...existing, properties: newBaseline };
|
|
39067
39144
|
}
|
|
39068
39145
|
const newState = {
|
|
39069
39146
|
...report.state,
|
|
@@ -39130,13 +39207,14 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
|
|
|
39130
39207
|
return;
|
|
39131
39208
|
}
|
|
39132
39209
|
const provider = providerRegistry.getProvider(outcome.resourceType);
|
|
39210
|
+
const desiredProperties = stateResource.observedProperties ?? stateResource.properties ?? {};
|
|
39133
39211
|
try {
|
|
39134
39212
|
await withRetry(
|
|
39135
39213
|
() => provider.update(
|
|
39136
39214
|
outcome.logicalId,
|
|
39137
39215
|
stateResource.physicalId,
|
|
39138
39216
|
outcome.resourceType,
|
|
39139
|
-
|
|
39217
|
+
desiredProperties,
|
|
39140
39218
|
outcome.awsProperties
|
|
39141
39219
|
),
|
|
39142
39220
|
outcome.logicalId,
|
|
@@ -42209,6 +42287,7 @@ async function importCommand(stackArg, options) {
|
|
|
42209
42287
|
existingState,
|
|
42210
42288
|
selectiveMode
|
|
42211
42289
|
);
|
|
42290
|
+
await captureObservedForImportedResources(stackState, providerRegistry, logger);
|
|
42212
42291
|
const saveOptions = {};
|
|
42213
42292
|
if (existingEtag) {
|
|
42214
42293
|
saveOptions.expectedEtag = existingEtag;
|
|
@@ -42409,7 +42488,7 @@ function buildStackState(stackName, region, rows, templateParser, template, exis
|
|
|
42409
42488
|
};
|
|
42410
42489
|
}
|
|
42411
42490
|
return {
|
|
42412
|
-
version:
|
|
42491
|
+
version: STATE_SCHEMA_VERSION_CURRENT,
|
|
42413
42492
|
stackName,
|
|
42414
42493
|
region,
|
|
42415
42494
|
resources,
|
|
@@ -42502,6 +42581,33 @@ function createImportCommand() {
|
|
|
42502
42581
|
function collectMultiple(value, previous) {
|
|
42503
42582
|
return [...previous ?? [], value];
|
|
42504
42583
|
}
|
|
42584
|
+
async function captureObservedForImportedResources(stackState, providerRegistry, logger) {
|
|
42585
|
+
const entries = Object.entries(stackState.resources);
|
|
42586
|
+
if (entries.length === 0)
|
|
42587
|
+
return;
|
|
42588
|
+
await Promise.all(
|
|
42589
|
+
entries.map(async ([logicalId, resource]) => {
|
|
42590
|
+
try {
|
|
42591
|
+
const provider = providerRegistry.getProvider(resource.resourceType);
|
|
42592
|
+
if (!provider.readCurrentState)
|
|
42593
|
+
return;
|
|
42594
|
+
const observed = await provider.readCurrentState(
|
|
42595
|
+
resource.physicalId,
|
|
42596
|
+
logicalId,
|
|
42597
|
+
resource.resourceType,
|
|
42598
|
+
resource.properties ?? {}
|
|
42599
|
+
);
|
|
42600
|
+
if (observed !== void 0) {
|
|
42601
|
+
resource.observedProperties = observed;
|
|
42602
|
+
}
|
|
42603
|
+
} catch (err) {
|
|
42604
|
+
logger.debug(
|
|
42605
|
+
`observedProperties capture for imported ${logicalId} (${resource.resourceType}) failed: ${err instanceof Error ? err.message : String(err)} \u2014 drift will fall back to template properties for this resource until the next successful deploy.`
|
|
42606
|
+
);
|
|
42607
|
+
}
|
|
42608
|
+
})
|
|
42609
|
+
);
|
|
42610
|
+
}
|
|
42505
42611
|
|
|
42506
42612
|
// src/cli/index.ts
|
|
42507
42613
|
var SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
@@ -42531,7 +42637,7 @@ function reorderArgs(argv) {
|
|
|
42531
42637
|
}
|
|
42532
42638
|
async function main() {
|
|
42533
42639
|
const program = new Command14();
|
|
42534
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
42640
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.48.0");
|
|
42535
42641
|
program.addCommand(createBootstrapCommand());
|
|
42536
42642
|
program.addCommand(createSynthCommand());
|
|
42537
42643
|
program.addCommand(createListCommand());
|