-
Notifications
You must be signed in to change notification settings - Fork 86
Expand file tree
/
Copy pathindex.ts
More file actions
312 lines (273 loc) · 8.46 KB
/
index.ts
File metadata and controls
312 lines (273 loc) · 8.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
import * as path from 'path';
import type * as cxapi from '@aws-cdk/cloud-assembly-api';
import { environmentsFromDescriptors } from './private';
import type { ICloudAssemblySource } from '../../api/cloud-assembly';
import { ALL_STACKS } from '../../api/cloud-assembly/private';
import type { IIoHost } from '../../api/io';
import { asIoHelper } from '../../api/io/private';
import type { Tag } from '../../api/tags';
import { assemblyFromSource } from '../../toolkit/private';
import { bundledPackageRootDir, loadStructuredFile, serializeStructure } from '../../util';
/**
* Create manage bootstrap environments
*/
export class BootstrapEnvironments {
/**
* Create from a list of environment descriptors
* List of strings like `['aws://012345678912/us-east-1', 'aws://234567890123/eu-west-1']`
*/
static fromList(environments: string[]): BootstrapEnvironments {
return new BootstrapEnvironments(environmentsFromDescriptors(environments));
}
/**
* Create from a cloud assembly source
*/
static fromCloudAssemblySource(cx: ICloudAssemblySource): BootstrapEnvironments {
return new BootstrapEnvironments(async (ioHost: IIoHost) => {
const ioHelper = asIoHelper(ioHost, 'bootstrap');
await using assembly = await assemblyFromSource(ioHelper, cx);
const stackCollection = await assembly.selectStacksV2(ALL_STACKS);
return stackCollection.stackArtifacts.map(stack => stack.environment);
});
}
private constructor(private readonly envProvider: cxapi.Environment[] | ((ioHost: IIoHost) => Promise<cxapi.Environment[]>)) {
}
/**
* Compute the bootstrap enviornments
*
* @internal
*/
async getEnvironments(ioHost: IIoHost): Promise<cxapi.Environment[]> {
if (Array.isArray(this.envProvider)) {
return this.envProvider;
}
return this.envProvider(ioHost);
}
}
/**
* Options for Bootstrap
*/
export interface BootstrapOptions {
/**
* Bootstrap environment parameters for CloudFormation used when deploying the bootstrap stack
* @default BootstrapEnvironmentParameters.onlyExisting()
*/
readonly parameters?: BootstrapStackParameters;
/**
* The template source of the bootstrap stack
*
* @default BootstrapSource.default()
*/
readonly source?: { source: 'default' } | { source: 'custom'; templateFile: string };
/**
* Whether to execute the changeset or only create it and leave it in review
* @default true
*/
readonly execute?: boolean;
/**
* Tags for cdktoolkit stack
*
* @default []
*/
readonly tags?: Tag[];
/**
* Whether the stacks created by the bootstrap process should be protected from termination
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-protect-stacks.html
* @default true
*/
readonly terminationProtection?: boolean;
/**
* Whether to force deployment if a bootstrap stack already exists
* @default false
*/
readonly forceDeployment?: boolean;
}
/**
* Parameter values for the bootstrapping template
*/
export interface BootstrapParameters {
/**
* The name to be given to the CDK Bootstrap bucket
* By default, a name is generated by CloudFormation
*
* @default - No value, optional argument
*/
readonly bucketName?: string;
/**
* The ID of an existing KMS key to be used for encrypting items in the bucket
* By default, the default KMS key is used
*
* @default - No value, optional argument
*/
readonly kmsKeyId?: string;
/**
* Whether or not to create a new customer master key (CMK)
*
* Only applies to modern bootstrapping
* Legacy bootstrapping will never create a CMK, only use the default S3 key
*
* @default false
*/
readonly createCustomerMasterKey?: boolean;
/**
* The list of AWS account IDs that are trusted to deploy into the environment being bootstrapped
*
* @default []
*/
readonly trustedAccounts?: string[];
/**
* The list of AWS account IDs that are trusted to look up values in the environment being bootstrapped
*
* @default []
*/
readonly trustedAccountsForLookup?: string[];
/**
* The list of AWS account IDs that should not be trusted by the bootstrapped environment
* If these accounts are already trusted, they will be removed on bootstrapping
*
* @default []
*/
readonly untrustedAccounts?: string[];
/**
* The ARNs of the IAM managed policies that should be attached to the role performing CloudFormation deployments
* In most cases, this will be the AdministratorAccess policy
* At least one policy is required if `trustedAccounts` were passed
*
* @default []
*/
readonly cloudFormationExecutionPolicies?: string[];
/**
* Identifier to distinguish multiple bootstrapped environments
* The default qualifier is an arbitrary but unique string
*
* @default 'hnb659fds'
*/
readonly qualifier?: string;
/**
* Whether or not to enable S3 Staging Bucket Public Access Block Configuration
*
* @default true
*/
readonly publicAccessBlockConfiguration?: boolean;
/**
* Flag for using the default permissions boundary for bootstrapping
*
* @default - No value, optional argument
*/
readonly examplePermissionsBoundary?: boolean;
/**
* Name for the customer's custom permissions boundary for bootstrapping
*
* @default - No value, optional argument
*/
readonly customPermissionsBoundary?: string;
/**
* Whether to apply the permissions boundary to all bootstrap roles
* (not just the CloudFormation execution role)
*
* @default false
*/
readonly permissionsBoundaryAllRoles?: boolean;
}
export interface EnvironmentBootstrapResult {
environment: cxapi.Environment;
status: 'success' | 'no-op';
duration: number;
}
export interface BootstrapResult {
environments: EnvironmentBootstrapResult[];
duration: number;
}
/**
* Parameters of the bootstrapping template with flexible configuration options
*/
export class BootstrapStackParameters {
/**
* Use only existing parameters on the stack.
*/
public static onlyExisting() {
return new BootstrapStackParameters({}, true);
}
/**
* Use exactly these parameters and remove any other existing parameters from the stack.
*/
public static exactly(params: BootstrapParameters) {
return new BootstrapStackParameters(params, false);
}
/**
* Define additional parameters for the stack, while keeping existing parameters for unspecified values.
*/
public static withExisting(params: BootstrapParameters) {
return new BootstrapStackParameters(params, true);
}
/**
* The parameters as a Map for easy access and manipulation
*/
public readonly parameters?: BootstrapParameters;
public readonly keepExistingParameters: boolean;
private constructor(params?: BootstrapParameters, usePreviousParameters = true) {
this.keepExistingParameters = usePreviousParameters;
this.parameters = params;
}
}
/**
* Source configuration for bootstrap operations
*/
export class BootstrapSource {
/**
* Use the default bootstrap template
*/
static default(): BootstrapOptions['source'] {
return { source: 'default' };
}
/**
* Use a custom bootstrap template
*/
static customTemplate(templateFile: string): BootstrapOptions['source'] {
return {
source: 'custom',
templateFile,
};
}
}
/**
* Represents a bootstrap template that can be serialized to YAML or JSON
*/
export class BootstrapTemplate {
/**
* Load a bootstrap template from a source
*
* @param source - The bootstrap template source configuration
* @returns A BootstrapTemplate instance
*/
static async fromSource(source: BootstrapOptions['source'] = { source: 'default' }): Promise<BootstrapTemplate> {
let template: any;
switch (source.source) {
case 'custom':
template = await loadStructuredFile(source.templateFile);
break;
case 'default':
template = await loadStructuredFile(path.join(bundledPackageRootDir(__dirname), 'lib', 'api', 'bootstrap', 'bootstrap-template.yaml'));
break;
}
return new BootstrapTemplate(template);
}
private constructor(private readonly template: any) {
}
/**
* Serialize the template as YAML
*
* @returns The template as a YAML string
*/
public asYAML(): string {
return serializeStructure(this.template, false);
}
/**
* Serialize the template as JSON
*
* @returns The template as a JSON string
*/
public asJSON(): string {
return serializeStructure(this.template, true);
}
}