Skip to content

Commit 8577876

Browse files
committed
feat(toolkit): add a return type for toolkit.deploy()
`toolkit.deploy()` now returns information about the stacks it deployed.
1 parent 3e8359c commit 8577876

File tree

16 files changed

+607
-8
lines changed

16 files changed

+607
-8
lines changed

packages/@aws-cdk/cloud-assembly-schema/lib/cloud-assembly/schema.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,12 @@ export interface ArtifactManifest {
100100
readonly properties?: ArtifactProperties;
101101

102102
/**
103-
* A string that represents this artifact. Should only be used in user interfaces.
103+
* A string that can be shown to a user to uniquely identify this artifact inside a cloud assembly tree
104+
*
105+
* Is used by the CLI to present a list of stacks to the user in a way that
106+
* makes sense to them. Even though the property name "display name" doesn't
107+
* imply it, this field is used to select stacks as well, so all stacks should
108+
* have a unique display name.
104109
*
105110
* @default - no display name
106111
*/

packages/@aws-cdk/cloud-assembly-schema/schema/cloud-assembly.schema.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
]
8484
},
8585
"displayName": {
86-
"description": "A string that represents this artifact. Should only be used in user interfaces. (Default - no display name)",
86+
"description": "A string that can be shown to a user to uniquely identify this artifact inside a cloud assembly tree\n\nIs used by the CLI to present a list of stacks to the user in a way that\nmakes sense to them. Even though the property name \"display name\" doesn't\nimply it, this field is used to select stacks as well, so all stacks should\nhave a unique display name. (Default - no display name)",
8787
"type": "string"
8888
}
8989
},
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"schemaHash": "78936b0f9299bbe47497dd77f8065d71e65d8d739a0413ad7698ad03b22ef83e",
2+
"schemaHash": "96958a4c40e0a00e850f0c14dd6e9c0fc8db0b075f1f155cea41ab198c0514be",
33
"revision": 43
4-
}
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './toolkit';
2+
export * from './types';
23
export * from '../api/shared-public';

packages/@aws-cdk/toolkit-lib/lib/toolkit/toolkit.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as fs from 'fs-extra';
66
import * as uuid from 'uuid';
77
import type { ToolkitServices } from './private';
88
import { assemblyFromSource } from './private';
9+
import type { DeployResult } from './types';
910
import type { BootstrapEnvironments, BootstrapOptions, BootstrapResult, EnvironmentBootstrapResult } from '../actions/bootstrap';
1011
import { BootstrapSource } from '../actions/bootstrap';
1112
import { AssetBuildTime, type DeployOptions } from '../actions/deploy';
@@ -421,7 +422,7 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
421422
*
422423
* Deploys the selected stacks into an AWS account
423424
*/
424-
public async deploy(cx: ICloudAssemblySource, options: DeployOptions = {}): Promise<void> {
425+
public async deploy(cx: ICloudAssemblySource, options: DeployOptions = {}): Promise<DeployResult> {
425426
const ioHelper = asIoHelper(this.ioHost, 'deploy');
426427
const assembly = await assemblyFromSource(ioHelper, cx);
427428
return this._deploy(assembly, 'deploy', options);
@@ -430,17 +431,21 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
430431
/**
431432
* Helper to allow deploy being called as part of the watch action.
432433
*/
433-
private async _deploy(assembly: StackAssembly, action: 'deploy' | 'watch', options: ExtendedDeployOptions = {}) {
434+
private async _deploy(assembly: StackAssembly, action: 'deploy' | 'watch', options: ExtendedDeployOptions = {}): Promise<DeployResult> {
434435
const ioHelper = asIoHelper(this.ioHost, action);
435436
const selectStacks = options.stacks ?? ALL_STACKS;
436437
const synthSpan = await ioHelper.span(SPAN.SYNTH_ASSEMBLY).begin({ stacks: selectStacks });
437438
const stackCollection = await assembly.selectStacksV2(selectStacks);
438439
await this.validateStacksMetadata(stackCollection, ioHelper);
439440
const synthDuration = await synthSpan.end();
440441

442+
const ret: DeployResult = {
443+
stacks: [],
444+
};
445+
441446
if (stackCollection.stackCount === 0) {
442447
await ioHelper.notify(IO.CDK_TOOLKIT_E5001.msg('This app contains no stacks'));
443-
return;
448+
return ret;
444449
}
445450

446451
const deployments = await this.deploymentsForAction('deploy');
@@ -673,6 +678,17 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
673678
await ioHelper.notify(IO.CDK_TOOLKIT_I5901.msg(buffer.join('\n')));
674679
}
675680
await ioHelper.notify(IO.CDK_TOOLKIT_I5901.msg(`Stack ARN:\n${deployResult.stackArn}`));
681+
682+
ret.stacks.push({
683+
stackName: stack.stackName,
684+
environment: {
685+
account: stack.environment.account,
686+
region: stack.environment.region,
687+
},
688+
stackArn: deployResult.stackArn,
689+
outputs: deployResult.outputs,
690+
hierarchicalId: stack.hierarchicalId,
691+
});
676692
} catch (e: any) {
677693
// It has to be exactly this string because an integration test tests for
678694
// "bold(stackname) failed: ResourceNotReady: <error>"
@@ -733,6 +749,8 @@ export class Toolkit extends CloudAssemblySourceBuilder implements AsyncDisposab
733749
buildAsset,
734750
publishAsset,
735751
});
752+
753+
return ret;
736754
}
737755

738756
/**
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Result interface for toolkit.deploy operation
3+
*/
4+
export interface DeployResult {
5+
/**
6+
* Map of deployed stacks by artifact ID.
7+
*/
8+
readonly stacks: DeployedStack[];
9+
}
10+
11+
/**
12+
* Information about a deployed stack
13+
*/
14+
export interface DeployedStack {
15+
/**
16+
* The name of the deployed stack
17+
*
18+
* A stack name is unique inside its environment, but not unique globally.
19+
*/
20+
readonly stackName: string;
21+
22+
/**
23+
* The environment where the stack was deployed
24+
*
25+
* This environment is always concrete, because even though the CDK app's
26+
* stack may be region-agnostic, in order to be deployed it will have to have
27+
* been specialized.
28+
*/
29+
readonly environment: Environment;
30+
31+
/**
32+
* Hierarchical identifier
33+
*
34+
* This uniquely identifies the stack inside the CDK app.
35+
*
36+
* In practice this will be the stack's construct path, but unfortunately the
37+
* Cloud Assembly contract doesn't require or guarantee that.
38+
*/
39+
readonly hierarchicalId: string;
40+
41+
/**
42+
* The ARN of the deployed stack
43+
*/
44+
readonly stackArn: string;
45+
46+
/**
47+
* The outputs of the deployed CloudFormation stack
48+
*/
49+
readonly outputs: { [key: string]: string };
50+
}
51+
52+
/**
53+
* An environment, which is an (account, region) pair
54+
*/
55+
export interface Environment {
56+
/**
57+
* The account number
58+
*/
59+
readonly account: string;
60+
61+
/**
62+
* The region number
63+
*/
64+
readonly region: string;
65+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as cdk from 'aws-cdk-lib/core';
2+
3+
const app = new cdk.App({ autoSynth: false });
4+
const stage = new cdk.Stage(app, 'Stage');
5+
new cdk.Stack(stage, 'Stack1');
6+
7+
app.synth();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"app": "$(npx -c 'which tsx') app.ts"
3+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "40.0.0",
3+
"files": {
4+
"7f4fb64a3afca08edbdbaa369e00317cb253697278406a83c78e849e89045f9d": {
5+
"source": {
6+
"path": "StageStack130339B27.template.json",
7+
"packaging": "file"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "7f4fb64a3afca08edbdbaa369e00317cb253697278406a83c78e849e89045f9d.json",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
}
17+
},
18+
"dockerImages": {}
19+
}

0 commit comments

Comments
 (0)