@fjall/components-infrastructure 0.95.0 → 0.99.1
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 +90 -107
- package/dist/lib/app.js +149 -139
- package/dist/lib/config/aws/__t17fixture.d.ts +1 -0
- package/dist/lib/config/aws/__t17fixture.js +3 -0
- package/dist/lib/config/aws/__t17fixtureType.d.ts +2 -0
- package/dist/lib/config/aws/__t17fixtureType.js +1 -0
- package/dist/lib/config/aws/alarmTopic.js +8 -4
- package/dist/lib/config/aws/cloudTrail.js +1 -1
- package/dist/lib/config/aws/disasterRecovery.js +11 -16
- package/dist/lib/config/aws/ecrDefaultImage.d.ts +0 -1
- package/dist/lib/config/aws/ecrDefaultImage.js +13 -23
- package/dist/lib/config/aws/identityCenter.d.ts +10 -3
- package/dist/lib/config/aws/identityCenter.js +101 -37
- package/dist/lib/config/aws/identityCenterGroupMembership.js +8 -2
- package/dist/lib/config/aws/identityCenterMembership.d.ts +11 -0
- package/dist/lib/config/aws/identityCenterMembership.js +61 -0
- package/dist/lib/config/aws/index.d.ts +1 -1
- package/dist/lib/config/aws/index.js +1 -1
- package/dist/lib/config/aws/ipam.js +6 -11
- package/dist/lib/config/aws/oidcConnector.js +5 -1
- package/dist/lib/config/aws/scpPreset.js +4 -1
- package/dist/lib/patterns/aws/_eslint_test_tmp/leak.d.ts +1 -0
- package/dist/lib/patterns/aws/_eslint_test_tmp/leak.js +4 -0
- package/dist/lib/patterns/aws/account.js +7 -8
- package/dist/lib/patterns/aws/apexDomainPattern.js +10 -10
- package/dist/lib/patterns/aws/bastionFactory.d.ts +10 -0
- package/dist/lib/patterns/aws/bastionFactory.js +29 -0
- package/dist/lib/patterns/aws/buildkite.d.ts +2 -2
- package/dist/lib/patterns/aws/buildkite.js +51 -97
- package/dist/lib/patterns/aws/cdn.js +1 -1
- package/dist/lib/patterns/aws/clickhouseDatabase.d.ts +172 -0
- package/dist/lib/patterns/aws/clickhouseDatabase.js +600 -0
- package/dist/lib/patterns/aws/compute.d.ts +4 -6
- package/dist/lib/patterns/aws/compute.js +7 -13
- package/dist/lib/patterns/aws/computeEcs.d.ts +95 -396
- package/dist/lib/patterns/aws/computeEcs.js +880 -46
- package/dist/lib/patterns/aws/computeEcsTypes.d.ts +889 -0
- package/dist/lib/patterns/aws/computeEcsTypes.js +12 -0
- package/dist/lib/patterns/aws/computeLambda.d.ts +0 -5
- package/dist/lib/patterns/aws/computeLambda.js +1 -2
- package/dist/lib/patterns/aws/database.d.ts +50 -8
- package/dist/lib/patterns/aws/database.js +183 -27
- package/dist/lib/patterns/aws/domain.js +8 -7
- package/dist/lib/patterns/aws/index.d.ts +3 -0
- package/dist/lib/patterns/aws/index.js +3 -0
- package/dist/lib/patterns/aws/interfaces/compute.d.ts +13 -1
- 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/database.d.ts +187 -8
- package/dist/lib/patterns/aws/interfaces/database.js +17 -3
- package/dist/lib/patterns/aws/interfaces/index.d.ts +4 -2
- package/dist/lib/patterns/aws/interfaces/index.js +4 -2
- package/dist/lib/patterns/aws/interfaces/messaging.d.ts +7 -0
- package/dist/lib/patterns/aws/interfaces/migrationContributor.d.ts +47 -0
- package/dist/lib/patterns/aws/interfaces/migrationContributor.js +9 -0
- 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/messaging.d.ts +66 -10
- package/dist/lib/patterns/aws/messaging.js +115 -20
- package/dist/lib/patterns/aws/network.js +16 -7
- package/dist/lib/patterns/aws/organisation.d.ts +4 -0
- package/dist/lib/patterns/aws/organisation.js +24 -5
- package/dist/lib/patterns/aws/storage.d.ts +1 -2
- package/dist/lib/patterns/aws/storage.js +3 -2
- package/dist/lib/patterns/aws/vpcPeer.d.ts +34 -0
- package/dist/lib/patterns/aws/vpcPeer.js +38 -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 +25 -7
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.d.ts +49 -0
- package/dist/lib/resources/aws/analytics/clickhouseAlarms.js +140 -0
- package/dist/lib/resources/aws/analytics/clickhouseConstants.d.ts +4 -4
- package/dist/lib/resources/aws/analytics/clickhouseConstants.js +6 -4
- package/dist/lib/resources/aws/analytics/clickhouseTypes.d.ts +12 -0
- package/dist/lib/resources/aws/analytics/clickhouseUserData.d.ts +1 -0
- package/dist/lib/resources/aws/analytics/clickhouseUserData.js +56 -5
- 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/base/awsStack.js +4 -2
- package/dist/lib/resources/aws/compute/__tmp__/regression-shape.d.ts +2 -0
- package/dist/lib/resources/aws/compute/__tmp__/regression-shape.js +11 -0
- package/dist/lib/resources/aws/compute/asgInlineLifecycleHook.d.ts +52 -0
- package/dist/lib/resources/aws/compute/asgInlineLifecycleHook.js +60 -0
- package/dist/lib/resources/aws/compute/blockDeviceVolume.d.ts +8 -0
- package/dist/lib/resources/aws/compute/blockDeviceVolume.js +10 -0
- package/dist/lib/resources/aws/compute/ec2.d.ts +132 -12
- package/dist/lib/resources/aws/compute/ec2.js +163 -23
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationHandler.d.ts +41 -0
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationHandler.js +194 -0
- package/dist/lib/resources/aws/compute/ec2GracefulTerminationLambda.source.cjs +458 -0
- package/dist/lib/resources/aws/compute/ecs.d.ts +27 -1
- package/dist/lib/resources/aws/compute/ecs.js +42 -2
- package/dist/lib/resources/aws/compute/ecsConstants.d.ts +9 -0
- package/dist/lib/resources/aws/compute/ecsConstants.js +16 -0
- package/dist/lib/resources/aws/compute/ecsImages.js +32 -20
- package/dist/lib/resources/aws/compute/ecsLifecycleHookMigration.d.ts +96 -0
- package/dist/lib/resources/aws/compute/ecsLifecycleHookMigration.js +113 -0
- package/dist/lib/resources/aws/compute/ecsNetworking.d.ts +2 -1
- package/dist/lib/resources/aws/compute/ecsNetworking.js +18 -6
- 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/ecsServiceFactory.d.ts +13 -4
- package/dist/lib/resources/aws/compute/ecsServiceFactory.js +155 -33
- package/dist/lib/resources/aws/compute/ecsTaskDefinition.d.ts +31 -1
- package/dist/lib/resources/aws/compute/ecsTaskDefinition.js +110 -6
- package/dist/lib/resources/aws/compute/ecsTypes.d.ts +180 -13
- package/dist/lib/resources/aws/compute/ecsValidation.d.ts +9 -0
- package/dist/lib/resources/aws/compute/ecsValidation.js +63 -0
- package/dist/lib/resources/aws/compute/index.d.ts +2 -0
- package/dist/lib/resources/aws/compute/index.js +2 -0
- package/dist/lib/resources/aws/compute/lambda.d.ts +7 -13
- package/dist/lib/resources/aws/compute/lambda.js +30 -38
- package/dist/lib/resources/aws/compute/lifecycleHookLambda.source.cjs +192 -0
- package/dist/lib/resources/aws/compute/persistentDataVolume.d.ts +104 -0
- package/dist/lib/resources/aws/compute/persistentDataVolume.js +245 -0
- package/dist/lib/resources/aws/compute/persistentDataVolumeLambda.source.cjs +398 -0
- package/dist/lib/resources/aws/compute/samApplication.d.ts +15 -0
- package/dist/lib/resources/aws/compute/samApplication.js +27 -0
- package/dist/lib/resources/aws/database/clickhouseConstants.d.ts +159 -0
- package/dist/lib/resources/aws/database/clickhouseConstants.js +181 -0
- package/dist/lib/resources/aws/database/clickhouseSchemas.d.ts +71 -0
- package/dist/lib/resources/aws/database/clickhouseSchemas.js +157 -0
- package/dist/lib/resources/aws/database/clickhouseSecurityGroup.d.ts +14 -0
- package/dist/lib/resources/aws/database/clickhouseSecurityGroup.js +23 -0
- package/dist/lib/resources/aws/database/clickhouseUserData.d.ts +69 -0
- package/dist/lib/resources/aws/database/clickhouseUserData.js +371 -0
- package/dist/lib/resources/aws/database/clickhouseXmlRenderer.d.ts +56 -0
- package/dist/lib/resources/aws/database/clickhouseXmlRenderer.js +112 -0
- package/dist/lib/resources/aws/database/rdsAurora.d.ts +8 -1
- package/dist/lib/resources/aws/database/rdsAurora.js +42 -32
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.d.ts +15 -2
- package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +39 -43
- package/dist/lib/resources/aws/database/rdsDefaults.d.ts +6 -0
- package/dist/lib/resources/aws/database/rdsDefaults.js +7 -1
- package/dist/lib/resources/aws/database/rdsHelpers.d.ts +3 -3
- package/dist/lib/resources/aws/database/rdsHelpers.js +1 -0
- package/dist/lib/resources/aws/database/rdsInstance.d.ts +8 -1
- package/dist/lib/resources/aws/database/rdsInstance.js +51 -34
- package/dist/lib/resources/aws/database/rdsProxyOutput.d.ts +1 -1
- package/dist/lib/resources/aws/database/rdsProxyOutput.js +1 -1
- package/dist/lib/resources/aws/iam/delegationRole.js +12 -5
- package/dist/lib/resources/aws/iam/identityCenter/groupMembership.d.ts +9 -0
- package/dist/lib/resources/aws/iam/identityCenter/groupMembership.js +12 -0
- package/dist/lib/resources/aws/iam/identityCenter/index.d.ts +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/index.js +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/permissionSet.d.ts +1 -0
- package/dist/lib/resources/aws/iam/identityCenter/permissionSet.js +1 -0
- package/dist/lib/resources/aws/logging/logGroup.d.ts +0 -8
- package/dist/lib/resources/aws/logging/logGroup.js +0 -11
- package/dist/lib/resources/aws/messaging/defaultEventBus.d.ts +7 -0
- package/dist/lib/resources/aws/messaging/defaultEventBus.js +21 -0
- package/dist/lib/resources/aws/messaging/eventBridgeRule.d.ts +96 -0
- package/dist/lib/resources/aws/messaging/eventBridgeRule.js +110 -0
- package/dist/lib/resources/aws/messaging/eventTargets.d.ts +84 -0
- package/dist/lib/resources/aws/messaging/eventTargets.js +152 -0
- package/dist/lib/resources/aws/messaging/eventbridge.d.ts +25 -2
- package/dist/lib/resources/aws/messaging/eventbridge.js +22 -10
- package/dist/lib/resources/aws/messaging/index.d.ts +5 -0
- package/dist/lib/resources/aws/messaging/index.js +2 -0
- package/dist/lib/resources/aws/messaging/schedule.d.ts +118 -0
- package/dist/lib/resources/aws/messaging/schedule.js +64 -0
- package/dist/lib/resources/aws/messaging/sns.d.ts +2 -1
- package/dist/lib/resources/aws/messaging/sqs.d.ts +2 -1
- package/dist/lib/resources/aws/messaging/subscription.d.ts +112 -0
- package/dist/lib/resources/aws/messaging/subscription.js +67 -0
- package/dist/lib/resources/aws/messaging/utils.d.ts +6 -0
- package/dist/lib/resources/aws/messaging/utils.js +10 -0
- package/dist/lib/resources/aws/monitoring/clickhouseAlarms.d.ts +60 -0
- package/dist/lib/resources/aws/monitoring/clickhouseAlarms.js +139 -0
- package/dist/lib/resources/aws/monitoring/index.d.ts +2 -0
- package/dist/lib/resources/aws/monitoring/index.js +2 -0
- package/dist/lib/resources/aws/monitoring/scheduleAlarms.d.ts +47 -0
- package/dist/lib/resources/aws/monitoring/scheduleAlarms.js +106 -0
- package/dist/lib/resources/aws/networking/crossAccountDelegationRecord.js +6 -3
- package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.d.ts +40 -0
- package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.js +158 -0
- package/dist/lib/resources/aws/networking/dnsRecord/dnsRecordBase.js +7 -4
- package/dist/lib/resources/aws/networking/domainCertificate.d.ts +2 -2
- package/dist/lib/resources/aws/networking/domainCertificate.js +6 -3
- package/dist/lib/resources/aws/networking/hostedZone.js +6 -4
- 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/serviceDiscovery.d.ts +96 -0
- package/dist/lib/resources/aws/networking/serviceDiscovery.js +96 -0
- package/dist/lib/resources/aws/networking/vpc.d.ts +4 -1
- package/dist/lib/resources/aws/networking/vpc.js +10 -3
- 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 +106 -0
- package/dist/lib/resources/aws/organisation/costAllocationTagActivator.d.ts +16 -5
- package/dist/lib/resources/aws/organisation/costAllocationTagActivator.js +17 -3
- package/dist/lib/resources/aws/organisation/index.d.ts +1 -1
- package/dist/lib/resources/aws/organisation/organisationPolicy.d.ts +2 -0
- package/dist/lib/resources/aws/organisation/organisationPolicy.js +3 -2
- package/dist/lib/resources/aws/secrets/secret.d.ts +7 -0
- package/dist/lib/resources/aws/secrets/secret.js +4 -3
- package/dist/lib/resources/aws/storage/bucketDeployment.d.ts +16 -0
- package/dist/lib/resources/aws/storage/bucketDeployment.js +17 -0
- package/dist/lib/resources/aws/storage/ecr.js +5 -5
- package/dist/lib/resources/aws/storage/index.d.ts +1 -0
- package/dist/lib/resources/aws/storage/index.js +1 -0
- package/dist/lib/resources/aws/storage/s3.js +10 -3
- package/dist/lib/resources/aws/utilities/customResource.js +18 -9
- package/dist/lib/synth_dump.d.ts +1 -0
- package/dist/lib/synth_dump.js +42 -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 +10 -0
- package/dist/lib/utils/cdkContext.js +13 -0
- package/dist/lib/utils/connections.d.ts +7 -1
- package/dist/lib/utils/connections.js +21 -0
- package/dist/lib/utils/connector.d.ts +30 -2
- package/dist/lib/utils/connector.js +6 -1
- package/dist/lib/utils/costAllocationTags.d.ts +15 -0
- package/dist/lib/utils/costAllocationTags.js +16 -0
- package/dist/lib/utils/databaseTypes.d.ts +14 -0
- package/dist/lib/utils/getConfig.d.ts +2 -0
- package/dist/lib/utils/getConfig.js +2 -0
- package/dist/lib/utils/index.d.ts +4 -0
- package/dist/lib/utils/index.js +4 -0
- package/dist/lib/utils/manifestWriter.d.ts +6 -89
- package/dist/lib/utils/manifestWriter.js +36 -23
- package/dist/lib/utils/migrationVersionResolvers.d.ts +2 -0
- package/dist/lib/utils/migrationVersionResolvers.js +2 -0
- package/dist/lib/utils/orgConfigParser.js +2 -1
- package/dist/lib/utils/resolveAlertsTopic.d.ts +14 -0
- package/dist/lib/utils/resolveAlertsTopic.js +30 -0
- package/dist/lib/utils/validationLogger.js +6 -3
- package/dist/lib/utils/vpcPeerInterface.d.ts +22 -0
- package/dist/lib/utils/vpcPeerInterface.js +1 -0
- package/package.json +22 -18
package/dist/lib/app.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { App as CdkApp, Aspects, Tags } from "aws-cdk-lib";
|
|
2
|
+
import { maskSensitiveOutput } from "@fjall/util";
|
|
2
3
|
import { Vpc } from "./resources/aws/networking/vpc.js";
|
|
3
|
-
import {
|
|
4
|
-
import { Ec2Instance } from "./resources/aws/compute/ec2.js";
|
|
4
|
+
import { createBastion } from "./patterns/aws/bastionFactory.js";
|
|
5
5
|
import { AwsStack } from "./resources/index.js";
|
|
6
6
|
import { EcrFactory } from "./resources/aws/storage/ecr.js";
|
|
7
7
|
import { NetworkFactory } from "./patterns/aws/network.js";
|
|
8
|
+
import { MessagingFactory } from "./patterns/aws/messaging.js";
|
|
9
|
+
import { Schedule } from "./resources/aws/messaging/schedule.js";
|
|
10
|
+
import { ServiceDiscoveryNamespace } from "./resources/aws/networking/serviceDiscovery.js";
|
|
8
11
|
import { StandardTagsAspect } from "./utils/standardTagsAspect.js";
|
|
9
12
|
import { BACKUP_TIER_TAG_KEY, BACKUP_TIER_TAG_MAP } from "./utils/backupTierMapping.js";
|
|
10
13
|
import { randomBytes } from "crypto";
|
|
@@ -14,8 +17,7 @@ import { FJALL_AUDIT_CONFIG } from "./config/audit.js";
|
|
|
14
17
|
import { FjallLogger } from "./utils/validationLogger.js";
|
|
15
18
|
import { getManifestCollector, writeManifest } from "./utils/manifestWriter.js";
|
|
16
19
|
import { toPascalCase, toKebab } from "./utils/capitaliseString.js";
|
|
17
|
-
|
|
18
|
-
const COST_ALLOCATION_SERVICE_TAG = "fjall:costAllocation:service";
|
|
20
|
+
import { COST_ALLOCATION_TAGS } from "./utils/costAllocationTags.js";
|
|
19
21
|
/**
|
|
20
22
|
* The basic corner-stone of all Fjall-hosted applications.
|
|
21
23
|
* This class is a singleton and should be used to create and manage
|
|
@@ -30,6 +32,9 @@ export class App extends CdkApp {
|
|
|
30
32
|
vpc;
|
|
31
33
|
additionalVpcs = new Map();
|
|
32
34
|
defaultEcr;
|
|
35
|
+
defaultEventBus;
|
|
36
|
+
eventBusOverride;
|
|
37
|
+
defaultNamespace;
|
|
33
38
|
defaultAuditRole;
|
|
34
39
|
auditRoleExternalId;
|
|
35
40
|
bastion;
|
|
@@ -61,49 +66,20 @@ export class App extends CdkApp {
|
|
|
61
66
|
if (options?.tunnel) {
|
|
62
67
|
this.initialiseTunnel(options.tunnel);
|
|
63
68
|
}
|
|
69
|
+
if (options?.eventBus !== undefined) {
|
|
70
|
+
this.eventBusOverride = options.eventBus;
|
|
71
|
+
}
|
|
64
72
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Apply backup tier tag to all resources in the app.
|
|
67
|
-
* Maps tier names to AWS Backup plan tag values.
|
|
68
|
-
*/
|
|
69
73
|
applyBackupTag(tier) {
|
|
70
74
|
this.globalTags[BACKUP_TIER_TAG_KEY] = BACKUP_TIER_TAG_MAP[tier];
|
|
71
75
|
}
|
|
72
|
-
/**
|
|
73
|
-
* Initialise the tunnel bastion in the network stack.
|
|
74
|
-
* Creates a minimal EC2 instance for SSM port forwarding to databases.
|
|
75
|
-
*/
|
|
76
76
|
initialiseTunnel(config) {
|
|
77
77
|
if (this.networkDisabled || !this.vpc) {
|
|
78
78
|
throw new Error("Tunnel requires a network. Configure network before enabling tunnel.");
|
|
79
79
|
}
|
|
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
|
-
});
|
|
80
|
+
const { bastion } = createBastion(this.getDefaultNetworkStack(), this.name, this.stackPrefix, this.vpc, config);
|
|
81
|
+
this.bastion = bastion;
|
|
103
82
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Initialise the network (VPC) for this application.
|
|
106
|
-
*/
|
|
107
83
|
initialiseNetwork(config) {
|
|
108
84
|
const networkStack = this.getDefaultNetworkStack();
|
|
109
85
|
if ("useExisting" in config) {
|
|
@@ -117,45 +93,12 @@ export class App extends CdkApp {
|
|
|
117
93
|
this.vpc = network.getVpc();
|
|
118
94
|
}
|
|
119
95
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Get the application name.
|
|
122
|
-
* @returns {string} The application name
|
|
123
|
-
*/
|
|
124
96
|
getName() {
|
|
125
97
|
return this.name;
|
|
126
98
|
}
|
|
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
99
|
static getApp(name, options) {
|
|
151
100
|
return App.getInstance(name, options);
|
|
152
101
|
}
|
|
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
102
|
static getInstance(name, options) {
|
|
160
103
|
// Despite supporting multiple stacks you can still only ever
|
|
161
104
|
// have a single Application per CDK deployment
|
|
@@ -195,16 +138,31 @@ export class App extends CdkApp {
|
|
|
195
138
|
if (options?.tunnel && !App.instance.bastion) {
|
|
196
139
|
App.instance.initialiseTunnel(options.tunnel);
|
|
197
140
|
}
|
|
141
|
+
if (options?.eventBus !== undefined) {
|
|
142
|
+
if (App.instance.eventBusOverride === undefined &&
|
|
143
|
+
App.instance.defaultEventBus === undefined) {
|
|
144
|
+
App.instance.eventBusOverride = options.eventBus;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const reason = App.instance.defaultEventBus !== undefined
|
|
148
|
+
? "bus was already materialised via getEventBus()"
|
|
149
|
+
: "override was already set on a prior App.getApp() call";
|
|
150
|
+
FjallLogger.warn(`App.getApp() eventBus override ignored: ${reason}. ` +
|
|
151
|
+
`Pass eventBus options to the first App.getApp() call.`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
198
154
|
}
|
|
199
155
|
return App.instance;
|
|
200
156
|
}
|
|
157
|
+
static resetForTesting() {
|
|
158
|
+
App.instance = null;
|
|
159
|
+
}
|
|
201
160
|
/**
|
|
202
161
|
* Retrieve a stack by key. If the stack does not exist, it will be created.
|
|
203
162
|
* Dependencies are only applied the first time a stack is created.
|
|
204
163
|
*
|
|
205
164
|
* @param key - The key of the stack
|
|
206
165
|
* @param dependencies - The stack(s) that this stack depends on
|
|
207
|
-
* @returns {AwsStack}
|
|
208
166
|
*/
|
|
209
167
|
getStack(key, dependencies) {
|
|
210
168
|
// Apply the aspect once before creating the first stack
|
|
@@ -223,29 +181,24 @@ export class App extends CdkApp {
|
|
|
223
181
|
*
|
|
224
182
|
* Only depends on Network. Database dependency is added automatically
|
|
225
183
|
* by CDK when compute resources reference database resources.
|
|
226
|
-
*
|
|
227
|
-
* @returns {AwsStack}
|
|
228
184
|
*/
|
|
229
185
|
getDefaultComputeStack() {
|
|
230
186
|
return this.getStack(`${this.stackPrefix}Compute`, this.getDefaultNetworkStack());
|
|
231
187
|
}
|
|
232
188
|
/**
|
|
233
189
|
* Retrieve default network stack - named as `${this.name}Network`
|
|
234
|
-
* @returns {AwsStack}
|
|
235
190
|
*/
|
|
236
191
|
getDefaultNetworkStack() {
|
|
237
192
|
return this.getStack(`${this.stackPrefix}Network`);
|
|
238
193
|
}
|
|
239
194
|
/**
|
|
240
195
|
* Retrieve default database stack - named as `${this.name}Database`
|
|
241
|
-
* @returns {AwsStack}
|
|
242
196
|
*/
|
|
243
197
|
getDefaultDatabaseStack() {
|
|
244
198
|
return this.getStack(`${this.stackPrefix}Database`, this.getDefaultNetworkStack());
|
|
245
199
|
}
|
|
246
200
|
/**
|
|
247
201
|
* Retrieve default storage stack - named as `${this.name}Storage`
|
|
248
|
-
* @returns {AwsStack}
|
|
249
202
|
*/
|
|
250
203
|
getDefaultStorageStack() {
|
|
251
204
|
return this.getStack(`${this.stackPrefix}Storage`, this.getDefaultNetworkStack());
|
|
@@ -255,8 +208,6 @@ export class App extends CdkApp {
|
|
|
255
208
|
*
|
|
256
209
|
* Depends on Network. Compute/Storage dependencies are added automatically
|
|
257
210
|
* by CDK when CDN resources reference ALB or S3 bucket resources.
|
|
258
|
-
*
|
|
259
|
-
* @returns {AwsStack}
|
|
260
211
|
*/
|
|
261
212
|
getDefaultCdnStack() {
|
|
262
213
|
return this.getStack(`${this.stackPrefix}Cdn`, this.getDefaultNetworkStack());
|
|
@@ -267,8 +218,6 @@ export class App extends CdkApp {
|
|
|
267
218
|
* Used for SQS queues, SNS topics, and EventBridge event buses.
|
|
268
219
|
* Depends on Network only. These are regional services that don't
|
|
269
220
|
* require VPC, but we maintain consistent stack dependency patterns.
|
|
270
|
-
*
|
|
271
|
-
* @returns {AwsStack}
|
|
272
221
|
*/
|
|
273
222
|
getDefaultMessagingStack() {
|
|
274
223
|
return this.getStack(`${this.stackPrefix}Messaging`, this.getDefaultNetworkStack());
|
|
@@ -280,7 +229,6 @@ export class App extends CdkApp {
|
|
|
280
229
|
* Network must be configured via App.getApp() options or app.addNetwork().
|
|
281
230
|
*
|
|
282
231
|
* @param name - Optional name of the VPC to retrieve. If not provided, returns the default VPC.
|
|
283
|
-
* @returns {IVpc} The configured VPC
|
|
284
232
|
* @throws {Error} If network is disabled, not configured, or named VPC not found
|
|
285
233
|
*/
|
|
286
234
|
getVpc(name) {
|
|
@@ -304,11 +252,6 @@ export class App extends CdkApp {
|
|
|
304
252
|
}
|
|
305
253
|
return this.vpc;
|
|
306
254
|
}
|
|
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
255
|
getVpcNames() {
|
|
313
256
|
const names = [];
|
|
314
257
|
if (this.vpc) {
|
|
@@ -317,10 +260,6 @@ export class App extends CdkApp {
|
|
|
317
260
|
names.push(...this.additionalVpcs.keys());
|
|
318
261
|
return names;
|
|
319
262
|
}
|
|
320
|
-
/**
|
|
321
|
-
* Retrieve the default application container registry. If the registry does not exist
|
|
322
|
-
* it will be created.
|
|
323
|
-
*/
|
|
324
263
|
getDefaultContainerRegistry() {
|
|
325
264
|
if (!this.defaultEcr) {
|
|
326
265
|
const networkStack = this.getDefaultNetworkStack();
|
|
@@ -332,6 +271,67 @@ export class App extends CdkApp {
|
|
|
332
271
|
}
|
|
333
272
|
return this.defaultEcr;
|
|
334
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Lazy getter for the per-app default custom EventBridge bus (D2).
|
|
276
|
+
*
|
|
277
|
+
* Buses are recreatable in non-prod; the env-resolved default keeps prod
|
|
278
|
+
* history. The override (`App.getApp({ eventBus: { name?, removalPolicy? } })`)
|
|
279
|
+
* is consulted first; absent override falls back to the app name and the
|
|
280
|
+
* `env({ default: "DESTROY", production: "RETAIN" })` resolution per D17.
|
|
281
|
+
* NODE_ENV is not consulted — it is not set during CDK synth in Fjall's
|
|
282
|
+
* deployment paths.
|
|
283
|
+
*/
|
|
284
|
+
getEventBus() {
|
|
285
|
+
if (this.defaultEventBus) {
|
|
286
|
+
return this.defaultEventBus;
|
|
287
|
+
}
|
|
288
|
+
const eventBusName = this.eventBusOverride?.name ?? this.getName();
|
|
289
|
+
const removalPolicy = this.eventBusOverride?.removalPolicy;
|
|
290
|
+
const bus = this.addMessaging(MessagingFactory.build(`${this.stackPrefix}EventBus`, {
|
|
291
|
+
type: "eventBus",
|
|
292
|
+
eventBusName,
|
|
293
|
+
appName: this.name,
|
|
294
|
+
removalPolicy
|
|
295
|
+
}));
|
|
296
|
+
this.defaultEventBus = bus;
|
|
297
|
+
return bus;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Lazy getter for the per-app Cloud Map private DNS namespace (D7 + D29 of
|
|
301
|
+
* the ClickHouse Database Factory promotion design).
|
|
302
|
+
*
|
|
303
|
+
* The namespace is constructed in the network stack on first call and
|
|
304
|
+
* reused thereafter — `app.getNamespace() === app.getNamespace()`. Default
|
|
305
|
+
* name is `${toKebab(appName)}.local` per the implementation-defined
|
|
306
|
+
* derivation rule; v1 has no override config option (D29). Returns the
|
|
307
|
+
* `IPrivateDnsNamespace` interface per D18(a), never the concrete class.
|
|
308
|
+
*/
|
|
309
|
+
getNamespace() {
|
|
310
|
+
return this.ensureNamespace().getNamespace();
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Register a Cloud Map service against the per-app namespace. Lazily creates
|
|
314
|
+
* the namespace on first call (same construct as `getNamespace()`) and
|
|
315
|
+
* delegates to the `ServiceDiscoveryNamespace` wrapper's `registerService`
|
|
316
|
+
* — keeping both halves of Cloud Map (namespace + services) routed through
|
|
317
|
+
* the wrapper layer per § Wrapper Routing Discipline.
|
|
318
|
+
*/
|
|
319
|
+
registerService(props) {
|
|
320
|
+
return this.ensureNamespace().registerService(props);
|
|
321
|
+
}
|
|
322
|
+
ensureNamespace() {
|
|
323
|
+
if (this.defaultNamespace) {
|
|
324
|
+
return this.defaultNamespace;
|
|
325
|
+
}
|
|
326
|
+
const networkStack = this.getDefaultNetworkStack();
|
|
327
|
+
const namespace = new ServiceDiscoveryNamespace(networkStack.getStack(), `${this.stackPrefix}Namespace`, {
|
|
328
|
+
vpc: this.getVpc(),
|
|
329
|
+
name: `${toKebab(this.name)}.local`
|
|
330
|
+
});
|
|
331
|
+
networkStack.addConstruct(namespace);
|
|
332
|
+
this.defaultNamespace = namespace;
|
|
333
|
+
return namespace;
|
|
334
|
+
}
|
|
335
335
|
/**
|
|
336
336
|
* Create a cross-account audit role in the Network stack that allows
|
|
337
337
|
* the Fjall platform to use CloudQuery for comprehensive AWS resource auditing.
|
|
@@ -341,7 +341,6 @@ export class App extends CdkApp {
|
|
|
341
341
|
*
|
|
342
342
|
* @param webappAccountId - Optional AWS account ID of the Fjall webapp. Defaults to configured platform account.
|
|
343
343
|
* @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
344
|
*/
|
|
346
345
|
createAuditRole(webappAccountId, externalId) {
|
|
347
346
|
if (!this.defaultAuditRole) {
|
|
@@ -361,17 +360,9 @@ export class App extends CdkApp {
|
|
|
361
360
|
}
|
|
362
361
|
return this.defaultAuditRole;
|
|
363
362
|
}
|
|
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
363
|
getAuditRoleExternalId() {
|
|
369
364
|
return this.auditRoleExternalId;
|
|
370
365
|
}
|
|
371
|
-
/**
|
|
372
|
-
* Generate a unique external ID for audit role
|
|
373
|
-
* Format: fjall-audit-{appName}-{timestamp}
|
|
374
|
-
*/
|
|
375
366
|
generateAuditExternalId() {
|
|
376
367
|
const uniqueId = randomBytes(8).toString("hex");
|
|
377
368
|
return `fjall-audit-${toKebab(this.name)}-${uniqueId}`;
|
|
@@ -406,9 +397,6 @@ export class App extends CdkApp {
|
|
|
406
397
|
computeStack.addConstruct(construct);
|
|
407
398
|
return construct;
|
|
408
399
|
}
|
|
409
|
-
/**
|
|
410
|
-
* Manually add a resource to the default compute stack.
|
|
411
|
-
*/
|
|
412
400
|
addComputeResource(resource) {
|
|
413
401
|
const computeStack = this.getDefaultComputeStack();
|
|
414
402
|
computeStack.addConstruct(resource);
|
|
@@ -443,9 +431,6 @@ export class App extends CdkApp {
|
|
|
443
431
|
}
|
|
444
432
|
return databaseConstruct;
|
|
445
433
|
}
|
|
446
|
-
/**
|
|
447
|
-
* Type guard for IConnectable — checks if a construct has a connections property.
|
|
448
|
-
*/
|
|
449
434
|
isConnectable(construct) {
|
|
450
435
|
return (typeof construct === "object" &&
|
|
451
436
|
construct !== null &&
|
|
@@ -509,6 +494,32 @@ export class App extends CdkApp {
|
|
|
509
494
|
cdnStack.addConstruct(cdn);
|
|
510
495
|
return cdn;
|
|
511
496
|
}
|
|
497
|
+
/**
|
|
498
|
+
* Peer this app's VPC with a remote app's VPC.
|
|
499
|
+
*
|
|
500
|
+
* Creates the peering connection plus routes on both sides. The remote app
|
|
501
|
+
* must have deployed a `VpcPeerAccepter` first. Note: `app.getVpc(peerAppName)`
|
|
502
|
+
* does NOT return the peer's VPC — callers wanting the remote handle must use
|
|
503
|
+
* the returned `VpcPeer` instance.
|
|
504
|
+
*/
|
|
505
|
+
addVpcPeer(fn) {
|
|
506
|
+
const networkStack = this.getDefaultNetworkStack();
|
|
507
|
+
const peer = fn(this, networkStack.getStack());
|
|
508
|
+
networkStack.addConstruct(peer);
|
|
509
|
+
return peer;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Accept VPC peering requests from remote apps.
|
|
513
|
+
*
|
|
514
|
+
* Creates an IAM role for cross-account peering acceptance and return-route
|
|
515
|
+
* management, and publishes VPC metadata to SSM for discovery.
|
|
516
|
+
*/
|
|
517
|
+
addVpcPeerAccepter(fn) {
|
|
518
|
+
const networkStack = this.getDefaultNetworkStack();
|
|
519
|
+
const accepter = fn(this, networkStack.getStack());
|
|
520
|
+
networkStack.addConstruct(accepter);
|
|
521
|
+
return accepter;
|
|
522
|
+
}
|
|
512
523
|
/**
|
|
513
524
|
* Add a messaging resource to the default queue stack using the factory pattern.
|
|
514
525
|
*
|
|
@@ -540,6 +551,32 @@ export class App extends CdkApp {
|
|
|
540
551
|
messagingStack.addConstruct(messaging);
|
|
541
552
|
return messaging;
|
|
542
553
|
}
|
|
554
|
+
/**
|
|
555
|
+
* Register an EventBridge schedule against a Fjall wrapper target.
|
|
556
|
+
*
|
|
557
|
+
* Defaults to the messaging stack; set `props.stackPlacement = "compute"`
|
|
558
|
+
* when the schedule's target lives in the compute stack and cross-stack
|
|
559
|
+
* output churn is undesired. `applicationId` is threaded automatically
|
|
560
|
+
* from `app.getName()` for alarm webhook routing per D13.
|
|
561
|
+
*
|
|
562
|
+
* @example
|
|
563
|
+
* app.addSchedule("MetricsCollection", {
|
|
564
|
+
* schedule: "rate(5 minutes)",
|
|
565
|
+
* target: notificationsQueue
|
|
566
|
+
* });
|
|
567
|
+
*/
|
|
568
|
+
addSchedule(id, props) {
|
|
569
|
+
const stack = props.stackPlacement === "compute"
|
|
570
|
+
? this.getDefaultComputeStack()
|
|
571
|
+
: this.getDefaultMessagingStack();
|
|
572
|
+
const schedule = new Schedule(stack.getStack(), id, {
|
|
573
|
+
...props,
|
|
574
|
+
applicationId: this.getName(),
|
|
575
|
+
appName: props.appName ?? this.getName()
|
|
576
|
+
});
|
|
577
|
+
stack.addConstruct(schedule);
|
|
578
|
+
return schedule;
|
|
579
|
+
}
|
|
543
580
|
/**
|
|
544
581
|
* Add a high-level infrastructure pattern to the application.
|
|
545
582
|
*
|
|
@@ -580,7 +617,6 @@ export class App extends CdkApp {
|
|
|
580
617
|
* Additional VPCs can be retrieved by name using app.getVpc(name).
|
|
581
618
|
*
|
|
582
619
|
* @param fn - Factory function that creates the Network construct
|
|
583
|
-
* @returns {Network} The created Network construct
|
|
584
620
|
*
|
|
585
621
|
* @example
|
|
586
622
|
* const isolatedVpc = app.addNetwork(
|
|
@@ -596,33 +632,19 @@ export class App extends CdkApp {
|
|
|
596
632
|
networkStack.addConstruct(network);
|
|
597
633
|
return network;
|
|
598
634
|
}
|
|
599
|
-
/**
|
|
600
|
-
* Manually add a resource to the default database stack.
|
|
601
|
-
*/
|
|
602
635
|
addDatabaseResource(resource) {
|
|
603
636
|
const databaseStack = this.getDefaultDatabaseStack();
|
|
604
637
|
databaseStack.addConstruct(resource);
|
|
605
638
|
}
|
|
606
|
-
/**
|
|
607
|
-
* Manually add a resource to the default storage stack.
|
|
608
|
-
*/
|
|
609
639
|
addStorageResource(resource) {
|
|
610
640
|
const storageStack = this.getDefaultStorageStack();
|
|
611
641
|
storageStack.addConstruct(resource);
|
|
612
642
|
}
|
|
613
|
-
/**
|
|
614
|
-
* Initialise standard tags
|
|
615
|
-
*/
|
|
616
643
|
initialiseStandardTags() {
|
|
617
644
|
const config = getConfig();
|
|
618
|
-
this.globalTags =
|
|
619
|
-
|
|
620
|
-
[COST_ALLOCATION_SERVICE_TAG]: this.name
|
|
621
|
-
};
|
|
645
|
+
this.globalTags[COST_ALLOCATION_TAGS.ENVIRONMENT] = config.environment;
|
|
646
|
+
this.globalTags[COST_ALLOCATION_TAGS.SERVICE] = this.name;
|
|
622
647
|
}
|
|
623
|
-
/**
|
|
624
|
-
* Apply all tags using CDK's native Tags.of().add() API
|
|
625
|
-
*/
|
|
626
648
|
applyTagsAspect() {
|
|
627
649
|
if (!this.aspectApplied && Object.keys(this.globalTags).length > 0) {
|
|
628
650
|
// Apply standard tags using Tags.of(this).add()
|
|
@@ -641,7 +663,7 @@ export class App extends CdkApp {
|
|
|
641
663
|
* @example
|
|
642
664
|
* app.addTags({
|
|
643
665
|
* "fjall:costAllocation:owner": "platform-team",
|
|
644
|
-
* "fjall:costAllocation:cost-
|
|
666
|
+
* "fjall:costAllocation:cost-centre": "CC-123",
|
|
645
667
|
* "team:slack-channel": "#platform-alerts"
|
|
646
668
|
* });
|
|
647
669
|
*/
|
|
@@ -656,11 +678,7 @@ export class App extends CdkApp {
|
|
|
656
678
|
}
|
|
657
679
|
return this;
|
|
658
680
|
}
|
|
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
|
-
*/
|
|
681
|
+
/** Call after app.synth() — inventory is not available before synthesis. */
|
|
664
682
|
exportResourceInventory() {
|
|
665
683
|
if (!this.resourceInventory) {
|
|
666
684
|
throw new Error("Resource inventory not available. Ensure a ResourceInventoryAspect has been added before calling exportResourceInventory().");
|
|
@@ -671,16 +689,9 @@ export class App extends CdkApp {
|
|
|
671
689
|
appName: this.name
|
|
672
690
|
};
|
|
673
691
|
}
|
|
674
|
-
/**
|
|
675
|
-
* Get the manifest collector for registering services and patterns.
|
|
676
|
-
* Used by ComputeFactory and PatternFactory to register their configurations.
|
|
677
|
-
*/
|
|
678
692
|
getManifestCollector() {
|
|
679
693
|
return this.manifestCollector;
|
|
680
694
|
}
|
|
681
|
-
/**
|
|
682
|
-
* Override synth to automatically export resource inventory and manifest
|
|
683
|
-
*/
|
|
684
695
|
synth(options) {
|
|
685
696
|
// Call parent synth first
|
|
686
697
|
const assembly = super.synth(options);
|
|
@@ -689,9 +700,8 @@ export class App extends CdkApp {
|
|
|
689
700
|
writeManifest(assembly, this.manifestCollector);
|
|
690
701
|
}
|
|
691
702
|
catch (error) {
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
FjallLogger.warn(`Failed to export Fjall manifest: ${errorMessage}`);
|
|
703
|
+
const maskedMessage = maskSensitiveOutput(error instanceof Error ? error.message : String(error));
|
|
704
|
+
FjallLogger.warn(`Failed to export Fjall manifest: ${maskedMessage}`);
|
|
695
705
|
}
|
|
696
706
|
return assembly;
|
|
697
707
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { CfnOutput } from "aws-cdk-lib";
|
|
2
|
-
import * as sns from "aws-cdk-lib/aws-sns";
|
|
3
2
|
import { Construct } from "constructs";
|
|
3
|
+
import { SNSTopic } from "../../resources/aws/messaging/sns.js";
|
|
4
4
|
export class SharedAlarmTopic extends Construct {
|
|
5
5
|
topic;
|
|
6
6
|
topicArn;
|
|
7
7
|
constructor(scope, id) {
|
|
8
8
|
super(scope, id);
|
|
9
|
-
const
|
|
9
|
+
const wrapped = new SNSTopic(this, "AlarmNotifications", {
|
|
10
10
|
displayName: "Fjall CloudWatch Alarm Notifications"
|
|
11
11
|
});
|
|
12
|
-
this.topic =
|
|
12
|
+
this.topic = wrapped.getTopic();
|
|
13
|
+
// SharedAlarmTopicArn is a well-known cross-stack export consumed via
|
|
14
|
+
// Fn.importValue (see resolveAlertsTopic + its tests). Do not delete
|
|
15
|
+
// thinking it duplicates the wrapper's AlarmNotificationsTopicArn —
|
|
16
|
+
// the wrapper's auto-output has no exportName and cannot be imported.
|
|
13
17
|
this.topicArn = new CfnOutput(this, "SharedAlarmTopicArn", {
|
|
14
18
|
key: "SharedAlarmTopicArn",
|
|
15
|
-
value:
|
|
19
|
+
value: wrapped.getTopicArn(),
|
|
16
20
|
exportName: "SharedAlarmTopicArn"
|
|
17
21
|
});
|
|
18
22
|
}
|
|
@@ -3,7 +3,7 @@ import { Trail } from "../../resources/aws/logging/cloudTrail.js";
|
|
|
3
3
|
export class ManagementEventsTrail extends Construct {
|
|
4
4
|
constructor(scope, id, props) {
|
|
5
5
|
super(scope, id);
|
|
6
|
-
new Trail(this, "
|
|
6
|
+
new Trail(this, "ManagementEventsTrail", {
|
|
7
7
|
bucketName: `cloudtrail-management-events-${props.accountId}-${props.region}`,
|
|
8
8
|
trailName: "managementEvents",
|
|
9
9
|
isMultiRegionTrail: true
|
|
@@ -2,10 +2,10 @@ import { CfnOutput, Duration, RemovalPolicy } from "aws-cdk-lib";
|
|
|
2
2
|
import { Construct } from "constructs";
|
|
3
3
|
import { BackupVault, BackupPlan } from "../../resources/aws/backup/index.js";
|
|
4
4
|
import { BackupPlanRule, BackupVault as Vault } from "aws-cdk-lib/aws-backup";
|
|
5
|
-
import
|
|
5
|
+
import { cronSchedule } from "../../resources/aws/messaging/index.js";
|
|
6
6
|
import { AccountPrincipal, Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
7
|
+
import { getConfig } from "../../utils/getConfig.js";
|
|
8
|
+
import { toPascalCase } from "../../utils/capitaliseString.js";
|
|
9
9
|
// Backup retention constants (in days)
|
|
10
10
|
const RETENTION_PERIODS = {
|
|
11
11
|
STANDARD: 90,
|
|
@@ -34,16 +34,11 @@ export class DisasterRecovery extends Construct {
|
|
|
34
34
|
customBackupPlans;
|
|
35
35
|
constructor(scope, id, props) {
|
|
36
36
|
super(scope, id);
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const orgConfigRaw = app.node.tryGetContext("orgConfig");
|
|
40
|
-
const orgConfig = parseOrgConfig(typeof orgConfigRaw === "string" ? orgConfigRaw : undefined);
|
|
41
|
-
const providerAccounts = orgConfig.providerAccounts;
|
|
42
|
-
// Determine if this is a compliance account
|
|
37
|
+
const config = getConfig();
|
|
38
|
+
const providerAccounts = config.providerAccounts;
|
|
43
39
|
const account = providerAccounts.find((pa) => pa.id === props.accountId);
|
|
44
40
|
const isComplianceAccount = account?.environment === "compliance";
|
|
45
|
-
|
|
46
|
-
const disasterRecoveryRegion = orgConfig.disasterRecoveryRegion;
|
|
41
|
+
const disasterRecoveryRegion = config.disasterRecoveryRegion;
|
|
47
42
|
// Look up compliance account for cross-account replication
|
|
48
43
|
// Skip if the compliance account (prevent self-replication)
|
|
49
44
|
const disasterRecoveryAccount = isComplianceAccount
|
|
@@ -110,7 +105,7 @@ export class DisasterRecovery extends Construct {
|
|
|
110
105
|
// Create custom backup plans if provided
|
|
111
106
|
if (props.customBackupPlans && props.customBackupPlans.length > 0) {
|
|
112
107
|
this.customBackupPlans = props.customBackupPlans.map((config) => {
|
|
113
|
-
return new BackupPlan(this, `CustomBackupPlan
|
|
108
|
+
return new BackupPlan(this, `CustomBackupPlan${toPascalCase(config.planName)}`, {
|
|
114
109
|
planName: config.planName,
|
|
115
110
|
rules: config.rules,
|
|
116
111
|
tagValue: config.tagValue,
|
|
@@ -143,7 +138,7 @@ export class DisasterRecovery extends Construct {
|
|
|
143
138
|
return [
|
|
144
139
|
new BackupPlanRule({
|
|
145
140
|
ruleName: `${planName}Daily`,
|
|
146
|
-
scheduleExpression:
|
|
141
|
+
scheduleExpression: cronSchedule({ hour: "2", minute: "0" }), // 2 AM daily
|
|
147
142
|
deleteAfter: Duration.days(RETENTION_PERIODS.STANDARD),
|
|
148
143
|
startWindow: BACKUP_WINDOWS.START,
|
|
149
144
|
completionWindow: BACKUP_WINDOWS.COMPLETION
|
|
@@ -155,7 +150,7 @@ export class DisasterRecovery extends Construct {
|
|
|
155
150
|
return [
|
|
156
151
|
new BackupPlanRule({
|
|
157
152
|
ruleName: `${planName}Daily`,
|
|
158
|
-
scheduleExpression:
|
|
153
|
+
scheduleExpression: cronSchedule({ hour: "2", minute: "0" }), // 2 AM daily
|
|
159
154
|
deleteAfter: Duration.days(RETENTION_PERIODS.ENTERPRISE_CONTINUOUS),
|
|
160
155
|
enableContinuousBackup: true,
|
|
161
156
|
startWindow: BACKUP_WINDOWS.START,
|
|
@@ -171,7 +166,7 @@ export class DisasterRecovery extends Construct {
|
|
|
171
166
|
// Continuous backup (35-day max PITR window)
|
|
172
167
|
new BackupPlanRule({
|
|
173
168
|
ruleName: `${planName}Continuous`,
|
|
174
|
-
scheduleExpression:
|
|
169
|
+
scheduleExpression: cronSchedule({ hour: "2", minute: "0" }), // Daily for continuous backup
|
|
175
170
|
deleteAfter: Duration.days(RETENTION_PERIODS.ENTERPRISE_CONTINUOUS),
|
|
176
171
|
enableContinuousBackup: true,
|
|
177
172
|
startWindow: BACKUP_WINDOWS.START,
|
|
@@ -181,7 +176,7 @@ export class DisasterRecovery extends Construct {
|
|
|
181
176
|
// Hourly snapshots for long-term compliance (7 years)
|
|
182
177
|
new BackupPlanRule({
|
|
183
178
|
ruleName: `${planName}HourlyCompliance`,
|
|
184
|
-
scheduleExpression:
|
|
179
|
+
scheduleExpression: cronSchedule({ minute: "0" }), // Every hour
|
|
185
180
|
deleteAfter: Duration.days(RETENTION_PERIODS.ENTERPRISE_COMPLIANCE),
|
|
186
181
|
moveToColdStorageAfter: Duration.days(RETENTION_PERIODS.COLD_STORAGE_ONE_YEAR),
|
|
187
182
|
startWindow: BACKUP_WINDOWS.START,
|
|
@@ -3,7 +3,6 @@ import { type StackProps } from "aws-cdk-lib";
|
|
|
3
3
|
interface EcrDefaultImageProps extends StackProps {
|
|
4
4
|
region: string;
|
|
5
5
|
accountId: string;
|
|
6
|
-
eventBusArn: string;
|
|
7
6
|
}
|
|
8
7
|
export declare class EcrDefaultImage extends Construct {
|
|
9
8
|
constructor(scope: Construct, id: string, props: EcrDefaultImageProps);
|