sst 2.47.2 → 2.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/cdk/deploy-stack.d.ts +3 -39
- package/cdk/deploy-stack.js +31 -27
- package/cdk/deployments-wrapper.js +5 -12
- package/cdk/deployments.d.ts +13 -34
- package/cdk/deployments.js +58 -51
- package/credentials.js +1 -1
- package/package.json +8 -8
- package/package.json.bak +8 -8
- package/stacks/synth.js +1 -1
package/cdk/deploy-stack.d.ts
CHANGED
|
@@ -1,31 +1,13 @@
|
|
|
1
1
|
import * as cxapi from "@aws-cdk/cx-api";
|
|
2
2
|
import type { Tag } from "@aws-sdk/client-cloudformation";
|
|
3
|
+
import { ResourcesToImport } from "sst-aws-cdk/lib/api/deployments/cloudformation.js";
|
|
4
|
+
import { DeploymentMethod } from "sst-aws-cdk/lib/api/deployments/deployment-method.js";
|
|
5
|
+
import { DeployStackResult } from "sst-aws-cdk/lib/api/deployments/deployment-result.js";
|
|
3
6
|
import type { SDK, SdkProvider } from "sst-aws-cdk/lib/api/aws-auth/index.js";
|
|
4
7
|
import type { EnvironmentResources } from "sst-aws-cdk/lib/api/environment-resources.js";
|
|
5
8
|
import { HotswapMode, HotswapPropertyOverrides } from "sst-aws-cdk/lib/api/hotswap/common.js";
|
|
6
|
-
import { ResourcesToImport } from "sst-aws-cdk/lib/api/util/cloudformation.js";
|
|
7
9
|
import { type StackActivityProgress } from "sst-aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.js";
|
|
8
10
|
import { StringWithoutPlaceholders } from "sst-aws-cdk/lib/api/util/placeholders.js";
|
|
9
|
-
export type DeployStackResult = SuccessfulDeployStackResult | NeedRollbackFirstDeployStackResult | ReplacementRequiresNoRollbackStackResult;
|
|
10
|
-
/** Successfully deployed a stack */
|
|
11
|
-
export interface SuccessfulDeployStackResult {
|
|
12
|
-
readonly type: "did-deploy-stack";
|
|
13
|
-
readonly noOp: boolean;
|
|
14
|
-
readonly outputs: {
|
|
15
|
-
[name: string]: string;
|
|
16
|
-
};
|
|
17
|
-
readonly stackArn: string;
|
|
18
|
-
}
|
|
19
|
-
/** The stack is currently in a failpaused state, and needs to be rolled back before the deployment */
|
|
20
|
-
export interface NeedRollbackFirstDeployStackResult {
|
|
21
|
-
readonly type: "failpaused-need-rollback-first";
|
|
22
|
-
readonly reason: "not-norollback" | "replacement";
|
|
23
|
-
}
|
|
24
|
-
/** The upcoming change has a replacement, which requires deploying without --no-rollback */
|
|
25
|
-
export interface ReplacementRequiresNoRollbackStackResult {
|
|
26
|
-
readonly type: "replacement-requires-norollback";
|
|
27
|
-
}
|
|
28
|
-
export declare function assertIsSuccessfulDeployStackResult(x: DeployStackResult): asserts x is SuccessfulDeployStackResult;
|
|
29
11
|
export interface DeployStackOptions {
|
|
30
12
|
/**
|
|
31
13
|
* The stack to be deployed
|
|
@@ -183,24 +165,6 @@ export interface DeployStackOptions {
|
|
|
183
165
|
*/
|
|
184
166
|
readonly assetParallelism?: boolean;
|
|
185
167
|
}
|
|
186
|
-
export type DeploymentMethod = DirectDeploymentMethod | ChangeSetDeploymentMethod;
|
|
187
|
-
export interface DirectDeploymentMethod {
|
|
188
|
-
readonly method: "direct";
|
|
189
|
-
}
|
|
190
|
-
export interface ChangeSetDeploymentMethod {
|
|
191
|
-
readonly method: "change-set";
|
|
192
|
-
/**
|
|
193
|
-
* Whether to execute the changeset or leave it in review.
|
|
194
|
-
*
|
|
195
|
-
* @default true
|
|
196
|
-
*/
|
|
197
|
-
readonly execute?: boolean;
|
|
198
|
-
/**
|
|
199
|
-
* Optional name to use for the CloudFormation change set.
|
|
200
|
-
* If not provided, a name will be generated automatically.
|
|
201
|
-
*/
|
|
202
|
-
readonly changeSetName?: string;
|
|
203
|
-
}
|
|
204
168
|
export declare function deployStack(options: DeployStackOptions): Promise<DeployStackResult | undefined>;
|
|
205
169
|
export interface DestroyStackOptions {
|
|
206
170
|
/**
|
package/cdk/deploy-stack.js
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import * as uuid from "uuid";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { AssetManifestBuilder } from "sst-aws-cdk/lib/api/deployments/asset-manifest-builder.js";
|
|
3
|
+
import { publishAssets } from "sst-aws-cdk/lib/api/deployments/asset-publishing.js";
|
|
4
|
+
import { addMetadataAssetsToManifest } from "sst-aws-cdk/lib/api/deployments/assets.js";
|
|
5
|
+
import { determineAllowCrossAccountAssetPublishing } from "sst-aws-cdk/lib/api/deployments/checks.js";
|
|
6
|
+
import { changeSetHasNoChanges, CloudFormationStack, TemplateParameters, waitForChangeSet, waitForStackDeploy, waitForStackDelete, } from "sst-aws-cdk/lib/api/deployments/cloudformation.js";
|
|
7
|
+
import { tryHotswapDeployment } from "sst-aws-cdk/lib/api/deployments/hotswap-deployments.js";
|
|
8
|
+
import { debug, info, warning } from "sst-aws-cdk/lib/logging.js";
|
|
9
|
+
import { ToolkitError } from "sst-aws-cdk/lib/toolkit/error.js";
|
|
10
|
+
import { formatErrorMessage } from "sst-aws-cdk/lib/util/error.js";
|
|
4
11
|
import { CfnEvaluationException } from "sst-aws-cdk/lib/api/evaluate-cloudformation-template.js";
|
|
5
12
|
import { HotswapMode, HotswapPropertyOverrides, } from "sst-aws-cdk/lib/api/hotswap/common.js";
|
|
6
|
-
import { tryHotswapDeployment } from "sst-aws-cdk/lib/api/hotswap-deployments.js";
|
|
7
|
-
import { changeSetHasNoChanges, CloudFormationStack, TemplateParameters, waitForChangeSet, waitForStackDeploy, waitForStackDelete, } from "sst-aws-cdk/lib/api/util/cloudformation.js";
|
|
8
13
|
import { makeBodyParameter, } from "sst-aws-cdk/lib/api/util/template-body-parameter.js";
|
|
9
|
-
import { AssetManifestBuilder } from "sst-aws-cdk/lib/util/asset-manifest-builder.js";
|
|
10
|
-
import { determineAllowCrossAccountAssetPublishing } from "sst-aws-cdk/lib/api/util/checks.js";
|
|
11
|
-
import { publishAssets } from "sst-aws-cdk/lib/util/asset-publishing.js";
|
|
12
14
|
import { callWithRetry } from "./util.js";
|
|
13
|
-
export function assertIsSuccessfulDeployStackResult(x) {
|
|
14
|
-
if (x.type !== "did-deploy-stack") {
|
|
15
|
-
throw new Error(`Unexpected deployStack result. This should not happen: ${JSON.stringify(x)}. If you are seeing this error, please report it at https://github.com/aws/aws-cdk/issues/new/choose.`);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
15
|
export async function deployStack(options) {
|
|
19
16
|
const stackArtifact = options.stack;
|
|
20
17
|
const stackEnv = options.resolvedEnvironment;
|
|
@@ -27,7 +24,7 @@ export async function deployStack(options) {
|
|
|
27
24
|
await cfn.deleteStack({ StackName: deployName });
|
|
28
25
|
const deletedStack = await waitForStackDelete(cfn, deployName);
|
|
29
26
|
if (deletedStack && deletedStack.stackStatus.name !== "DELETE_COMPLETE") {
|
|
30
|
-
throw new
|
|
27
|
+
throw new ToolkitError(`Failed deleting stack ${deployName} that had previously failed creation (current state: ${deletedStack.stackStatus})`);
|
|
31
28
|
}
|
|
32
29
|
// Update variable to mark that the stack does not exist anymore, but avoid
|
|
33
30
|
// doing an actual lookup in CloudFormation (which would be silly to do if
|
|
@@ -81,16 +78,16 @@ export async function deployStack(options) {
|
|
|
81
78
|
if (hotswapDeploymentResult) {
|
|
82
79
|
return hotswapDeploymentResult;
|
|
83
80
|
}
|
|
84
|
-
|
|
81
|
+
info("Could not perform a hotswap deployment, as the stack %s contains non-Asset changes", stackArtifact.displayName);
|
|
85
82
|
}
|
|
86
83
|
catch (e) {
|
|
87
84
|
if (!(e instanceof CfnEvaluationException)) {
|
|
88
85
|
throw e;
|
|
89
86
|
}
|
|
90
|
-
|
|
87
|
+
info("Could not perform a hotswap deployment, because the CloudFormation template could not be resolved: %s", formatErrorMessage(e));
|
|
91
88
|
}
|
|
92
89
|
if (hotswapMode === HotswapMode.FALL_BACK) {
|
|
93
|
-
|
|
90
|
+
info("Falling back to doing a full deployment");
|
|
94
91
|
options.sdk.appendCustomUserAgent("cdk-hotswap/fallback");
|
|
95
92
|
}
|
|
96
93
|
else {
|
|
@@ -140,7 +137,7 @@ class FullCloudFormationDeployment {
|
|
|
140
137
|
};
|
|
141
138
|
if (deploymentMethod.method === "direct" &&
|
|
142
139
|
this.options.resourcesToImport) {
|
|
143
|
-
throw new
|
|
140
|
+
throw new ToolkitError("Importing resources requires a changeset deployment");
|
|
144
141
|
}
|
|
145
142
|
switch (deploymentMethod.method) {
|
|
146
143
|
case "change-set":
|
|
@@ -152,7 +149,8 @@ class FullCloudFormationDeployment {
|
|
|
152
149
|
async changeSetDeployment(deploymentMethod) {
|
|
153
150
|
const changeSetName = deploymentMethod.changeSetName ?? "cdk-deploy-change-set";
|
|
154
151
|
const execute = deploymentMethod.execute ?? true;
|
|
155
|
-
const
|
|
152
|
+
const importExistingResources = deploymentMethod.importExistingResources ?? false;
|
|
153
|
+
const changeSetDescription = await this.createChangeSet(changeSetName, execute, importExistingResources);
|
|
156
154
|
await this.updateTerminationProtection();
|
|
157
155
|
if (changeSetHasNoChanges(changeSetDescription)) {
|
|
158
156
|
debug("No changes are to be performed on %s.", this.stackName);
|
|
@@ -180,7 +178,7 @@ class FullCloudFormationDeployment {
|
|
|
180
178
|
};
|
|
181
179
|
}
|
|
182
180
|
if (!execute) {
|
|
183
|
-
|
|
181
|
+
info("Changeset %s created and waiting in review for manual execution (--no-execute)", changeSetDescription.ChangeSetId);
|
|
184
182
|
return {
|
|
185
183
|
type: "did-deploy-stack",
|
|
186
184
|
noOp: false,
|
|
@@ -193,20 +191,25 @@ class FullCloudFormationDeployment {
|
|
|
193
191
|
const isPausedFailState = this.cloudFormationStack.stackStatus.isRollbackable;
|
|
194
192
|
const rollback = this.options.rollback ?? true;
|
|
195
193
|
if (isPausedFailState && replacement) {
|
|
196
|
-
return {
|
|
194
|
+
return {
|
|
195
|
+
type: "failpaused-need-rollback-first",
|
|
196
|
+
reason: "replacement",
|
|
197
|
+
status: this.cloudFormationStack.stackStatus.name,
|
|
198
|
+
};
|
|
197
199
|
}
|
|
198
|
-
if (isPausedFailState &&
|
|
200
|
+
if (isPausedFailState && rollback) {
|
|
199
201
|
return {
|
|
200
202
|
type: "failpaused-need-rollback-first",
|
|
201
203
|
reason: "not-norollback",
|
|
204
|
+
status: this.cloudFormationStack.stackStatus.name,
|
|
202
205
|
};
|
|
203
206
|
}
|
|
204
207
|
if (!rollback && replacement) {
|
|
205
|
-
return { type: "replacement-requires-
|
|
208
|
+
return { type: "replacement-requires-rollback" };
|
|
206
209
|
}
|
|
207
210
|
return this.executeChangeSet(changeSetDescription);
|
|
208
211
|
}
|
|
209
|
-
async createChangeSet(changeSetName, willExecute) {
|
|
212
|
+
async createChangeSet(changeSetName, willExecute, importExistingResources) {
|
|
210
213
|
await this.cleanupOldChangeset(changeSetName);
|
|
211
214
|
debug(`Attempting to create ChangeSet with name ${changeSetName} to ${this.verb} stack ${this.stackName}`);
|
|
212
215
|
const changeSet = await this.cfn.createChangeSet({
|
|
@@ -220,6 +223,7 @@ class FullCloudFormationDeployment {
|
|
|
220
223
|
ResourcesToImport: this.options.resourcesToImport,
|
|
221
224
|
Description: `CDK Changeset for execution ${this.uuid}`,
|
|
222
225
|
ClientToken: `create${this.uuid}`,
|
|
226
|
+
ImportExistingResources: importExistingResources,
|
|
223
227
|
...this.commonPrepareOptions(),
|
|
224
228
|
});
|
|
225
229
|
debug("Initiated creation of changeset: %s; waiting for it to finish creating...", changeSet.Id);
|
|
@@ -328,12 +332,12 @@ class FullCloudFormationDeployment {
|
|
|
328
332
|
const successStack = await waitForStackDeploy(this.cfn, this.stackName);
|
|
329
333
|
// This shouldn't really happen, but catch it anyway. You never know.
|
|
330
334
|
if (!successStack) {
|
|
331
|
-
throw new
|
|
335
|
+
throw new ToolkitError("Stack deploy failed (the stack disappeared while we were deploying it)");
|
|
332
336
|
}
|
|
333
337
|
finalState = successStack;
|
|
334
338
|
}
|
|
335
339
|
catch (e) {
|
|
336
|
-
throw new
|
|
340
|
+
throw new ToolkitError(suffixWithErrors(formatErrorMessage(e) /*, monitor?.errors*/));
|
|
337
341
|
}
|
|
338
342
|
finally {
|
|
339
343
|
// await monitor?.stop();
|
|
@@ -397,11 +401,11 @@ export async function destroyStack(options) {
|
|
|
397
401
|
const destroyedStack = await waitForStackDelete(cfn, deployName);
|
|
398
402
|
if (destroyedStack &&
|
|
399
403
|
destroyedStack.stackStatus.name !== "DELETE_COMPLETE") {
|
|
400
|
-
throw new
|
|
404
|
+
throw new ToolkitError(`Failed to destroy ${deployName}: ${destroyedStack.stackStatus}`);
|
|
401
405
|
}
|
|
402
406
|
}
|
|
403
407
|
catch (e) {
|
|
404
|
-
throw new
|
|
408
|
+
throw new ToolkitError(suffixWithErrors(formatErrorMessage(e) /* , monitor?.errors */));
|
|
405
409
|
}
|
|
406
410
|
finally {
|
|
407
411
|
/*
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import * as cxapi from "@aws-cdk/cx-api";
|
|
2
|
+
import { AssetManifestBuilder } from "sst-aws-cdk/lib/api/deployments/asset-manifest-builder.js";
|
|
2
3
|
import { AssetManifest } from "cdk-assets";
|
|
3
4
|
import { debug } from "sst-aws-cdk/lib/logging.js";
|
|
4
|
-
import { CloudFormationStack, TemplateParameters, waitForStackDelete, } from "sst-aws-cdk/lib/api/
|
|
5
|
-
import { addMetadataAssetsToManifest } from "sst-aws-cdk/lib/assets.js";
|
|
6
|
-
import { publishAssets } from "sst-aws-cdk/lib/util/asset-publishing.js";
|
|
7
|
-
import { AssetManifestBuilder } from "sst-aws-cdk/lib/util/asset-manifest-builder.js";
|
|
5
|
+
import { CloudFormationStack, TemplateParameters, waitForStackDelete, } from "sst-aws-cdk/lib/api/deployments/cloudformation.js";
|
|
6
|
+
import { addMetadataAssetsToManifest } from "sst-aws-cdk/lib/api/deployments/assets.js";
|
|
8
7
|
import { makeBodyParameter } from "sst-aws-cdk/lib/api/util/template-body-parameter.js";
|
|
9
|
-
import { Deployments, } from "./deployments.js";
|
|
8
|
+
import { publishAssets, Deployments, } from "./deployments.js";
|
|
10
9
|
import { lazy } from "../util/lazy.js";
|
|
11
10
|
export async function publishDeployAssets(sdkProvider, options) {
|
|
12
11
|
const { deployment, envResources, stackSdk, resolvedEnvironment, executionRoleArn, } = await useDeployment().get(sdkProvider, options);
|
|
@@ -14,10 +13,7 @@ export async function publishDeployAssets(sdkProvider, options) {
|
|
|
14
13
|
for (const asset of assetArtifacts) {
|
|
15
14
|
const manifest = AssetManifest.fromFile(asset.file);
|
|
16
15
|
await publishAssets(manifest, sdkProvider, resolvedEnvironment, {
|
|
17
|
-
buildAssets: true,
|
|
18
|
-
allowCrossAccount: true,
|
|
19
16
|
quiet: options.quiet,
|
|
20
|
-
parallel: options.assetParallelism,
|
|
21
17
|
});
|
|
22
18
|
}
|
|
23
19
|
return deployStack({
|
|
@@ -101,10 +97,7 @@ async function deployStack(options) {
|
|
|
101
97
|
? templateParams.updateExisting(finalParameterValues, cloudFormationStack.parameters)
|
|
102
98
|
: templateParams.supplyAll(finalParameterValues);
|
|
103
99
|
const bodyParameter = await makeBodyParameter(stackArtifact, options.resolvedEnvironment, legacyAssets, options.envResources, options.overrideTemplate);
|
|
104
|
-
await publishAssets(legacyAssets.toManifest(stackArtifact.assembly.directory), options.sdkProvider, stackEnv, {
|
|
105
|
-
parallel: options.assetParallelism,
|
|
106
|
-
allowCrossAccount: true,
|
|
107
|
-
});
|
|
100
|
+
await publishAssets(legacyAssets.toManifest(stackArtifact.assembly.directory), options.sdkProvider, stackEnv, { quiet: options.quiet });
|
|
108
101
|
return {
|
|
109
102
|
isUpdate: cloudFormationStack.exists &&
|
|
110
103
|
cloudFormationStack.stackStatus.name !== "REVIEW_IN_PROGRESS",
|
package/cdk/deployments.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import * as cxapi from "@aws-cdk/cx-api";
|
|
2
2
|
import * as cdk_assets from "cdk-assets";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
3
|
+
import { type ResourceIdentifierSummaries, ResourcesToImport, Template } from "sst-aws-cdk/lib/api/deployments/cloudformation.js";
|
|
4
|
+
import { DeploymentMethod } from "sst-aws-cdk/lib/api/deployments/deployment-method.js";
|
|
5
|
+
import { DeployStackResult } from "sst-aws-cdk/lib/api/deployments/deployment-result.js";
|
|
6
|
+
import { type RootTemplateWithNestedStacks } from "sst-aws-cdk/lib/api/deployments/nested-stack-helpers.js";
|
|
6
7
|
import type { SdkProvider } from "sst-aws-cdk/lib/api/aws-auth/sdk-provider.js";
|
|
7
|
-
import {
|
|
8
|
+
import { EnvironmentAccess } from "sst-aws-cdk/lib/api/environment-access.js";
|
|
8
9
|
import { type EnvironmentResources } from "sst-aws-cdk/lib/api/environment-resources.js";
|
|
9
10
|
import { HotswapMode, HotswapPropertyOverrides } from "sst-aws-cdk/lib/api/hotswap/common.js";
|
|
10
|
-
import {
|
|
11
|
-
import { type ResourceIdentifierSummaries, ResourcesToImport, Template } from "sst-aws-cdk/lib/api/util/cloudformation.js";
|
|
11
|
+
import type { Tag } from "sst-aws-cdk/lib/api/tags.js";
|
|
12
12
|
import { StackActivityProgress } from "sst-aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.js";
|
|
13
|
-
import {
|
|
13
|
+
import { AssetManifest } from "cdk-assets";
|
|
14
14
|
export interface DeployStackOptions {
|
|
15
15
|
/**
|
|
16
16
|
* Stack to deploy
|
|
@@ -223,20 +223,12 @@ interface AssetOptions {
|
|
|
223
223
|
readonly roleArn?: string;
|
|
224
224
|
}
|
|
225
225
|
export interface BuildStackAssetsOptions extends AssetOptions {
|
|
226
|
-
/**
|
|
227
|
-
* Options to pass on to `buildAsests()` function
|
|
228
|
-
*/
|
|
229
|
-
readonly buildOptions?: BuildAssetsOptions;
|
|
230
226
|
/**
|
|
231
227
|
* Stack name this asset is for
|
|
232
228
|
*/
|
|
233
229
|
readonly stackName?: string;
|
|
234
230
|
}
|
|
235
231
|
interface PublishStackAssetsOptions extends AssetOptions {
|
|
236
|
-
/**
|
|
237
|
-
* Options to pass on to `publishAsests()` function
|
|
238
|
-
*/
|
|
239
|
-
readonly publishOptions?: Omit<PublishAssetsOptions, "buildAssets">;
|
|
240
232
|
/**
|
|
241
233
|
* Stack name this asset is for
|
|
242
234
|
*/
|
|
@@ -300,22 +292,6 @@ export declare class Deployments {
|
|
|
300
292
|
rollbackStack(options: RollbackStackOptions): Promise<RollbackStackResult>;
|
|
301
293
|
destroyStack(options: DestroyStackOptions): Promise<void>;
|
|
302
294
|
stackExists(options: StackExistsOptions): Promise<boolean>;
|
|
303
|
-
prepareAndValidateAssets(asset: cxapi.AssetManifestArtifact, options: AssetOptions): Promise<{
|
|
304
|
-
manifest: cdk_assets.AssetManifest;
|
|
305
|
-
stackEnv: cxapi.Environment;
|
|
306
|
-
}>;
|
|
307
|
-
/**
|
|
308
|
-
* Build all assets in a manifest
|
|
309
|
-
*
|
|
310
|
-
* @deprecated Use `buildSingleAsset` instead
|
|
311
|
-
*/
|
|
312
|
-
buildAssets(asset: cxapi.AssetManifestArtifact, options: BuildStackAssetsOptions): Promise<void>;
|
|
313
|
-
/**
|
|
314
|
-
* Publish all assets in a manifest
|
|
315
|
-
*
|
|
316
|
-
* @deprecated Use `publishSingleAsset` instead
|
|
317
|
-
*/
|
|
318
|
-
publishAssets(asset: cxapi.AssetManifestArtifact, options: PublishStackAssetsOptions): Promise<void>;
|
|
319
295
|
/**
|
|
320
296
|
* Build a single asset from an asset manifest
|
|
321
297
|
*
|
|
@@ -323,16 +299,16 @@ export declare class Deployments {
|
|
|
323
299
|
* will be validated according to the constraints in that manifest artifact.
|
|
324
300
|
* If that is not necessary, `'no-version-validation'` can be passed.
|
|
325
301
|
*/
|
|
326
|
-
buildSingleAsset(assetArtifact: cxapi.AssetManifestArtifact | "no-version-validation", assetManifest: AssetManifest, asset: IManifestEntry, options: BuildStackAssetsOptions): Promise<void>;
|
|
302
|
+
buildSingleAsset(assetArtifact: cxapi.AssetManifestArtifact | "no-version-validation", assetManifest: cdk_assets.AssetManifest, asset: cdk_assets.IManifestEntry, options: BuildStackAssetsOptions): Promise<void>;
|
|
327
303
|
/**
|
|
328
304
|
* Publish a single asset from an asset manifest
|
|
329
305
|
*/
|
|
330
|
-
publishSingleAsset(assetManifest: AssetManifest, asset: IManifestEntry, options: PublishStackAssetsOptions): Promise<void>;
|
|
306
|
+
publishSingleAsset(assetManifest: cdk_assets.AssetManifest, asset: cdk_assets.IManifestEntry, options: PublishStackAssetsOptions): Promise<void>;
|
|
331
307
|
private allowCrossAccountAssetPublishingForEnv;
|
|
332
308
|
/**
|
|
333
309
|
* Return whether a single asset has been published already
|
|
334
310
|
*/
|
|
335
|
-
isSingleAssetPublished(assetManifest: AssetManifest, asset: IManifestEntry, options: PublishStackAssetsOptions): Promise<boolean>;
|
|
311
|
+
isSingleAssetPublished(assetManifest: cdk_assets.AssetManifest, asset: cdk_assets.IManifestEntry, options: PublishStackAssetsOptions): Promise<boolean>;
|
|
336
312
|
/**
|
|
337
313
|
* Validate that the bootstrap stack has the right version for this stack
|
|
338
314
|
*
|
|
@@ -341,4 +317,7 @@ export declare class Deployments {
|
|
|
341
317
|
validateBootstrapStackVersion(stackName: string, requiresBootstrapStackVersion: number | undefined, bootstrapStackVersionSsmParameter: string | undefined, envResources: EnvironmentResources): Promise<void>;
|
|
342
318
|
private cachedPublisher;
|
|
343
319
|
}
|
|
320
|
+
export declare function publishAssets(manifest: AssetManifest, sdk: SdkProvider, targetEnv: cxapi.Environment, options: {
|
|
321
|
+
quiet?: boolean;
|
|
322
|
+
}): Promise<void>;
|
|
344
323
|
export {};
|
package/cdk/deployments.js
CHANGED
|
@@ -2,20 +2,22 @@
|
|
|
2
2
|
import { randomUUID } from "crypto";
|
|
3
3
|
import * as cxapi from "@aws-cdk/cx-api";
|
|
4
4
|
import * as cdk_assets from "cdk-assets";
|
|
5
|
-
import {
|
|
5
|
+
import { AssetManifestBuilder } from "sst-aws-cdk/lib/api/deployments/asset-manifest-builder.js";
|
|
6
|
+
import { EVENT_TO_LOGGER, PublishingAws, } from "sst-aws-cdk/lib/api/deployments/asset-publishing.js";
|
|
7
|
+
import { determineAllowCrossAccountAssetPublishing } from "sst-aws-cdk/lib/api/deployments/checks.js";
|
|
8
|
+
import { CloudFormationStack, stabilizeStack, uploadStackTemplateAssets, } from "sst-aws-cdk/lib/api/deployments/cloudformation.js";
|
|
9
|
+
import { deployStack, destroyStack } from "./deploy-stack.js";
|
|
10
|
+
import { loadCurrentTemplate, loadCurrentTemplateWithNestedStacks, } from "sst-aws-cdk/lib/api/deployments/nested-stack-helpers.js";
|
|
6
11
|
import { debug, warning } from "sst-aws-cdk/lib/logging.js";
|
|
12
|
+
import { ToolkitError } from "sst-aws-cdk/lib/toolkit/error.js";
|
|
13
|
+
import { formatErrorMessage } from "sst-aws-cdk/lib/util/error.js";
|
|
7
14
|
import { EnvironmentAccess } from "sst-aws-cdk/lib/api/environment-access.js";
|
|
8
|
-
import { deployStack, destroyStack, } from "./deploy-stack.js";
|
|
9
|
-
import { loadCurrentTemplateWithNestedStacks, loadCurrentTemplate, } from "sst-aws-cdk/lib/api/nested-stack-helpers.js";
|
|
10
15
|
import { DEFAULT_TOOLKIT_STACK_NAME } from "sst-aws-cdk/lib/api/toolkit-info.js";
|
|
11
|
-
import { determineAllowCrossAccountAssetPublishing } from "sst-aws-cdk/lib/api/util/checks.js";
|
|
12
|
-
import { CloudFormationStack, stabilizeStack, uploadStackTemplateAssets, } from "sst-aws-cdk/lib/api/util/cloudformation.js";
|
|
13
16
|
import { StackActivityMonitor, } from "sst-aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.js";
|
|
14
17
|
import { StackEventPoller } from "sst-aws-cdk/lib/api/util/cloudformation/stack-event-poller.js";
|
|
15
18
|
import { RollbackChoice } from "sst-aws-cdk/lib/api/util/cloudformation/stack-status.js";
|
|
16
19
|
import { makeBodyParameter } from "sst-aws-cdk/lib/api/util/template-body-parameter.js";
|
|
17
|
-
import {
|
|
18
|
-
import { buildAssets, EVENT_TO_LOGGER, publishAssets, PublishingAws, } from "sst-aws-cdk/lib/util/asset-publishing.js";
|
|
20
|
+
import { AssetManifest } from "cdk-assets";
|
|
19
21
|
const BOOTSTRAP_STACK_VERSION_FOR_ROLLBACK = 23;
|
|
20
22
|
/**
|
|
21
23
|
* Scope for a single set of deployments from a set of Cloud Assembly Artifacts
|
|
@@ -98,7 +100,7 @@ export class Deployments {
|
|
|
98
100
|
let deploymentMethod = options.deploymentMethod;
|
|
99
101
|
if (options.changeSetName || options.execute !== undefined) {
|
|
100
102
|
if (deploymentMethod) {
|
|
101
|
-
throw new
|
|
103
|
+
throw new ToolkitError("You cannot supply both 'deploymentMethod' and 'changeSetName/execute'. Supply one or the other.");
|
|
102
104
|
}
|
|
103
105
|
deploymentMethod = {
|
|
104
106
|
method: "change-set",
|
|
@@ -114,12 +116,7 @@ export class Deployments {
|
|
|
114
116
|
const assetArtifacts = options.stack.dependencies.filter(cxapi.AssetManifestArtifact.isAssetManifestArtifact);
|
|
115
117
|
for (const asset of assetArtifacts) {
|
|
116
118
|
const manifest = AssetManifest.fromFile(asset.file);
|
|
117
|
-
await publishAssets(manifest, this.deployStackSdkProvider, env.resolvedEnvironment, {
|
|
118
|
-
buildAssets: true,
|
|
119
|
-
allowCrossAccount: true,
|
|
120
|
-
quiet: options.quiet,
|
|
121
|
-
parallel: options.assetParallelism,
|
|
122
|
-
});
|
|
119
|
+
await publishAssets(manifest, this.deployStackSdkProvider, env.resolvedEnvironment, { quiet: options.quiet });
|
|
123
120
|
}
|
|
124
121
|
return deployStack({
|
|
125
122
|
stack: options.stack,
|
|
@@ -152,7 +149,7 @@ export class Deployments {
|
|
|
152
149
|
async rollbackStack(options) {
|
|
153
150
|
let resourcesToSkip = options.orphanLogicalIds ?? [];
|
|
154
151
|
if (options.force && resourcesToSkip.length > 0) {
|
|
155
|
-
throw new
|
|
152
|
+
throw new ToolkitError("Cannot combine --force with --orphan");
|
|
156
153
|
}
|
|
157
154
|
const env = await this.envs.accessStackForMutableStackOperations(options.stack);
|
|
158
155
|
if (options.validateBootstrapStackVersion ?? true) {
|
|
@@ -212,7 +209,7 @@ export class Deployments {
|
|
|
212
209
|
warning(`Stack ${deployName} failed creation and rollback. This state cannot be rolled back. You can recreate this stack by running 'cdk deploy'.`);
|
|
213
210
|
return { notInRollbackableState: true };
|
|
214
211
|
default:
|
|
215
|
-
throw new
|
|
212
|
+
throw new ToolkitError(`Unexpected rollback choice: ${cloudFormationStack.stackStatus.rollbackChoice}`);
|
|
216
213
|
}
|
|
217
214
|
const monitor = options.quiet
|
|
218
215
|
? undefined
|
|
@@ -225,7 +222,7 @@ export class Deployments {
|
|
|
225
222
|
const successStack = await stabilizeStack(cfn, deployName);
|
|
226
223
|
// This shouldn't really happen, but catch it anyway. You never know.
|
|
227
224
|
if (!successStack) {
|
|
228
|
-
throw new
|
|
225
|
+
throw new ToolkitError("Stack deploy failed (the stack disappeared while we were rolling it back)");
|
|
229
226
|
}
|
|
230
227
|
finalStackState = successStack;
|
|
231
228
|
const errors = monitor?.errors?.join(", ");
|
|
@@ -234,7 +231,7 @@ export class Deployments {
|
|
|
234
231
|
}
|
|
235
232
|
}
|
|
236
233
|
catch (e) {
|
|
237
|
-
stackErrorMessage = suffixWithErrors(e
|
|
234
|
+
stackErrorMessage = suffixWithErrors(formatErrorMessage(e), monitor?.errors);
|
|
238
235
|
}
|
|
239
236
|
finally {
|
|
240
237
|
await monitor?.stop();
|
|
@@ -249,9 +246,9 @@ export class Deployments {
|
|
|
249
246
|
// Do another loop-de-loop
|
|
250
247
|
continue;
|
|
251
248
|
}
|
|
252
|
-
throw new
|
|
249
|
+
throw new ToolkitError(`${stackErrorMessage} (fix problem and retry, or orphan these resources using --orphan or --force)`);
|
|
253
250
|
}
|
|
254
|
-
throw new
|
|
251
|
+
throw new ToolkitError("Rollback did not finish after a large number of iterations; stopping because it looks like we're not making progress anymore. You can retry if rollback was progressing as expected.");
|
|
255
252
|
}
|
|
256
253
|
async destroyStack(options) {
|
|
257
254
|
const env = await this.envs.accessStackForMutableStackOperations(options.stack);
|
|
@@ -276,33 +273,6 @@ export class Deployments {
|
|
|
276
273
|
const stack = await CloudFormationStack.lookup(env.sdk.cloudFormation(), options.deployName ?? options.stack.stackName);
|
|
277
274
|
return stack.exists;
|
|
278
275
|
}
|
|
279
|
-
async prepareAndValidateAssets(asset, options) {
|
|
280
|
-
const env = await this.envs.accessStackForMutableStackOperations(options.stack);
|
|
281
|
-
await this.validateBootstrapStackVersion(options.stack.stackName, asset.requiresBootstrapStackVersion, asset.bootstrapStackVersionSsmParameter, env.resources);
|
|
282
|
-
const manifest = AssetManifest.fromFile(asset.file);
|
|
283
|
-
return { manifest, stackEnv: env.resolvedEnvironment };
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Build all assets in a manifest
|
|
287
|
-
*
|
|
288
|
-
* @deprecated Use `buildSingleAsset` instead
|
|
289
|
-
*/
|
|
290
|
-
async buildAssets(asset, options) {
|
|
291
|
-
const { manifest, stackEnv } = await this.prepareAndValidateAssets(asset, options);
|
|
292
|
-
await buildAssets(manifest, this.assetSdkProvider, stackEnv, options.buildOptions);
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Publish all assets in a manifest
|
|
296
|
-
*
|
|
297
|
-
* @deprecated Use `publishSingleAsset` instead
|
|
298
|
-
*/
|
|
299
|
-
async publishAssets(asset, options) {
|
|
300
|
-
const { manifest, stackEnv } = await this.prepareAndValidateAssets(asset, options);
|
|
301
|
-
await publishAssets(manifest, this.assetSdkProvider, stackEnv, {
|
|
302
|
-
...options.publishOptions,
|
|
303
|
-
allowCrossAccount: await this.allowCrossAccountAssetPublishingForEnv(options.stack),
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
276
|
/**
|
|
307
277
|
* Build a single asset from an asset manifest
|
|
308
278
|
*
|
|
@@ -323,17 +293,15 @@ export class Deployments {
|
|
|
323
293
|
/**
|
|
324
294
|
* Publish a single asset from an asset manifest
|
|
325
295
|
*/
|
|
326
|
-
// eslint-disable-next-line max-len
|
|
327
296
|
async publishSingleAsset(assetManifest, asset, options) {
|
|
328
297
|
const stackEnv = await this.envs.resolveStackEnvironment(options.stack);
|
|
329
298
|
// No need to validate anymore, we already did that during build
|
|
330
299
|
const publisher = this.cachedPublisher(assetManifest, stackEnv, options.stackName);
|
|
331
|
-
// eslint-disable-next-line no-console
|
|
332
300
|
await publisher.publishEntry(asset, {
|
|
333
301
|
allowCrossAccount: await this.allowCrossAccountAssetPublishingForEnv(options.stack),
|
|
334
302
|
});
|
|
335
303
|
if (publisher.hasFailures) {
|
|
336
|
-
throw new
|
|
304
|
+
throw new ToolkitError(`Failed to publish asset ${asset.id}`);
|
|
337
305
|
}
|
|
338
306
|
}
|
|
339
307
|
async allowCrossAccountAssetPublishingForEnv(stack) {
|
|
@@ -362,7 +330,7 @@ export class Deployments {
|
|
|
362
330
|
await envResources.validateVersion(requiresBootstrapStackVersion, bootstrapStackVersionSsmParameter);
|
|
363
331
|
}
|
|
364
332
|
catch (e) {
|
|
365
|
-
throw new
|
|
333
|
+
throw new ToolkitError(`${stackName}: ${formatErrorMessage(e)}`);
|
|
366
334
|
}
|
|
367
335
|
}
|
|
368
336
|
cachedPublisher(assetManifest, env, stackName) {
|
|
@@ -399,3 +367,42 @@ class ParallelSafeAssetProgress {
|
|
|
399
367
|
function suffixWithErrors(msg, errors) {
|
|
400
368
|
return errors && errors.length > 0 ? `${msg}: ${errors.join(", ")}` : msg;
|
|
401
369
|
}
|
|
370
|
+
//////////////////////
|
|
371
|
+
// Manually copied over functions
|
|
372
|
+
//////////////////////
|
|
373
|
+
/*
|
|
374
|
+
* Copy over deprecated `publishAssets` from `lib/api/deployments/asset-publishing.ts`
|
|
375
|
+
* to be used in `deployments-wrapper.ts`
|
|
376
|
+
*/
|
|
377
|
+
class PublishingProgressListener {
|
|
378
|
+
constructor() { }
|
|
379
|
+
onPublishEvent(type, event) {
|
|
380
|
+
const handler = EVENT_TO_LOGGER[type];
|
|
381
|
+
handler(`[${event.percentComplete}%] ${type}: ${event.message}`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
export async function publishAssets(manifest, sdk, targetEnv, options) {
|
|
385
|
+
// This shouldn't really happen (it's a programming error), but we don't have
|
|
386
|
+
// the types here to guide us. Do an runtime validation to be super super sure.
|
|
387
|
+
if (targetEnv.account === undefined ||
|
|
388
|
+
targetEnv.account === cxapi.UNKNOWN_ACCOUNT ||
|
|
389
|
+
targetEnv.region === undefined ||
|
|
390
|
+
targetEnv.account === cxapi.UNKNOWN_REGION) {
|
|
391
|
+
throw new ToolkitError(`Asset publishing requires resolved account and region, got ${JSON.stringify(targetEnv)}`);
|
|
392
|
+
}
|
|
393
|
+
const publisher = new cdk_assets.AssetPublishing(manifest, {
|
|
394
|
+
aws: new PublishingAws(sdk, targetEnv),
|
|
395
|
+
progressListener: options.quiet
|
|
396
|
+
? undefined
|
|
397
|
+
: new PublishingProgressListener(),
|
|
398
|
+
throwOnError: false,
|
|
399
|
+
publishInParallel: true,
|
|
400
|
+
buildAssets: true,
|
|
401
|
+
publishAssets: true,
|
|
402
|
+
quiet: options.quiet,
|
|
403
|
+
});
|
|
404
|
+
await publisher.publish({ allowCrossAccount: true });
|
|
405
|
+
if (publisher.hasFailures) {
|
|
406
|
+
throw new ToolkitError("Failed to publish one or more assets. See the error messages above for more information.");
|
|
407
|
+
}
|
|
408
|
+
}
|
package/credentials.js
CHANGED
|
@@ -12,7 +12,7 @@ export const useAWSCredentialsProvider = lazy(() => {
|
|
|
12
12
|
const project = useProject();
|
|
13
13
|
Logger.debug("Using AWS profile", project.config.profile);
|
|
14
14
|
const provider = fromNodeProviderChain({
|
|
15
|
-
|
|
15
|
+
parentClientConfig: { region: project.config.region },
|
|
16
16
|
profile: project.config.profile,
|
|
17
17
|
roleArn: project.config.role,
|
|
18
18
|
mfaCodeProvider: async (serialArn) => {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"sideEffects": false,
|
|
3
3
|
"name": "sst",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.48.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sst": "cli/sst.js"
|
|
7
7
|
},
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://sst.dev",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@aws-cdk/aws-lambda-python-alpha": "2.
|
|
29
|
-
"@aws-cdk/cloud-assembly-schema": "
|
|
30
|
-
"@aws-cdk/cloudformation-diff": "2.
|
|
31
|
-
"@aws-cdk/cx-api": "2.
|
|
28
|
+
"@aws-cdk/aws-lambda-python-alpha": "2.179.0-alpha.0",
|
|
29
|
+
"@aws-cdk/cloud-assembly-schema": "39.2.20",
|
|
30
|
+
"@aws-cdk/cloudformation-diff": "2.179.0",
|
|
31
|
+
"@aws-cdk/cx-api": "2.179.0",
|
|
32
32
|
"@aws-crypto/sha256-js": "^5.2.0",
|
|
33
33
|
"@aws-sdk/client-cloudformation": "^3.454.0",
|
|
34
34
|
"@aws-sdk/client-ecs": "^3.454.0",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"@smithy/signature-v4": "^2.0.16",
|
|
54
54
|
"@trpc/server": "9.16.0",
|
|
55
55
|
"adm-zip": "0.5.14",
|
|
56
|
-
"aws-cdk-lib": "2.
|
|
56
|
+
"aws-cdk-lib": "2.179.0",
|
|
57
57
|
"aws-iot-device-sdk": "^2.2.13",
|
|
58
58
|
"aws-sdk": "^2.1501.0",
|
|
59
59
|
"builtin-modules": "3.2.0",
|
|
60
|
-
"cdk-assets": "
|
|
60
|
+
"cdk-assets": "3.0.0-rc.143",
|
|
61
61
|
"chalk": "^5.2.0",
|
|
62
62
|
"chokidar": "^3.5.3",
|
|
63
63
|
"ci-info": "^3.7.0",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"ora": "^6.1.2",
|
|
86
86
|
"react": "^18.0.0",
|
|
87
87
|
"remeda": "^1.3.0",
|
|
88
|
-
"sst-aws-cdk": "2.
|
|
88
|
+
"sst-aws-cdk": "2.179.0-3",
|
|
89
89
|
"tree-kill": "^1.2.2",
|
|
90
90
|
"undici": "^5.12.0",
|
|
91
91
|
"uuid": "^9.0.0",
|
package/package.json.bak
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
},
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"name": "sst",
|
|
8
|
-
"version": "2.
|
|
8
|
+
"version": "2.48.0",
|
|
9
9
|
"bin": {
|
|
10
10
|
"sst": "cli/sst.js"
|
|
11
11
|
},
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://sst.dev",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@aws-cdk/aws-lambda-python-alpha": "2.
|
|
39
|
-
"@aws-cdk/cloud-assembly-schema": "
|
|
40
|
-
"@aws-cdk/cloudformation-diff": "2.
|
|
41
|
-
"@aws-cdk/cx-api": "2.
|
|
38
|
+
"@aws-cdk/aws-lambda-python-alpha": "2.179.0-alpha.0",
|
|
39
|
+
"@aws-cdk/cloud-assembly-schema": "39.2.20",
|
|
40
|
+
"@aws-cdk/cloudformation-diff": "2.179.0",
|
|
41
|
+
"@aws-cdk/cx-api": "2.179.0",
|
|
42
42
|
"@aws-crypto/sha256-js": "^5.2.0",
|
|
43
43
|
"@aws-sdk/client-cloudformation": "^3.454.0",
|
|
44
44
|
"@aws-sdk/client-ecs": "^3.454.0",
|
|
@@ -63,11 +63,11 @@
|
|
|
63
63
|
"@smithy/signature-v4": "^2.0.16",
|
|
64
64
|
"@trpc/server": "9.16.0",
|
|
65
65
|
"adm-zip": "0.5.14",
|
|
66
|
-
"aws-cdk-lib": "2.
|
|
66
|
+
"aws-cdk-lib": "2.179.0",
|
|
67
67
|
"aws-iot-device-sdk": "^2.2.13",
|
|
68
68
|
"aws-sdk": "^2.1501.0",
|
|
69
69
|
"builtin-modules": "3.2.0",
|
|
70
|
-
"cdk-assets": "
|
|
70
|
+
"cdk-assets": "3.0.0-rc.143",
|
|
71
71
|
"chalk": "^5.2.0",
|
|
72
72
|
"chokidar": "^3.5.3",
|
|
73
73
|
"ci-info": "^3.7.0",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"ora": "^6.1.2",
|
|
96
96
|
"react": "^18.0.0",
|
|
97
97
|
"remeda": "^1.3.0",
|
|
98
|
-
"sst-aws-cdk": "2.
|
|
98
|
+
"sst-aws-cdk": "2.179.0-3",
|
|
99
99
|
"tree-kill": "^1.2.2",
|
|
100
100
|
"undici": "^5.12.0",
|
|
101
101
|
"uuid": "^9.0.0",
|
package/stacks/synth.js
CHANGED
|
@@ -10,7 +10,7 @@ export async function synth(opts) {
|
|
|
10
10
|
Logger.debug("Synthesizing stacks...");
|
|
11
11
|
const { App } = await import("../constructs/App.js");
|
|
12
12
|
const cxapi = await import("@aws-cdk/cx-api");
|
|
13
|
-
const { Configuration } = await import("sst-aws-cdk/lib/
|
|
13
|
+
const { Configuration } = await import("sst-aws-cdk/lib/cli/user-configuration.js");
|
|
14
14
|
const project = useProject();
|
|
15
15
|
const cwd = process.cwd();
|
|
16
16
|
process.chdir(project.paths.root);
|