@fjall/components-infrastructure 37.0.0 → 39.0.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 +52 -12
- package/dist/lib/app.js +60 -24
- package/dist/lib/config/aws/configRecorder.js +3 -0
- package/dist/lib/config/aws/disasterRecovery.d.ts +1 -2
- package/dist/lib/config/aws/disasterRecovery.js +167 -45
- package/dist/lib/patterns/aws/buildkite/buildkite.js +7 -2
- package/dist/lib/patterns/aws/cdn.d.ts +19 -11
- package/dist/lib/patterns/aws/cdn.js +53 -25
- package/dist/lib/patterns/aws/clickhouseDatabase.js +8 -4
- package/dist/lib/patterns/aws/computeEcs.js +17 -1
- package/dist/lib/patterns/aws/computeEcsTypes.d.ts +30 -4
- package/dist/lib/patterns/aws/computePropApplicability.js +1 -0
- package/dist/lib/patterns/aws/domain.js +3 -3
- package/dist/lib/patterns/aws/externalRecordsPattern.d.ts +9 -6
- package/dist/lib/patterns/aws/externalRecordsPattern.js +22 -46
- package/dist/lib/patterns/aws/interfaces/domain.d.ts +8 -5
- package/dist/lib/patterns/aws/interfaces/pattern.d.ts +9 -10
- package/dist/lib/patterns/aws/messaging.d.ts +10 -0
- package/dist/lib/patterns/aws/messaging.js +10 -6
- package/dist/lib/patterns/aws/payload.d.ts +5 -0
- package/dist/lib/patterns/aws/payload.js +23 -11
- package/dist/lib/patterns/aws/storage.d.ts +41 -0
- package/dist/lib/patterns/aws/storage.js +23 -8
- package/dist/lib/patterns/aws/targets/targetResolution.d.ts +4 -4
- package/dist/lib/patterns/aws/targets/targetResolution.js +4 -4
- package/dist/lib/resources/aws/backup/backupVault.d.ts +27 -2
- package/dist/lib/resources/aws/backup/backupVault.js +49 -6
- package/dist/lib/resources/aws/cdn/cloudFront.d.ts +42 -18
- package/dist/lib/resources/aws/cdn/cloudFront.js +39 -51
- package/dist/lib/resources/aws/cdn/cloudFrontLogDelivery.d.ts +90 -0
- package/dist/lib/resources/aws/cdn/cloudFrontLogDelivery.js +213 -0
- package/dist/lib/resources/aws/cdn/index.d.ts +1 -0
- package/dist/lib/resources/aws/cdn/index.js +1 -0
- package/dist/lib/resources/aws/compute/ecs.d.ts +7 -4
- package/dist/lib/resources/aws/compute/ecs.js +27 -21
- package/dist/lib/resources/aws/compute/ecsServiceFactory.js +3 -0
- package/dist/lib/resources/aws/compute/ecsTypes.d.ts +11 -0
- package/dist/lib/resources/aws/compute/ecsValidation.d.ts +8 -0
- package/dist/lib/resources/aws/compute/ecsValidation.js +8 -0
- package/dist/lib/resources/aws/compute/persistentDataVolume.d.ts +8 -0
- package/dist/lib/resources/aws/compute/persistentDataVolume.js +2 -0
- package/dist/lib/resources/aws/database/dynamodb.js +2 -1
- package/dist/lib/resources/aws/database/rdsAurora.js +6 -1
- package/dist/lib/resources/aws/database/rdsInstance.js +6 -1
- package/dist/lib/resources/aws/logging/accessLogBucket.d.ts +15 -8
- package/dist/lib/resources/aws/logging/accessLogBucket.js +16 -9
- package/dist/lib/resources/aws/logging/cloudTrail.js +3 -0
- package/dist/lib/resources/aws/messaging/eventBridgeQueueGrants.d.ts +16 -0
- package/dist/lib/resources/aws/messaging/eventBridgeQueueGrants.js +91 -0
- package/dist/lib/resources/aws/messaging/eventBridgeRule.js +36 -5
- package/dist/lib/resources/aws/messaging/eventTargets.d.ts +4 -3
- package/dist/lib/resources/aws/messaging/eventTargets.js +71 -31
- package/dist/lib/resources/aws/messaging/queuePolicyQuota.d.ts +25 -0
- package/dist/lib/resources/aws/messaging/queuePolicyQuota.js +190 -0
- package/dist/lib/resources/aws/messaging/schedule.d.ts +5 -5
- package/dist/lib/resources/aws/messaging/sqs.d.ts +36 -1
- package/dist/lib/resources/aws/messaging/sqs.js +40 -2
- package/dist/lib/resources/aws/messaging/subscription.d.ts +4 -3
- package/dist/lib/resources/aws/networking/vpc.js +12 -6
- package/dist/lib/resources/aws/secrets/stackEncryptionKey.d.ts +26 -1
- package/dist/lib/resources/aws/secrets/stackEncryptionKey.js +56 -1
- package/dist/lib/resources/aws/storage/s3.d.ts +21 -1
- package/dist/lib/resources/aws/storage/s3.js +89 -3
- package/dist/lib/utils/backupTierMapping.d.ts +23 -2
- package/dist/lib/utils/backupTierMapping.js +25 -0
- package/dist/lib/utils/cdkContext.d.ts +14 -0
- package/dist/lib/utils/cdkContext.js +38 -1
- package/dist/lib/utils/exportNaming.d.ts +30 -27
- package/dist/lib/utils/exportNaming.js +32 -28
- package/dist/lib/utils/standardTagsAspect.d.ts +8 -18
- package/dist/lib/utils/standardTagsAspect.js +8 -34
- package/package.json +4 -4
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
import type { Construct } from "constructs";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Construct-side adapter for the stack-qualified export names whose contract
|
|
4
|
+
* is `@fjall/util`'s `stackExportNames` module.
|
|
4
5
|
*
|
|
5
|
-
* Export names are unique per account per region, so a name built only from
|
|
6
|
-
* construct id or a cluster name is shared by every app that happens to use
|
|
7
|
-
* the same id — and the ids inside a pattern are literals the app author
|
|
8
|
-
* chooses. Two apps then collide, and the second one fails at
|
|
9
|
-
* execution ("Export with name X is already exported by stack
|
|
10
|
-
* first resources exist, so it rolls back rather than refusing
|
|
6
|
+
* Export names are unique per account per region, so a name built only from
|
|
7
|
+
* a construct id or a cluster name is shared by every app that happens to use
|
|
8
|
+
* the same id — and the ids inside a pattern are literals the app author
|
|
9
|
+
* never chooses. Two apps then collide, and the second one fails at
|
|
10
|
+
* CloudFormation execution ("Export with name X is already exported by stack
|
|
11
|
+
* Y") after its first resources exist, so it rolls back rather than refusing
|
|
12
|
+
* up front. Stack names are already unique per account+region and Fjall
|
|
13
|
+
* derives them from the app name, so qualifying with the stack makes the
|
|
14
|
+
* export unique AND puts the app name in it.
|
|
11
15
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
16
|
+
* `@fjall/util` owns the composition — `stackScopedExportName` and the
|
|
17
|
+
* builders on top of it (`deployableServiceExportName`,
|
|
18
|
+
* `deployableClusterExportName`, `clusterArnExportName`,
|
|
19
|
+
* `vpcCidrExportName`) — so the runtime consumers that read an export back
|
|
20
|
+
* (deploy-core's `EcsServiceResolver`, the fjall.io webapp's VPC CIDR
|
|
21
|
+
* capture) rebuild the exact name through the same function the construct
|
|
22
|
+
* emitted it with. This helper only supplies the stack: a construct passes
|
|
23
|
+
* itself and the suffix is qualified with the stack it lives in. An export a
|
|
24
|
+
* consumer rebuilds by whole name goes through its specific builder with
|
|
25
|
+
* `Stack.of(this).stackName`, never through this generic form.
|
|
15
26
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* `
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* with their own vocabulary module and must keep their exact spelling:
|
|
26
|
-
* `getDomainExportNames` (@fjall/util), `EXPORT_NAMES`
|
|
27
|
-
* (patterns/aws/targets/targetResolution.ts), `SHARED_ALARM_TOPIC_EXPORT_NAME`,
|
|
28
|
-
* the CloudTrail output keys, and `${toPascalCase(appName)}EcrRepositoryName`
|
|
29
|
-
* (read by `resolveEcrRepositoryName` in the CLI). Account-level singletons
|
|
30
|
-
* (`AccountId`, `Environment`, `OrganisationId`, `FjallAuditRoleArn`, …) also
|
|
31
|
-
* keep their bare names: exactly one is meant to exist, so a collision there
|
|
32
|
-
* correctly reports a duplicate deployment.
|
|
27
|
+
* NOT for exports a consumer reconstructs from its own vocabulary module.
|
|
28
|
+
* Those keep their exact spelling: `getDomainExportNames` (@fjall/util),
|
|
29
|
+
* `EXPORT_NAMES` (patterns/aws/targets/targetResolution.ts),
|
|
30
|
+
* `SHARED_ALARM_TOPIC_EXPORT_NAME`, the CloudTrail output keys, and
|
|
31
|
+
* `${toPascalCase(appName)}EcrRepositoryName` (read by
|
|
32
|
+
* `resolveEcrRepositoryName` in the CLI). Account-level singletons
|
|
33
|
+
* (`AccountId`, `Environment`, `OrganisationId`, `FjallAuditRoleArn`, …)
|
|
34
|
+
* also keep their bare names: exactly one is meant to exist, so a collision
|
|
35
|
+
* there correctly reports a duplicate deployment.
|
|
33
36
|
*/
|
|
34
37
|
export declare function stackScopedExportName(scope: Construct, suffix: string): string;
|
|
35
38
|
/**
|
|
@@ -1,38 +1,42 @@
|
|
|
1
1
|
import { Stack } from "aws-cdk-lib";
|
|
2
|
+
import { stackScopedExportName as qualifyWithStack } from "@fjall/util";
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
+
* Construct-side adapter for the stack-qualified export names whose contract
|
|
5
|
+
* is `@fjall/util`'s `stackExportNames` module.
|
|
4
6
|
*
|
|
5
|
-
* Export names are unique per account per region, so a name built only from
|
|
6
|
-
* construct id or a cluster name is shared by every app that happens to use
|
|
7
|
-
* the same id — and the ids inside a pattern are literals the app author
|
|
8
|
-
* chooses. Two apps then collide, and the second one fails at
|
|
9
|
-
* execution ("Export with name X is already exported by stack
|
|
10
|
-
* first resources exist, so it rolls back rather than refusing
|
|
7
|
+
* Export names are unique per account per region, so a name built only from
|
|
8
|
+
* a construct id or a cluster name is shared by every app that happens to use
|
|
9
|
+
* the same id — and the ids inside a pattern are literals the app author
|
|
10
|
+
* never chooses. Two apps then collide, and the second one fails at
|
|
11
|
+
* CloudFormation execution ("Export with name X is already exported by stack
|
|
12
|
+
* Y") after its first resources exist, so it rolls back rather than refusing
|
|
13
|
+
* up front. Stack names are already unique per account+region and Fjall
|
|
14
|
+
* derives them from the app name, so qualifying with the stack makes the
|
|
15
|
+
* export unique AND puts the app name in it.
|
|
11
16
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
17
|
+
* `@fjall/util` owns the composition — `stackScopedExportName` and the
|
|
18
|
+
* builders on top of it (`deployableServiceExportName`,
|
|
19
|
+
* `deployableClusterExportName`, `clusterArnExportName`,
|
|
20
|
+
* `vpcCidrExportName`) — so the runtime consumers that read an export back
|
|
21
|
+
* (deploy-core's `EcsServiceResolver`, the fjall.io webapp's VPC CIDR
|
|
22
|
+
* capture) rebuild the exact name through the same function the construct
|
|
23
|
+
* emitted it with. This helper only supplies the stack: a construct passes
|
|
24
|
+
* itself and the suffix is qualified with the stack it lives in. An export a
|
|
25
|
+
* consumer rebuilds by whole name goes through its specific builder with
|
|
26
|
+
* `Stack.of(this).stackName`, never through this generic form.
|
|
15
27
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* `
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* with their own vocabulary module and must keep their exact spelling:
|
|
26
|
-
* `getDomainExportNames` (@fjall/util), `EXPORT_NAMES`
|
|
27
|
-
* (patterns/aws/targets/targetResolution.ts), `SHARED_ALARM_TOPIC_EXPORT_NAME`,
|
|
28
|
-
* the CloudTrail output keys, and `${toPascalCase(appName)}EcrRepositoryName`
|
|
29
|
-
* (read by `resolveEcrRepositoryName` in the CLI). Account-level singletons
|
|
30
|
-
* (`AccountId`, `Environment`, `OrganisationId`, `FjallAuditRoleArn`, …) also
|
|
31
|
-
* keep their bare names: exactly one is meant to exist, so a collision there
|
|
32
|
-
* correctly reports a duplicate deployment.
|
|
28
|
+
* NOT for exports a consumer reconstructs from its own vocabulary module.
|
|
29
|
+
* Those keep their exact spelling: `getDomainExportNames` (@fjall/util),
|
|
30
|
+
* `EXPORT_NAMES` (patterns/aws/targets/targetResolution.ts),
|
|
31
|
+
* `SHARED_ALARM_TOPIC_EXPORT_NAME`, the CloudTrail output keys, and
|
|
32
|
+
* `${toPascalCase(appName)}EcrRepositoryName` (read by
|
|
33
|
+
* `resolveEcrRepositoryName` in the CLI). Account-level singletons
|
|
34
|
+
* (`AccountId`, `Environment`, `OrganisationId`, `FjallAuditRoleArn`, …)
|
|
35
|
+
* also keep their bare names: exactly one is meant to exist, so a collision
|
|
36
|
+
* there correctly reports a duplicate deployment.
|
|
33
37
|
*/
|
|
34
38
|
export function stackScopedExportName(scope, suffix) {
|
|
35
|
-
return
|
|
39
|
+
return qualifyWithStack(Stack.of(scope).stackName, suffix);
|
|
36
40
|
}
|
|
37
41
|
/**
|
|
38
42
|
* Export name for the account's IPAM private default scope.
|
|
@@ -5,12 +5,19 @@ import { type IConstruct } from "constructs";
|
|
|
5
5
|
*
|
|
6
6
|
* This aspect handles tags that depend on resource-specific properties:
|
|
7
7
|
* - fjall:operations:pool on VPCs with IPAM configuration
|
|
8
|
-
* - fjall:disasterRecovery:tier on S3 buckets with backup configuration
|
|
9
8
|
*
|
|
10
9
|
* Standard Fjall tags (costAllocation:environment, costAllocation:service, etc.)
|
|
11
10
|
* are applied via Tags.of(app).add() in the App class, which properly merges
|
|
12
11
|
* with existing tags from L2 constructs.
|
|
13
12
|
*
|
|
13
|
+
* The disaster-recovery tier tag is NOT applied here. It is stamped at
|
|
14
|
+
* construction by the five constructs that own a backup-eligible resource
|
|
15
|
+
* (`tagBackupTier`), because an aspect can only reach the resource by walking
|
|
16
|
+
* up the scope chain — which cannot tell an Aurora cluster from its member
|
|
17
|
+
* instances, or a primary from its read replica — and because `Tags.of(...)`
|
|
18
|
+
* called inside `visit()` is an aspect adding an aspect, dropped silently when
|
|
19
|
+
* `aspectStabilization` is off.
|
|
20
|
+
*
|
|
14
21
|
* This aspect uses Tags.of(node).add() to properly merge with existing tags
|
|
15
22
|
*/
|
|
16
23
|
export declare class StandardTagsAspect implements IAspect {
|
|
@@ -21,21 +28,4 @@ export declare class StandardTagsAspect implements IAspect {
|
|
|
21
28
|
* Tag format: fjall:operations:pool = "{accountId}-{region}"
|
|
22
29
|
*/
|
|
23
30
|
private addIpamPoolTag;
|
|
24
|
-
/**
|
|
25
|
-
* Add the disaster recovery tier tag to S3 buckets from the bucket's
|
|
26
|
-
* effective tier — the per-bucket `backupVaultTier` override, else the
|
|
27
|
-
* app-level tier the factory threaded in. CDK child tags override parent
|
|
28
|
-
* tags, so an override wins over the app-level tag set via
|
|
29
|
-
* `App.getApp({ backup })`; an inherited app tier writes the value that tag
|
|
30
|
-
* already carries. The same resolution decides the bucket's versioning
|
|
31
|
-
* default (`S3Bucket`).
|
|
32
|
-
*
|
|
33
|
-
* Tag format: fjall:disasterRecovery:tier = "{tier}"
|
|
34
|
-
*
|
|
35
|
-
* Tier mapping:
|
|
36
|
-
* - standard -> "default" (matches existing backup plans)
|
|
37
|
-
* - resilient -> "resilient"
|
|
38
|
-
* - enterprise -> "enterprise"
|
|
39
|
-
*/
|
|
40
|
-
private addBackupTierTag;
|
|
41
31
|
}
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { CfnResource, Stack, Tags } from "aws-cdk-lib";
|
|
2
|
-
import { BACKUP_TIER_TAG_KEY, BACKUP_TIER_TAG_MAP } from "./backupTierMapping.js";
|
|
3
2
|
import { formatIpamPairTagValue, IPAM_OPERATIONS_POOL_TAG_KEY } from "@fjall/util/aws";
|
|
4
3
|
/**
|
|
5
4
|
* Aspect to apply special Fjall tags to specific resource types.
|
|
6
5
|
*
|
|
7
6
|
* This aspect handles tags that depend on resource-specific properties:
|
|
8
7
|
* - fjall:operations:pool on VPCs with IPAM configuration
|
|
9
|
-
* - fjall:disasterRecovery:tier on S3 buckets with backup configuration
|
|
10
8
|
*
|
|
11
9
|
* Standard Fjall tags (costAllocation:environment, costAllocation:service, etc.)
|
|
12
10
|
* are applied via Tags.of(app).add() in the App class, which properly merges
|
|
13
11
|
* with existing tags from L2 constructs.
|
|
14
12
|
*
|
|
13
|
+
* The disaster-recovery tier tag is NOT applied here. It is stamped at
|
|
14
|
+
* construction by the five constructs that own a backup-eligible resource
|
|
15
|
+
* (`tagBackupTier`), because an aspect can only reach the resource by walking
|
|
16
|
+
* up the scope chain — which cannot tell an Aurora cluster from its member
|
|
17
|
+
* instances, or a primary from its read replica — and because `Tags.of(...)`
|
|
18
|
+
* called inside `visit()` is an aspect adding an aspect, dropped silently when
|
|
19
|
+
* `aspectStabilization` is off.
|
|
20
|
+
*
|
|
15
21
|
* This aspect uses Tags.of(node).add() to properly merge with existing tags
|
|
16
22
|
*/
|
|
17
23
|
export class StandardTagsAspect {
|
|
@@ -31,9 +37,6 @@ export class StandardTagsAspect {
|
|
|
31
37
|
if (resource.cfnResourceType === "AWS::EC2::VPC") {
|
|
32
38
|
this.addIpamPoolTag(resource);
|
|
33
39
|
}
|
|
34
|
-
if (resource.cfnResourceType === "AWS::S3::Bucket") {
|
|
35
|
-
this.addBackupTierTag(resource);
|
|
36
|
-
}
|
|
37
40
|
}
|
|
38
41
|
/**
|
|
39
42
|
* Add IPAM pool tag to VPCs that use IPAM for IP address allocation.
|
|
@@ -53,33 +56,4 @@ export class StandardTagsAspect {
|
|
|
53
56
|
Tags.of(vpc).add(IPAM_OPERATIONS_POOL_TAG_KEY, formatIpamPairTagValue(accountId, region));
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Add the disaster recovery tier tag to S3 buckets from the bucket's
|
|
58
|
-
* effective tier — the per-bucket `backupVaultTier` override, else the
|
|
59
|
-
* app-level tier the factory threaded in. CDK child tags override parent
|
|
60
|
-
* tags, so an override wins over the app-level tag set via
|
|
61
|
-
* `App.getApp({ backup })`; an inherited app tier writes the value that tag
|
|
62
|
-
* already carries. The same resolution decides the bucket's versioning
|
|
63
|
-
* default (`S3Bucket`).
|
|
64
|
-
*
|
|
65
|
-
* Tag format: fjall:disasterRecovery:tier = "{tier}"
|
|
66
|
-
*
|
|
67
|
-
* Tier mapping:
|
|
68
|
-
* - standard -> "default" (matches existing backup plans)
|
|
69
|
-
* - resilient -> "resilient"
|
|
70
|
-
* - enterprise -> "enterprise"
|
|
71
|
-
*/
|
|
72
|
-
addBackupTierTag(resource) {
|
|
73
|
-
let construct = resource;
|
|
74
|
-
while (construct) {
|
|
75
|
-
const backupConstruct = construct;
|
|
76
|
-
if (backupConstruct.effectiveBackupTier) {
|
|
77
|
-
const tier = backupConstruct.effectiveBackupTier;
|
|
78
|
-
const tagValue = BACKUP_TIER_TAG_MAP[tier];
|
|
79
|
-
Tags.of(resource).add(BACKUP_TIER_TAG_KEY, tagValue);
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
construct = construct.node.scope;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
59
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/components-infrastructure",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "39.0.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/fjall-tech/fjall.git",
|
|
@@ -76,12 +76,12 @@
|
|
|
76
76
|
"reflect-metadata": "^0.2.2",
|
|
77
77
|
"tsx": "^4.23.1",
|
|
78
78
|
"typescript": "^6.0.3",
|
|
79
|
-
"vitest": "^4.1.
|
|
79
|
+
"vitest": "^4.1.11"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@aws-sdk/client-organizations": "^3.1098.0",
|
|
83
|
-
"@fjall/generator": "^
|
|
84
|
-
"@fjall/util": "^
|
|
83
|
+
"@fjall/generator": "^39.0.0",
|
|
84
|
+
"@fjall/util": "^39.0.0",
|
|
85
85
|
"constructs": "^10.7.2",
|
|
86
86
|
"zod": "^4.4.3"
|
|
87
87
|
},
|