@fjall/components-infrastructure 0.95.0 → 0.96.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/lib/app.d.ts +25 -109
- package/dist/lib/app.js +37 -136
- package/dist/lib/patterns/aws/account.js +5 -4
- package/dist/lib/patterns/aws/computeEcs.d.ts +8 -397
- package/dist/lib/patterns/aws/computeEcs.js +13 -9
- package/dist/lib/patterns/aws/computeEcsTypes.d.ts +386 -0
- package/dist/lib/patterns/aws/computeEcsTypes.js +2 -0
- package/dist/lib/patterns/aws/domain.js +4 -5
- package/dist/lib/patterns/aws/index.d.ts +2 -0
- package/dist/lib/patterns/aws/index.js +2 -0
- package/dist/lib/patterns/aws/interfaces/compute.d.ts +6 -0
- package/dist/lib/patterns/aws/interfaces/connector.d.ts +1 -1
- package/dist/lib/patterns/aws/interfaces/connector.js +1 -1
- package/dist/lib/patterns/aws/interfaces/index.d.ts +2 -1
- package/dist/lib/patterns/aws/interfaces/index.js +1 -1
- package/dist/lib/patterns/aws/interfaces/vpcPeer.d.ts +7 -0
- package/dist/lib/patterns/aws/interfaces/vpcPeer.js +1 -0
- package/dist/lib/patterns/aws/organisation.js +2 -1
- package/dist/lib/patterns/aws/vpcPeer.d.ts +34 -0
- package/dist/lib/patterns/aws/vpcPeer.js +36 -0
- package/dist/lib/patterns/aws/vpcPeerAccepter.d.ts +29 -0
- package/dist/lib/patterns/aws/vpcPeerAccepter.js +196 -0
- package/dist/lib/resources/aws/analytics/clickhouse.js +10 -1
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.d.ts +34 -0
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.js +89 -0
- package/dist/lib/resources/aws/analytics/clickhouseConstants.d.ts +1 -1
- package/dist/lib/resources/aws/analytics/clickhouseConstants.js +3 -1
- package/dist/lib/resources/aws/analytics/clickhouseTypes.d.ts +6 -0
- package/dist/lib/resources/aws/analytics/clickhouseUserData.d.ts +1 -0
- package/dist/lib/resources/aws/analytics/clickhouseUserData.js +3 -2
- package/dist/lib/resources/aws/analytics/index.d.ts +2 -0
- package/dist/lib/resources/aws/analytics/index.js +1 -0
- package/dist/lib/resources/aws/compute/ecsRemoteConnections.d.ts +38 -0
- package/dist/lib/resources/aws/compute/ecsRemoteConnections.js +80 -0
- package/dist/lib/resources/aws/compute/ecsTaskDefinition.js +8 -0
- package/dist/lib/resources/aws/compute/ecsTypes.d.ts +7 -0
- package/dist/lib/resources/aws/iam/delegationRole.js +11 -4
- package/dist/lib/resources/aws/networking/crossAccountDelegationRecord.js +2 -1
- package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.d.ts +40 -0
- package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.js +154 -0
- package/dist/lib/resources/aws/networking/dnsRecord/dnsRecordBase.js +2 -1
- package/dist/lib/resources/aws/networking/domainCertificate.js +2 -1
- package/dist/lib/resources/aws/networking/hostedZone.js +2 -1
- package/dist/lib/resources/aws/networking/index.d.ts +3 -0
- package/dist/lib/resources/aws/networking/index.js +3 -0
- package/dist/lib/resources/aws/networking/vpc.js +6 -2
- package/dist/lib/resources/aws/networking/vpcPeeringAccepterRole.d.ts +18 -0
- package/dist/lib/resources/aws/networking/vpcPeeringAccepterRole.js +61 -0
- package/dist/lib/resources/aws/networking/vpcPeeringConnection.d.ts +49 -0
- package/dist/lib/resources/aws/networking/vpcPeeringConnection.js +88 -0
- package/dist/lib/utils/bastionFactory.d.ts +10 -0
- package/dist/lib/utils/bastionFactory.js +29 -0
- package/dist/lib/utils/capitaliseString.d.ts +1 -1
- package/dist/lib/utils/capitaliseString.js +1 -1
- package/dist/lib/utils/cdkContext.d.ts +8 -0
- package/dist/lib/utils/cdkContext.js +11 -0
- package/dist/lib/utils/connections.d.ts +7 -1
- package/dist/lib/utils/connections.js +15 -0
- package/dist/lib/utils/connector.d.ts +18 -2
- package/dist/lib/utils/connector.js +6 -1
- package/dist/lib/utils/costAllocationTags.d.ts +6 -0
- package/dist/lib/utils/costAllocationTags.js +6 -0
- package/dist/lib/utils/index.d.ts +3 -0
- package/dist/lib/utils/index.js +3 -0
- package/dist/lib/utils/vpcPeerInterface.d.ts +22 -0
- package/dist/lib/utils/vpcPeerInterface.js +1 -0
- package/package.json +4 -3
package/dist/lib/app.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ import { type Ecr } from "./resources/aws/storage/ecr.js";
|
|
|
8
8
|
import { type AnyDatabase } from "./patterns/aws/database.js";
|
|
9
9
|
import { type INetworkProps, type Network } from "./patterns/aws/network.js";
|
|
10
10
|
import { type Cdn } from "./patterns/aws/cdn.js";
|
|
11
|
+
import { type VpcPeer } from "./patterns/aws/vpcPeer.js";
|
|
12
|
+
import { type VpcPeerAccepter } from "./patterns/aws/vpcPeerAccepter.js";
|
|
11
13
|
import { type AnyMessaging } from "./patterns/aws/messaging.js";
|
|
12
14
|
import { type AnyCompute } from "./patterns/aws/compute.js";
|
|
13
15
|
import { type Storage, type StorageFactoryFn } from "./patterns/aws/storage.js";
|
|
@@ -85,63 +87,19 @@ export declare class App extends CdkApp {
|
|
|
85
87
|
private resourceInventory?;
|
|
86
88
|
private manifestCollector;
|
|
87
89
|
private constructor();
|
|
88
|
-
/**
|
|
89
|
-
* Apply backup tier tag to all resources in the app.
|
|
90
|
-
* Maps tier names to AWS Backup plan tag values.
|
|
91
|
-
*/
|
|
92
90
|
private applyBackupTag;
|
|
93
|
-
/**
|
|
94
|
-
* Initialise the tunnel bastion in the network stack.
|
|
95
|
-
* Creates a minimal EC2 instance for SSM port forwarding to databases.
|
|
96
|
-
*/
|
|
97
91
|
private initialiseTunnel;
|
|
98
|
-
/**
|
|
99
|
-
* Initialise the network (VPC) for this application.
|
|
100
|
-
*/
|
|
101
92
|
private initialiseNetwork;
|
|
102
|
-
/**
|
|
103
|
-
* Get the application name.
|
|
104
|
-
* @returns {string} The application name
|
|
105
|
-
*/
|
|
106
93
|
getName(): string;
|
|
107
|
-
/**
|
|
108
|
-
* Get/Create a basic Fjall Application with standard tags applied.
|
|
109
|
-
*
|
|
110
|
-
* @param name Application name
|
|
111
|
-
* @param options Configuration options including network settings
|
|
112
|
-
* @returns {App}
|
|
113
|
-
*
|
|
114
|
-
* @example
|
|
115
|
-
* // Create app with new VPC
|
|
116
|
-
* const app = App.getApp(appName, {
|
|
117
|
-
* network: { maxAzs: 2, natGateways: false }
|
|
118
|
-
* });
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* // Create app using existing VPC
|
|
122
|
-
* const app = App.getApp(appName, {
|
|
123
|
-
* network: { useExisting: "vpc-12345678" }
|
|
124
|
-
* });
|
|
125
|
-
*
|
|
126
|
-
* @example
|
|
127
|
-
* // Create app without network (S3-only apps)
|
|
128
|
-
* const app = App.getApp(appName, { network: false });
|
|
129
|
-
*/
|
|
130
94
|
static getApp(name?: string, options?: IAppOptions): App;
|
|
131
|
-
/**
|
|
132
|
-
* Get/Create the singleton instance of the App
|
|
133
|
-
* @param name Application name
|
|
134
|
-
* @param options Configuration options including network settings
|
|
135
|
-
* @returns {App}
|
|
136
|
-
*/
|
|
137
95
|
static getInstance(name?: string, options?: IAppOptions): App;
|
|
96
|
+
static resetForTesting(): void;
|
|
138
97
|
/**
|
|
139
98
|
* Retrieve a stack by key. If the stack does not exist, it will be created.
|
|
140
99
|
* Dependencies are only applied the first time a stack is created.
|
|
141
100
|
*
|
|
142
101
|
* @param key - The key of the stack
|
|
143
102
|
* @param dependencies - The stack(s) that this stack depends on
|
|
144
|
-
* @returns {AwsStack}
|
|
145
103
|
*/
|
|
146
104
|
getStack(key: string, dependencies?: AwsStack | AwsStack[]): AwsStack;
|
|
147
105
|
/**
|
|
@@ -149,23 +107,18 @@ export declare class App extends CdkApp {
|
|
|
149
107
|
*
|
|
150
108
|
* Only depends on Network. Database dependency is added automatically
|
|
151
109
|
* by CDK when compute resources reference database resources.
|
|
152
|
-
*
|
|
153
|
-
* @returns {AwsStack}
|
|
154
110
|
*/
|
|
155
111
|
getDefaultComputeStack(): AwsStack;
|
|
156
112
|
/**
|
|
157
113
|
* Retrieve default network stack - named as `${this.name}Network`
|
|
158
|
-
* @returns {AwsStack}
|
|
159
114
|
*/
|
|
160
115
|
getDefaultNetworkStack(): AwsStack;
|
|
161
116
|
/**
|
|
162
117
|
* Retrieve default database stack - named as `${this.name}Database`
|
|
163
|
-
* @returns {AwsStack}
|
|
164
118
|
*/
|
|
165
119
|
getDefaultDatabaseStack(): AwsStack;
|
|
166
120
|
/**
|
|
167
121
|
* Retrieve default storage stack - named as `${this.name}Storage`
|
|
168
|
-
* @returns {AwsStack}
|
|
169
122
|
*/
|
|
170
123
|
getDefaultStorageStack(): AwsStack;
|
|
171
124
|
/**
|
|
@@ -173,8 +126,6 @@ export declare class App extends CdkApp {
|
|
|
173
126
|
*
|
|
174
127
|
* Depends on Network. Compute/Storage dependencies are added automatically
|
|
175
128
|
* by CDK when CDN resources reference ALB or S3 bucket resources.
|
|
176
|
-
*
|
|
177
|
-
* @returns {AwsStack}
|
|
178
129
|
*/
|
|
179
130
|
getDefaultCdnStack(): AwsStack;
|
|
180
131
|
/**
|
|
@@ -183,8 +134,6 @@ export declare class App extends CdkApp {
|
|
|
183
134
|
* Used for SQS queues, SNS topics, and EventBridge event buses.
|
|
184
135
|
* Depends on Network only. These are regional services that don't
|
|
185
136
|
* require VPC, but we maintain consistent stack dependency patterns.
|
|
186
|
-
*
|
|
187
|
-
* @returns {AwsStack}
|
|
188
137
|
*/
|
|
189
138
|
getDefaultMessagingStack(): AwsStack;
|
|
190
139
|
/**
|
|
@@ -194,20 +143,10 @@ export declare class App extends CdkApp {
|
|
|
194
143
|
* Network must be configured via App.getApp() options or app.addNetwork().
|
|
195
144
|
*
|
|
196
145
|
* @param name - Optional name of the VPC to retrieve. If not provided, returns the default VPC.
|
|
197
|
-
* @returns {IVpc} The configured VPC
|
|
198
146
|
* @throws {Error} If network is disabled, not configured, or named VPC not found
|
|
199
147
|
*/
|
|
200
148
|
getVpc(name?: string): IVpc;
|
|
201
|
-
/**
|
|
202
|
-
* Get the names of all available VPCs.
|
|
203
|
-
*
|
|
204
|
-
* @returns {string[]} Array of VPC names. Includes "default" if the default VPC is configured.
|
|
205
|
-
*/
|
|
206
149
|
getVpcNames(): string[];
|
|
207
|
-
/**
|
|
208
|
-
* Retrieve the default application container registry. If the registry does not exist
|
|
209
|
-
* it will be created.
|
|
210
|
-
*/
|
|
211
150
|
getDefaultContainerRegistry(): Ecr;
|
|
212
151
|
/**
|
|
213
152
|
* Create a cross-account audit role in the Network stack that allows
|
|
@@ -218,18 +157,9 @@ export declare class App extends CdkApp {
|
|
|
218
157
|
*
|
|
219
158
|
* @param webappAccountId - Optional AWS account ID of the Fjall webapp. Defaults to configured platform account.
|
|
220
159
|
* @param externalId - Optional external ID for additional security. If not provided, a unique ID will be generated.
|
|
221
|
-
* @returns {Role} The created audit role
|
|
222
160
|
*/
|
|
223
161
|
createAuditRole(webappAccountId?: string, externalId?: string): Role;
|
|
224
|
-
/**
|
|
225
|
-
* Get the external ID used for the audit role
|
|
226
|
-
* @returns {string | undefined} The external ID if audit role has been created
|
|
227
|
-
*/
|
|
228
162
|
getAuditRoleExternalId(): string | undefined;
|
|
229
|
-
/**
|
|
230
|
-
* Generate a unique external ID for audit role
|
|
231
|
-
* Format: fjall-audit-{appName}-{timestamp}
|
|
232
|
-
*/
|
|
233
163
|
private generateAuditExternalId;
|
|
234
164
|
/**
|
|
235
165
|
* Add a compute resource to the default compute stack using the factory pattern.
|
|
@@ -255,10 +185,7 @@ export declare class App extends CdkApp {
|
|
|
255
185
|
* }));
|
|
256
186
|
* worker.getFunction("process"); // Available on LambdaCompute
|
|
257
187
|
*/
|
|
258
|
-
addCompute<T extends AnyCompute>(fn: (app: App, scope: Construct) => T): T;
|
|
259
|
-
/**
|
|
260
|
-
* Manually add a resource to the default compute stack.
|
|
261
|
-
*/
|
|
188
|
+
addCompute<T extends AnyCompute & Construct>(fn: (app: App, scope: Construct) => T): T;
|
|
262
189
|
addComputeResource(resource: Construct): void;
|
|
263
190
|
/**
|
|
264
191
|
* Add a database resource to the default database stack using the factory pattern.
|
|
@@ -280,10 +207,7 @@ export declare class App extends CdkApp {
|
|
|
280
207
|
* }));
|
|
281
208
|
* cache.getTableName(); // Available
|
|
282
209
|
*/
|
|
283
|
-
addDatabase<T extends AnyDatabase>(fn: (app: App, scope: Construct) => T): T;
|
|
284
|
-
/**
|
|
285
|
-
* Type guard for IConnectable — checks if a construct has a connections property.
|
|
286
|
-
*/
|
|
210
|
+
addDatabase<T extends AnyDatabase & Construct>(fn: (app: App, scope: Construct) => T): T;
|
|
287
211
|
private isConnectable;
|
|
288
212
|
/**
|
|
289
213
|
* Add a storage resource (S3) to the default storage stack using the factory pattern.
|
|
@@ -322,6 +246,22 @@ export declare class App extends CdkApp {
|
|
|
322
246
|
* }));
|
|
323
247
|
*/
|
|
324
248
|
addCdn(fn: (app: App, scope: Construct) => Cdn): Cdn;
|
|
249
|
+
/**
|
|
250
|
+
* Peer this app's VPC with a remote app's VPC.
|
|
251
|
+
*
|
|
252
|
+
* Creates the peering connection plus routes on both sides. The remote app
|
|
253
|
+
* must have deployed a `VpcPeerAccepter` first. Note: `app.getVpc(peerAppName)`
|
|
254
|
+
* does NOT return the peer's VPC — callers wanting the remote handle must use
|
|
255
|
+
* the returned `VpcPeer` instance.
|
|
256
|
+
*/
|
|
257
|
+
addVpcPeer(fn: (app: App, scope: Construct) => VpcPeer): VpcPeer;
|
|
258
|
+
/**
|
|
259
|
+
* Accept VPC peering requests from remote apps.
|
|
260
|
+
*
|
|
261
|
+
* Creates an IAM role for cross-account peering acceptance and return-route
|
|
262
|
+
* management, and publishes VPC metadata to SSM for discovery.
|
|
263
|
+
*/
|
|
264
|
+
addVpcPeerAccepter(fn: (app: App, scope: Construct) => VpcPeerAccepter): VpcPeerAccepter;
|
|
325
265
|
/**
|
|
326
266
|
* Add a messaging resource to the default queue stack using the factory pattern.
|
|
327
267
|
*
|
|
@@ -347,7 +287,7 @@ export declare class App extends CdkApp {
|
|
|
347
287
|
* contentBasedDeduplication: true
|
|
348
288
|
* }));
|
|
349
289
|
*/
|
|
350
|
-
addMessaging<T extends AnyMessaging>(fn: (app: App, scope: Construct) => T): T;
|
|
290
|
+
addMessaging<T extends AnyMessaging & Construct>(fn: (app: App, scope: Construct) => T): T;
|
|
351
291
|
/**
|
|
352
292
|
* Add a high-level infrastructure pattern to the application.
|
|
353
293
|
*
|
|
@@ -375,7 +315,7 @@ export declare class App extends CdkApp {
|
|
|
375
315
|
* payload.getServer().getLambdaFunction().addEnvironment("CUSTOM", "value");
|
|
376
316
|
* payload.getCdn().getDistribution().addBehavior("/custom/*", customOrigin);
|
|
377
317
|
*/
|
|
378
|
-
addPattern<T extends AnyPattern>(fn: (app: App, scope: Construct) => T): T;
|
|
318
|
+
addPattern<T extends AnyPattern & Construct>(fn: (app: App, scope: Construct) => T): T;
|
|
379
319
|
/**
|
|
380
320
|
* Add an additional network (VPC) to the application.
|
|
381
321
|
*
|
|
@@ -383,7 +323,6 @@ export declare class App extends CdkApp {
|
|
|
383
323
|
* Additional VPCs can be retrieved by name using app.getVpc(name).
|
|
384
324
|
*
|
|
385
325
|
* @param fn - Factory function that creates the Network construct
|
|
386
|
-
* @returns {Network} The created Network construct
|
|
387
326
|
*
|
|
388
327
|
* @example
|
|
389
328
|
* const isolatedVpc = app.addNetwork(
|
|
@@ -391,21 +330,9 @@ export declare class App extends CdkApp {
|
|
|
391
330
|
* );
|
|
392
331
|
*/
|
|
393
332
|
addNetwork(fn: (app: App, scope: Construct) => Network): Network;
|
|
394
|
-
/**
|
|
395
|
-
* Manually add a resource to the default database stack.
|
|
396
|
-
*/
|
|
397
333
|
addDatabaseResource(resource: Construct): void;
|
|
398
|
-
/**
|
|
399
|
-
* Manually add a resource to the default storage stack.
|
|
400
|
-
*/
|
|
401
334
|
addStorageResource(resource: Construct): void;
|
|
402
|
-
/**
|
|
403
|
-
* Initialise standard tags
|
|
404
|
-
*/
|
|
405
335
|
private initialiseStandardTags;
|
|
406
|
-
/**
|
|
407
|
-
* Apply all tags using CDK's native Tags.of().add() API
|
|
408
|
-
*/
|
|
409
336
|
private applyTagsAspect;
|
|
410
337
|
/**
|
|
411
338
|
* Add custom tags to all resources in the app.
|
|
@@ -414,27 +341,16 @@ export declare class App extends CdkApp {
|
|
|
414
341
|
* @example
|
|
415
342
|
* app.addTags({
|
|
416
343
|
* "fjall:costAllocation:owner": "platform-team",
|
|
417
|
-
* "fjall:costAllocation:cost-
|
|
344
|
+
* "fjall:costAllocation:cost-centre": "CC-123",
|
|
418
345
|
* "team:slack-channel": "#platform-alerts"
|
|
419
346
|
* });
|
|
420
347
|
*/
|
|
421
348
|
addTags(tags: {
|
|
422
349
|
[key: string]: string;
|
|
423
350
|
}): App;
|
|
424
|
-
/**
|
|
425
|
-
* Export resource inventory collected during synthesis
|
|
426
|
-
* Call this after app.synth() to get complete resource inventory
|
|
427
|
-
* @returns {ResourceInventory} Complete inventory of all resources in the app
|
|
428
|
-
*/
|
|
351
|
+
/** Call after app.synth() — inventory is not available before synthesis. */
|
|
429
352
|
exportResourceInventory(): ResourceInventory;
|
|
430
|
-
/**
|
|
431
|
-
* Get the manifest collector for registering services and patterns.
|
|
432
|
-
* Used by ComputeFactory and PatternFactory to register their configurations.
|
|
433
|
-
*/
|
|
434
353
|
getManifestCollector(): ManifestCollector;
|
|
435
|
-
/**
|
|
436
|
-
* Override synth to automatically export resource inventory and manifest
|
|
437
|
-
*/
|
|
438
354
|
synth(options?: StageSynthesisOptions): CloudAssembly;
|
|
439
355
|
}
|
|
440
356
|
export default App;
|
package/dist/lib/app.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { App as CdkApp, Aspects, Tags } from "aws-cdk-lib";
|
|
2
2
|
import { Vpc } from "./resources/aws/networking/vpc.js";
|
|
3
|
-
import {
|
|
4
|
-
import { Ec2Instance } from "./resources/aws/compute/ec2.js";
|
|
3
|
+
import { createBastion } from "./utils/bastionFactory.js";
|
|
5
4
|
import { AwsStack } from "./resources/index.js";
|
|
6
5
|
import { EcrFactory } from "./resources/aws/storage/ecr.js";
|
|
7
6
|
import { NetworkFactory } from "./patterns/aws/network.js";
|
|
@@ -14,8 +13,7 @@ import { FJALL_AUDIT_CONFIG } from "./config/audit.js";
|
|
|
14
13
|
import { FjallLogger } from "./utils/validationLogger.js";
|
|
15
14
|
import { getManifestCollector, writeManifest } from "./utils/manifestWriter.js";
|
|
16
15
|
import { toPascalCase, toKebab } from "./utils/capitaliseString.js";
|
|
17
|
-
|
|
18
|
-
const COST_ALLOCATION_SERVICE_TAG = "fjall:costAllocation:service";
|
|
16
|
+
import { COST_ALLOCATION_TAGS } from "./utils/costAllocationTags.js";
|
|
19
17
|
/**
|
|
20
18
|
* The basic corner-stone of all Fjall-hosted applications.
|
|
21
19
|
* This class is a singleton and should be used to create and manage
|
|
@@ -62,48 +60,16 @@ export class App extends CdkApp {
|
|
|
62
60
|
this.initialiseTunnel(options.tunnel);
|
|
63
61
|
}
|
|
64
62
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Apply backup tier tag to all resources in the app.
|
|
67
|
-
* Maps tier names to AWS Backup plan tag values.
|
|
68
|
-
*/
|
|
69
63
|
applyBackupTag(tier) {
|
|
70
64
|
this.globalTags[BACKUP_TIER_TAG_KEY] = BACKUP_TIER_TAG_MAP[tier];
|
|
71
65
|
}
|
|
72
|
-
/**
|
|
73
|
-
* Initialise the tunnel bastion in the network stack.
|
|
74
|
-
* Creates a minimal EC2 instance for SSM port forwarding to databases.
|
|
75
|
-
*/
|
|
76
66
|
initialiseTunnel(config) {
|
|
77
67
|
if (this.networkDisabled || !this.vpc) {
|
|
78
68
|
throw new Error("Tunnel requires a network. Configure network before enabling tunnel.");
|
|
79
69
|
}
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
: "t4g.micro";
|
|
83
|
-
const networkStack = this.getDefaultNetworkStack();
|
|
84
|
-
const bastionId = `${this.stackPrefix}Bastion`;
|
|
85
|
-
this.bastion = new Ec2Instance(networkStack.getStack(), bastionId, {
|
|
86
|
-
serviceName: `${this.stackPrefix}Bastion`,
|
|
87
|
-
instanceType,
|
|
88
|
-
vpc: this.vpc,
|
|
89
|
-
enableSSH: false,
|
|
90
|
-
minCapacity: 1,
|
|
91
|
-
maxCapacity: 1
|
|
92
|
-
});
|
|
93
|
-
networkStack.addConstruct(this.bastion);
|
|
94
|
-
const outputPrefix = toPascalCase(this.name);
|
|
95
|
-
new CfnOutput(networkStack.getStack(), `${outputPrefix}BastionInstanceId`, {
|
|
96
|
-
value: this.bastion.getAutoScalingGroup().autoScalingGroupName,
|
|
97
|
-
description: "Bastion ASG name for SSM tunnel discovery"
|
|
98
|
-
});
|
|
99
|
-
new CfnOutput(networkStack.getStack(), `${outputPrefix}BastionSecurityGroupId`, {
|
|
100
|
-
value: this.bastion.asgSecurityGroup.securityGroupId,
|
|
101
|
-
description: "Bastion security group ID"
|
|
102
|
-
});
|
|
70
|
+
const { bastion } = createBastion(this.getDefaultNetworkStack(), this.name, this.stackPrefix, this.vpc, config);
|
|
71
|
+
this.bastion = bastion;
|
|
103
72
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Initialise the network (VPC) for this application.
|
|
106
|
-
*/
|
|
107
73
|
initialiseNetwork(config) {
|
|
108
74
|
const networkStack = this.getDefaultNetworkStack();
|
|
109
75
|
if ("useExisting" in config) {
|
|
@@ -117,45 +83,12 @@ export class App extends CdkApp {
|
|
|
117
83
|
this.vpc = network.getVpc();
|
|
118
84
|
}
|
|
119
85
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Get the application name.
|
|
122
|
-
* @returns {string} The application name
|
|
123
|
-
*/
|
|
124
86
|
getName() {
|
|
125
87
|
return this.name;
|
|
126
88
|
}
|
|
127
|
-
/**
|
|
128
|
-
* Get/Create a basic Fjall Application with standard tags applied.
|
|
129
|
-
*
|
|
130
|
-
* @param name Application name
|
|
131
|
-
* @param options Configuration options including network settings
|
|
132
|
-
* @returns {App}
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* // Create app with new VPC
|
|
136
|
-
* const app = App.getApp(appName, {
|
|
137
|
-
* network: { maxAzs: 2, natGateways: false }
|
|
138
|
-
* });
|
|
139
|
-
*
|
|
140
|
-
* @example
|
|
141
|
-
* // Create app using existing VPC
|
|
142
|
-
* const app = App.getApp(appName, {
|
|
143
|
-
* network: { useExisting: "vpc-12345678" }
|
|
144
|
-
* });
|
|
145
|
-
*
|
|
146
|
-
* @example
|
|
147
|
-
* // Create app without network (S3-only apps)
|
|
148
|
-
* const app = App.getApp(appName, { network: false });
|
|
149
|
-
*/
|
|
150
89
|
static getApp(name, options) {
|
|
151
90
|
return App.getInstance(name, options);
|
|
152
91
|
}
|
|
153
|
-
/**
|
|
154
|
-
* Get/Create the singleton instance of the App
|
|
155
|
-
* @param name Application name
|
|
156
|
-
* @param options Configuration options including network settings
|
|
157
|
-
* @returns {App}
|
|
158
|
-
*/
|
|
159
92
|
static getInstance(name, options) {
|
|
160
93
|
// Despite supporting multiple stacks you can still only ever
|
|
161
94
|
// have a single Application per CDK deployment
|
|
@@ -198,13 +131,15 @@ export class App extends CdkApp {
|
|
|
198
131
|
}
|
|
199
132
|
return App.instance;
|
|
200
133
|
}
|
|
134
|
+
static resetForTesting() {
|
|
135
|
+
App.instance = null;
|
|
136
|
+
}
|
|
201
137
|
/**
|
|
202
138
|
* Retrieve a stack by key. If the stack does not exist, it will be created.
|
|
203
139
|
* Dependencies are only applied the first time a stack is created.
|
|
204
140
|
*
|
|
205
141
|
* @param key - The key of the stack
|
|
206
142
|
* @param dependencies - The stack(s) that this stack depends on
|
|
207
|
-
* @returns {AwsStack}
|
|
208
143
|
*/
|
|
209
144
|
getStack(key, dependencies) {
|
|
210
145
|
// Apply the aspect once before creating the first stack
|
|
@@ -223,29 +158,24 @@ export class App extends CdkApp {
|
|
|
223
158
|
*
|
|
224
159
|
* Only depends on Network. Database dependency is added automatically
|
|
225
160
|
* by CDK when compute resources reference database resources.
|
|
226
|
-
*
|
|
227
|
-
* @returns {AwsStack}
|
|
228
161
|
*/
|
|
229
162
|
getDefaultComputeStack() {
|
|
230
163
|
return this.getStack(`${this.stackPrefix}Compute`, this.getDefaultNetworkStack());
|
|
231
164
|
}
|
|
232
165
|
/**
|
|
233
166
|
* Retrieve default network stack - named as `${this.name}Network`
|
|
234
|
-
* @returns {AwsStack}
|
|
235
167
|
*/
|
|
236
168
|
getDefaultNetworkStack() {
|
|
237
169
|
return this.getStack(`${this.stackPrefix}Network`);
|
|
238
170
|
}
|
|
239
171
|
/**
|
|
240
172
|
* Retrieve default database stack - named as `${this.name}Database`
|
|
241
|
-
* @returns {AwsStack}
|
|
242
173
|
*/
|
|
243
174
|
getDefaultDatabaseStack() {
|
|
244
175
|
return this.getStack(`${this.stackPrefix}Database`, this.getDefaultNetworkStack());
|
|
245
176
|
}
|
|
246
177
|
/**
|
|
247
178
|
* Retrieve default storage stack - named as `${this.name}Storage`
|
|
248
|
-
* @returns {AwsStack}
|
|
249
179
|
*/
|
|
250
180
|
getDefaultStorageStack() {
|
|
251
181
|
return this.getStack(`${this.stackPrefix}Storage`, this.getDefaultNetworkStack());
|
|
@@ -255,8 +185,6 @@ export class App extends CdkApp {
|
|
|
255
185
|
*
|
|
256
186
|
* Depends on Network. Compute/Storage dependencies are added automatically
|
|
257
187
|
* by CDK when CDN resources reference ALB or S3 bucket resources.
|
|
258
|
-
*
|
|
259
|
-
* @returns {AwsStack}
|
|
260
188
|
*/
|
|
261
189
|
getDefaultCdnStack() {
|
|
262
190
|
return this.getStack(`${this.stackPrefix}Cdn`, this.getDefaultNetworkStack());
|
|
@@ -267,8 +195,6 @@ export class App extends CdkApp {
|
|
|
267
195
|
* Used for SQS queues, SNS topics, and EventBridge event buses.
|
|
268
196
|
* Depends on Network only. These are regional services that don't
|
|
269
197
|
* require VPC, but we maintain consistent stack dependency patterns.
|
|
270
|
-
*
|
|
271
|
-
* @returns {AwsStack}
|
|
272
198
|
*/
|
|
273
199
|
getDefaultMessagingStack() {
|
|
274
200
|
return this.getStack(`${this.stackPrefix}Messaging`, this.getDefaultNetworkStack());
|
|
@@ -280,7 +206,6 @@ export class App extends CdkApp {
|
|
|
280
206
|
* Network must be configured via App.getApp() options or app.addNetwork().
|
|
281
207
|
*
|
|
282
208
|
* @param name - Optional name of the VPC to retrieve. If not provided, returns the default VPC.
|
|
283
|
-
* @returns {IVpc} The configured VPC
|
|
284
209
|
* @throws {Error} If network is disabled, not configured, or named VPC not found
|
|
285
210
|
*/
|
|
286
211
|
getVpc(name) {
|
|
@@ -304,11 +229,6 @@ export class App extends CdkApp {
|
|
|
304
229
|
}
|
|
305
230
|
return this.vpc;
|
|
306
231
|
}
|
|
307
|
-
/**
|
|
308
|
-
* Get the names of all available VPCs.
|
|
309
|
-
*
|
|
310
|
-
* @returns {string[]} Array of VPC names. Includes "default" if the default VPC is configured.
|
|
311
|
-
*/
|
|
312
232
|
getVpcNames() {
|
|
313
233
|
const names = [];
|
|
314
234
|
if (this.vpc) {
|
|
@@ -317,10 +237,6 @@ export class App extends CdkApp {
|
|
|
317
237
|
names.push(...this.additionalVpcs.keys());
|
|
318
238
|
return names;
|
|
319
239
|
}
|
|
320
|
-
/**
|
|
321
|
-
* Retrieve the default application container registry. If the registry does not exist
|
|
322
|
-
* it will be created.
|
|
323
|
-
*/
|
|
324
240
|
getDefaultContainerRegistry() {
|
|
325
241
|
if (!this.defaultEcr) {
|
|
326
242
|
const networkStack = this.getDefaultNetworkStack();
|
|
@@ -341,7 +257,6 @@ export class App extends CdkApp {
|
|
|
341
257
|
*
|
|
342
258
|
* @param webappAccountId - Optional AWS account ID of the Fjall webapp. Defaults to configured platform account.
|
|
343
259
|
* @param externalId - Optional external ID for additional security. If not provided, a unique ID will be generated.
|
|
344
|
-
* @returns {Role} The created audit role
|
|
345
260
|
*/
|
|
346
261
|
createAuditRole(webappAccountId, externalId) {
|
|
347
262
|
if (!this.defaultAuditRole) {
|
|
@@ -361,17 +276,9 @@ export class App extends CdkApp {
|
|
|
361
276
|
}
|
|
362
277
|
return this.defaultAuditRole;
|
|
363
278
|
}
|
|
364
|
-
/**
|
|
365
|
-
* Get the external ID used for the audit role
|
|
366
|
-
* @returns {string | undefined} The external ID if audit role has been created
|
|
367
|
-
*/
|
|
368
279
|
getAuditRoleExternalId() {
|
|
369
280
|
return this.auditRoleExternalId;
|
|
370
281
|
}
|
|
371
|
-
/**
|
|
372
|
-
* Generate a unique external ID for audit role
|
|
373
|
-
* Format: fjall-audit-{appName}-{timestamp}
|
|
374
|
-
*/
|
|
375
282
|
generateAuditExternalId() {
|
|
376
283
|
const uniqueId = randomBytes(8).toString("hex");
|
|
377
284
|
return `fjall-audit-${toKebab(this.name)}-${uniqueId}`;
|
|
@@ -406,9 +313,6 @@ export class App extends CdkApp {
|
|
|
406
313
|
computeStack.addConstruct(construct);
|
|
407
314
|
return construct;
|
|
408
315
|
}
|
|
409
|
-
/**
|
|
410
|
-
* Manually add a resource to the default compute stack.
|
|
411
|
-
*/
|
|
412
316
|
addComputeResource(resource) {
|
|
413
317
|
const computeStack = this.getDefaultComputeStack();
|
|
414
318
|
computeStack.addConstruct(resource);
|
|
@@ -443,9 +347,6 @@ export class App extends CdkApp {
|
|
|
443
347
|
}
|
|
444
348
|
return databaseConstruct;
|
|
445
349
|
}
|
|
446
|
-
/**
|
|
447
|
-
* Type guard for IConnectable — checks if a construct has a connections property.
|
|
448
|
-
*/
|
|
449
350
|
isConnectable(construct) {
|
|
450
351
|
return (typeof construct === "object" &&
|
|
451
352
|
construct !== null &&
|
|
@@ -509,6 +410,32 @@ export class App extends CdkApp {
|
|
|
509
410
|
cdnStack.addConstruct(cdn);
|
|
510
411
|
return cdn;
|
|
511
412
|
}
|
|
413
|
+
/**
|
|
414
|
+
* Peer this app's VPC with a remote app's VPC.
|
|
415
|
+
*
|
|
416
|
+
* Creates the peering connection plus routes on both sides. The remote app
|
|
417
|
+
* must have deployed a `VpcPeerAccepter` first. Note: `app.getVpc(peerAppName)`
|
|
418
|
+
* does NOT return the peer's VPC — callers wanting the remote handle must use
|
|
419
|
+
* the returned `VpcPeer` instance.
|
|
420
|
+
*/
|
|
421
|
+
addVpcPeer(fn) {
|
|
422
|
+
const networkStack = this.getDefaultNetworkStack();
|
|
423
|
+
const peer = fn(this, networkStack.getStack());
|
|
424
|
+
networkStack.addConstruct(peer);
|
|
425
|
+
return peer;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Accept VPC peering requests from remote apps.
|
|
429
|
+
*
|
|
430
|
+
* Creates an IAM role for cross-account peering acceptance and return-route
|
|
431
|
+
* management, and publishes VPC metadata to SSM for discovery.
|
|
432
|
+
*/
|
|
433
|
+
addVpcPeerAccepter(fn) {
|
|
434
|
+
const networkStack = this.getDefaultNetworkStack();
|
|
435
|
+
const accepter = fn(this, networkStack.getStack());
|
|
436
|
+
networkStack.addConstruct(accepter);
|
|
437
|
+
return accepter;
|
|
438
|
+
}
|
|
512
439
|
/**
|
|
513
440
|
* Add a messaging resource to the default queue stack using the factory pattern.
|
|
514
441
|
*
|
|
@@ -580,7 +507,6 @@ export class App extends CdkApp {
|
|
|
580
507
|
* Additional VPCs can be retrieved by name using app.getVpc(name).
|
|
581
508
|
*
|
|
582
509
|
* @param fn - Factory function that creates the Network construct
|
|
583
|
-
* @returns {Network} The created Network construct
|
|
584
510
|
*
|
|
585
511
|
* @example
|
|
586
512
|
* const isolatedVpc = app.addNetwork(
|
|
@@ -596,33 +522,19 @@ export class App extends CdkApp {
|
|
|
596
522
|
networkStack.addConstruct(network);
|
|
597
523
|
return network;
|
|
598
524
|
}
|
|
599
|
-
/**
|
|
600
|
-
* Manually add a resource to the default database stack.
|
|
601
|
-
*/
|
|
602
525
|
addDatabaseResource(resource) {
|
|
603
526
|
const databaseStack = this.getDefaultDatabaseStack();
|
|
604
527
|
databaseStack.addConstruct(resource);
|
|
605
528
|
}
|
|
606
|
-
/**
|
|
607
|
-
* Manually add a resource to the default storage stack.
|
|
608
|
-
*/
|
|
609
529
|
addStorageResource(resource) {
|
|
610
530
|
const storageStack = this.getDefaultStorageStack();
|
|
611
531
|
storageStack.addConstruct(resource);
|
|
612
532
|
}
|
|
613
|
-
/**
|
|
614
|
-
* Initialise standard tags
|
|
615
|
-
*/
|
|
616
533
|
initialiseStandardTags() {
|
|
617
534
|
const config = getConfig();
|
|
618
|
-
this.globalTags =
|
|
619
|
-
|
|
620
|
-
[COST_ALLOCATION_SERVICE_TAG]: this.name
|
|
621
|
-
};
|
|
535
|
+
this.globalTags[COST_ALLOCATION_TAGS.ENVIRONMENT] = config.environment;
|
|
536
|
+
this.globalTags[COST_ALLOCATION_TAGS.SERVICE] = this.name;
|
|
622
537
|
}
|
|
623
|
-
/**
|
|
624
|
-
* Apply all tags using CDK's native Tags.of().add() API
|
|
625
|
-
*/
|
|
626
538
|
applyTagsAspect() {
|
|
627
539
|
if (!this.aspectApplied && Object.keys(this.globalTags).length > 0) {
|
|
628
540
|
// Apply standard tags using Tags.of(this).add()
|
|
@@ -641,7 +553,7 @@ export class App extends CdkApp {
|
|
|
641
553
|
* @example
|
|
642
554
|
* app.addTags({
|
|
643
555
|
* "fjall:costAllocation:owner": "platform-team",
|
|
644
|
-
* "fjall:costAllocation:cost-
|
|
556
|
+
* "fjall:costAllocation:cost-centre": "CC-123",
|
|
645
557
|
* "team:slack-channel": "#platform-alerts"
|
|
646
558
|
* });
|
|
647
559
|
*/
|
|
@@ -656,11 +568,7 @@ export class App extends CdkApp {
|
|
|
656
568
|
}
|
|
657
569
|
return this;
|
|
658
570
|
}
|
|
659
|
-
/**
|
|
660
|
-
* Export resource inventory collected during synthesis
|
|
661
|
-
* Call this after app.synth() to get complete resource inventory
|
|
662
|
-
* @returns {ResourceInventory} Complete inventory of all resources in the app
|
|
663
|
-
*/
|
|
571
|
+
/** Call after app.synth() — inventory is not available before synthesis. */
|
|
664
572
|
exportResourceInventory() {
|
|
665
573
|
if (!this.resourceInventory) {
|
|
666
574
|
throw new Error("Resource inventory not available. Ensure a ResourceInventoryAspect has been added before calling exportResourceInventory().");
|
|
@@ -671,16 +579,9 @@ export class App extends CdkApp {
|
|
|
671
579
|
appName: this.name
|
|
672
580
|
};
|
|
673
581
|
}
|
|
674
|
-
/**
|
|
675
|
-
* Get the manifest collector for registering services and patterns.
|
|
676
|
-
* Used by ComputeFactory and PatternFactory to register their configurations.
|
|
677
|
-
*/
|
|
678
582
|
getManifestCollector() {
|
|
679
583
|
return this.manifestCollector;
|
|
680
584
|
}
|
|
681
|
-
/**
|
|
682
|
-
* Override synth to automatically export resource inventory and manifest
|
|
683
|
-
*/
|
|
684
585
|
synth(options) {
|
|
685
586
|
// Call parent synth first
|
|
686
587
|
const assembly = super.synth(options);
|
|
@@ -4,6 +4,7 @@ import { ManagementEventsTrail } from "../../config/aws/cloudTrail.js";
|
|
|
4
4
|
import { OidcConnector } from "../../config/aws/oidcConnector.js";
|
|
5
5
|
import { AccountMonitoringRole } from "../../config/aws/accountMonitoringRole.js";
|
|
6
6
|
import { AccountAuditRole } from "../../config/aws/accountAuditRole.js";
|
|
7
|
+
import { CDK_CONTEXT_KEYS } from "../../utils/cdkContext.js";
|
|
7
8
|
import { getConfig } from "../../utils/getConfig.js";
|
|
8
9
|
import { DisasterRecovery } from "../../config/aws/disasterRecovery.js";
|
|
9
10
|
import { S3BlockPublicAccess } from "../../config/aws/s3BlockPublicAccess.js";
|
|
@@ -27,7 +28,7 @@ export class Account extends Stack {
|
|
|
27
28
|
const env = props.env ?? { region, account: accountId };
|
|
28
29
|
super(scope, id, { ...props, env });
|
|
29
30
|
this.resolvedRegion = region ?? this.region;
|
|
30
|
-
const orgId = this.node.tryGetContext(
|
|
31
|
+
const orgId = this.node.tryGetContext(CDK_CONTEXT_KEYS.ORG_ID);
|
|
31
32
|
if (orgId) {
|
|
32
33
|
new CfnOutput(this, "OrganisationIdOutput", {
|
|
33
34
|
key: "OrganisationId",
|
|
@@ -66,10 +67,10 @@ export class Account extends Stack {
|
|
|
66
67
|
}
|
|
67
68
|
new ManagementEventsTrail(this, "CloudTrail", {
|
|
68
69
|
accountId: this.account,
|
|
69
|
-
region
|
|
70
|
+
region: this.resolvedRegion
|
|
70
71
|
});
|
|
71
72
|
new EcrDefaultImage(this, "EcrDefaultImage", {
|
|
72
|
-
region,
|
|
73
|
+
region: this.resolvedRegion,
|
|
73
74
|
accountId: this.account,
|
|
74
75
|
eventBusArn: eventBus.defaultEventBusArn.value
|
|
75
76
|
});
|
|
@@ -78,7 +79,7 @@ export class Account extends Stack {
|
|
|
78
79
|
const isComplianceAccount = environment === "compliance";
|
|
79
80
|
if (environment === "production" || isComplianceAccount) {
|
|
80
81
|
new DisasterRecovery(this, "DisasterRecovery", {
|
|
81
|
-
region,
|
|
82
|
+
region: this.resolvedRegion,
|
|
82
83
|
accountId
|
|
83
84
|
});
|
|
84
85
|
}
|