@fjall/components-infrastructure 33.0.0 → 33.1.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/README.md +15 -76
- package/dist/lib/app.d.ts +1 -1
- package/dist/lib/config/aws/identityCentreConfig.d.ts +1 -1
- package/dist/lib/config/aws/identityCentreConfig.js +1 -1
- package/dist/lib/config/aws/scpPreset.js +1 -2
- package/dist/lib/lambda-assets/cert-generator/asset/index.js +126 -0
- package/dist/lib/patterns/aws/buildkite/buildkite.d.ts +1 -1
- package/dist/lib/patterns/aws/buildkite/buildkite.js +1 -1
- package/dist/lib/patterns/aws/buildkite/factory.d.ts +2 -2
- package/dist/lib/patterns/aws/buildkite/pins.d.ts +2 -2
- package/dist/lib/patterns/aws/buildkite/pins.js +2 -2
- package/dist/lib/patterns/aws/buildkite/schema.d.ts +1 -1
- package/dist/lib/patterns/aws/buildkite/schema.js +1 -1
- package/dist/lib/patterns/aws/buildkite/userData.d.ts +1 -1
- package/dist/lib/patterns/aws/buildkite/userData.js +1 -1
- package/dist/lib/patterns/aws/buildkite.d.ts +1 -1
- package/dist/lib/patterns/aws/buildkite.js +1 -1
- package/dist/lib/patterns/aws/clickhouseDatabase.js +4 -1
- package/dist/lib/patterns/aws/clickhouseTls/types.d.ts +1 -1
- package/dist/lib/patterns/aws/computeEcsTypes.d.ts +5 -5
- package/dist/lib/patterns/aws/payload.js +6 -2
- package/dist/lib/patterns/aws/storage.d.ts +8 -0
- package/dist/lib/patterns/aws/storage.js +1 -0
- package/dist/lib/resources/aws/cdn/responseHeadersPolicy.d.ts +1 -1
- package/dist/lib/resources/aws/cdn/responseHeadersPolicy.js +1 -1
- package/dist/lib/resources/aws/compute/ec2.d.ts +2 -2
- package/dist/lib/resources/aws/compute/ec2.js +1 -1
- package/dist/lib/resources/aws/database/clickhouseConstants.d.ts +5 -5
- package/dist/lib/resources/aws/database/clickhouseConstants.js +5 -5
- package/dist/lib/resources/aws/iam/identityCenter/user.d.ts +1 -1
- package/dist/lib/resources/aws/iam/identityCenter/user.js +1 -1
- package/dist/lib/resources/aws/storage/bucketDeployment.d.ts +2 -3
- package/dist/lib/resources/aws/storage/bucketDeployment.js +2 -3
- package/dist/lib/resources/aws/storage/s3.d.ts +13 -1
- package/dist/lib/resources/aws/storage/s3.js +6 -3
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -54,84 +54,23 @@ for each of the two secrets.
|
|
|
54
54
|
|
|
55
55
|
## Useful commands
|
|
56
56
|
|
|
57
|
-
- `npm run build` compile
|
|
58
|
-
- `npm run watch`
|
|
59
|
-
- `npm
|
|
60
|
-
- `
|
|
61
|
-
- `cdk diff` compare deployed stack with current state
|
|
62
|
-
- `cdk synth` emits the synthesized CloudFormation template
|
|
57
|
+
- `npm run build` — clean, bundle the Lambda assets and compile TypeScript to `dist/`
|
|
58
|
+
- `npm run watch` — recompile on change
|
|
59
|
+
- `npm test` — run the Vitest suites
|
|
60
|
+
- `npm run typecheck` — type-check the library
|
|
63
61
|
|
|
64
|
-
|
|
62
|
+
Synthesis and deployment go through the `fjall` CLI (`fjall deploy`), which
|
|
63
|
+
assembles the stacks from an application's `fjall/` directory. The package is
|
|
64
|
+
not deployed with `cdk deploy` on its own.
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
## Using the constructs
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
The constructs are consumed through the `fjall` CLI: `fjall create app` and
|
|
69
|
+
`fjall add <resource>` write the `infrastructure.ts` that composes them, and
|
|
70
|
+
`fjall deploy` synthesises and deploys it. Every construct is also exported
|
|
71
|
+
from the package root for direct use; the reference lives at
|
|
72
|
+
[docs.fjall.io](https://docs.fjall.io).
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
## Licence
|
|
71
75
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
When a VPC is created in the same stack resources that rely on it will automatically detect it.
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
new AwsStack(`${id}App`)
|
|
78
|
-
.addNetwork(FjallVpc.build(`${id}Vpc`))
|
|
79
|
-
.addConstruct(Fargate.build(`${id}Fargate`));
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
2. In the same CDK Application but different stack
|
|
83
|
-
|
|
84
|
-
When a VPC is created in the same application, but you want to use separate stacks, you can directly reference the vpc resource itself. This is easily
|
|
85
|
-
retrieved from an awsStack using `awsStack.getNetwork()`.
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
const vpcStack = new AwsStack(`${id}Network`).addNetwork(
|
|
89
|
-
FjallVpc.build(`${id}Vpc`)
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
const newStack = new AwsStack(`${id}Compute`, { dependencies: [vpcStack] })
|
|
93
|
-
.addNetwork(vpcStack.getNetwork())
|
|
94
|
-
.addConstruct(Fargate.build(`${id}Fargate`));
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
3. Different CDK Applications
|
|
98
|
-
|
|
99
|
-
If your VPC was created in a completely separate CDK Stack it can be imported using it's `id` and `stackName`. However this method
|
|
100
|
-
requires you explicitly configure your `AwsStack` with an `account` and `region.
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
const env = {
|
|
104
|
-
region: "us-east-1",
|
|
105
|
-
account: "123456789012"
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const vpcStack = new AwsStack(`${id}Network`, { ...env }).addNetwork(
|
|
109
|
-
FjallVpc.build(`${id}Vpc`)
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
const newStack = new AwsStack(`${id}Compute`, {
|
|
113
|
-
...env,
|
|
114
|
-
dependencies: [vpcStack]
|
|
115
|
-
})
|
|
116
|
-
.addNetwork(FjallVpc.import(`${id}Vpc`, `${id}Network`))
|
|
117
|
-
.addConstruct(Fargate.build(`${id}Fargate`));
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Publishing package to npm
|
|
121
|
-
|
|
122
|
-
Log into your NPM account locally (make sure you have 2fa setup before trying this)
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
npm login
|
|
126
|
-
> Username:
|
|
127
|
-
> Password
|
|
128
|
-
> Email
|
|
129
|
-
> 2Fa
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Update the version in ./package.json, build the package and then run publish command
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
npm run build
|
|
136
|
-
npm publish --access restricted
|
|
137
|
-
```
|
|
76
|
+
Proprietary — see [LICENSE](./LICENSE).
|
package/dist/lib/app.d.ts
CHANGED
|
@@ -311,7 +311,7 @@ export declare class App extends CdkApp {
|
|
|
311
311
|
addDevSubstrate(props: IDevSubstrateProps): DevSubstrate;
|
|
312
312
|
/**
|
|
313
313
|
* Instantiate the self-hosted Buildkite agent fleet on the default compute
|
|
314
|
-
* stack (design
|
|
314
|
+
* stack (design: the 2026-07-18 Buildkite self-hosted agents design).
|
|
315
315
|
*
|
|
316
316
|
* Same placement contract as `addDevSubstrate` above: deploy-core selects
|
|
317
317
|
* stacks by the fixed six-category enum, so scoping under
|
|
@@ -4,7 +4,7 @@ import { type DefaultPermissionSetName } from "@fjall/generator";
|
|
|
4
4
|
* construct. The discriminated union on `source` mirrors AWS ground truth:
|
|
5
5
|
* the identity source of an Identity Center instance is neither readable nor
|
|
6
6
|
* settable via any supported API, so the mode is user-declared and
|
|
7
|
-
* authoritative. Design:
|
|
7
|
+
* authoritative. Design: the 2026-07-04 organisation user-management design.
|
|
8
8
|
*
|
|
9
9
|
* The source vocabulary is canonical in @fjall/generator
|
|
10
10
|
* (organisationSchemas.ts) — re-exported here so existing consumers keep
|
|
@@ -5,7 +5,7 @@ import { stripAndCamelCase } from "../../utils/stripAndCamelCase.js";
|
|
|
5
5
|
* construct. The discriminated union on `source` mirrors AWS ground truth:
|
|
6
6
|
* the identity source of an Identity Center instance is neither readable nor
|
|
7
7
|
* settable via any supported API, so the mode is user-declared and
|
|
8
|
-
* authoritative. Design:
|
|
8
|
+
* authoritative. Design: the 2026-07-04 organisation user-management design.
|
|
9
9
|
*
|
|
10
10
|
* The source vocabulary is canonical in @fjall/generator
|
|
11
11
|
* (organisationSchemas.ts) — re-exported here so existing consumers keep
|
|
@@ -140,8 +140,7 @@ function buildFoundationGuardrails(allowedRegions) {
|
|
|
140
140
|
// assume-root sessions) are deliberately NOT carved out — recovery on
|
|
141
141
|
// this tier is a break-glass SCP detach, not a standing carve-out. Do
|
|
142
142
|
// not add them without revisiting the decision:
|
|
143
|
-
//
|
|
144
|
-
// § Scenario 3.
|
|
143
|
+
// the centralised root-access break-glass runbook, § Scenario 3.
|
|
145
144
|
NotAction: [
|
|
146
145
|
"s3:GetBucketPolicy",
|
|
147
146
|
"s3:PutBucketPolicy",
|
|
@@ -18117,3 +18117,129 @@ exports.handler = async (event) => {
|
|
|
18117
18117
|
Data: { CaCertSha256: caCertSha256 }
|
|
18118
18118
|
};
|
|
18119
18119
|
};
|
|
18120
|
+
/*! Bundled license information:
|
|
18121
|
+
|
|
18122
|
+
reflect-metadata/Reflect.js:
|
|
18123
|
+
(*! *****************************************************************************
|
|
18124
|
+
Copyright (C) Microsoft. All rights reserved.
|
|
18125
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
18126
|
+
this file except in compliance with the License. You may obtain a copy of the
|
|
18127
|
+
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
18128
|
+
|
|
18129
|
+
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
18130
|
+
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
18131
|
+
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
18132
|
+
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
18133
|
+
|
|
18134
|
+
See the Apache Version 2.0 License for specific language governing permissions
|
|
18135
|
+
and limitations under the License.
|
|
18136
|
+
***************************************************************************** *)
|
|
18137
|
+
|
|
18138
|
+
pvtsutils/build/index.js:
|
|
18139
|
+
(*!
|
|
18140
|
+
* MIT License
|
|
18141
|
+
*
|
|
18142
|
+
* Copyright (c) 2017-2024 Peculiar Ventures, LLC
|
|
18143
|
+
*
|
|
18144
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
18145
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
18146
|
+
* in the Software without restriction, including without limitation the rights
|
|
18147
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18148
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
18149
|
+
* furnished to do so, subject to the following conditions:
|
|
18150
|
+
*
|
|
18151
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
18152
|
+
* copies or substantial portions of the Software.
|
|
18153
|
+
*
|
|
18154
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18155
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18156
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18157
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18158
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18159
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
18160
|
+
* SOFTWARE.
|
|
18161
|
+
*
|
|
18162
|
+
*)
|
|
18163
|
+
|
|
18164
|
+
pvutils/build/utils.js:
|
|
18165
|
+
(*!
|
|
18166
|
+
Copyright (c) Peculiar Ventures, LLC
|
|
18167
|
+
*)
|
|
18168
|
+
|
|
18169
|
+
asn1js/build/index.js:
|
|
18170
|
+
(*!
|
|
18171
|
+
* Copyright (c) 2014, GMO GlobalSign
|
|
18172
|
+
* Copyright (c) 2015-2022, Peculiar Ventures
|
|
18173
|
+
* All rights reserved.
|
|
18174
|
+
*
|
|
18175
|
+
* Author 2014-2019, Yury Strozhevsky
|
|
18176
|
+
*
|
|
18177
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
|
18178
|
+
* are permitted provided that the following conditions are met:
|
|
18179
|
+
*
|
|
18180
|
+
* * Redistributions of source code must retain the above copyright notice, this
|
|
18181
|
+
* list of conditions and the following disclaimer.
|
|
18182
|
+
*
|
|
18183
|
+
* * Redistributions in binary form must reproduce the above copyright notice, this
|
|
18184
|
+
* list of conditions and the following disclaimer in the documentation and/or
|
|
18185
|
+
* other materials provided with the distribution.
|
|
18186
|
+
*
|
|
18187
|
+
* * Neither the name of the copyright holder nor the names of its
|
|
18188
|
+
* contributors may be used to endorse or promote products derived from
|
|
18189
|
+
* this software without specific prior written permission.
|
|
18190
|
+
*
|
|
18191
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18192
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
18193
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18194
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
18195
|
+
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
18196
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
18197
|
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
18198
|
+
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
18199
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
18200
|
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
18201
|
+
*
|
|
18202
|
+
*)
|
|
18203
|
+
|
|
18204
|
+
tslib/tslib.es6.js:
|
|
18205
|
+
(*! *****************************************************************************
|
|
18206
|
+
Copyright (c) Microsoft Corporation.
|
|
18207
|
+
|
|
18208
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
18209
|
+
purpose with or without fee is hereby granted.
|
|
18210
|
+
|
|
18211
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
18212
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
18213
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
18214
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
18215
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
18216
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
18217
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
18218
|
+
***************************************************************************** *)
|
|
18219
|
+
|
|
18220
|
+
@peculiar/x509/build/x509.cjs.js:
|
|
18221
|
+
(*!
|
|
18222
|
+
* MIT License
|
|
18223
|
+
*
|
|
18224
|
+
* Copyright (c) Peculiar Ventures. All rights reserved.
|
|
18225
|
+
*
|
|
18226
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
18227
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
18228
|
+
* in the Software without restriction, including without limitation the rights
|
|
18229
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18230
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
18231
|
+
* furnished to do so, subject to the following conditions:
|
|
18232
|
+
*
|
|
18233
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
18234
|
+
* copies or substantial portions of the Software.
|
|
18235
|
+
*
|
|
18236
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18237
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18238
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18239
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18240
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18241
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
18242
|
+
* SOFTWARE.
|
|
18243
|
+
*
|
|
18244
|
+
*)
|
|
18245
|
+
*/
|
|
@@ -14,7 +14,7 @@ export type BuildkiteConstructProps = BuildkitePropsInput & {
|
|
|
14
14
|
* Self-hosted Buildkite agent fleet on the pinned Elastic CI Stack AMIs —
|
|
15
15
|
* scale-to-zero ASG + buildkite-agent-scaler, no secret ever transiting
|
|
16
16
|
* synth, allowlist-only instance IAM. Design:
|
|
17
|
-
*
|
|
17
|
+
* the 2026-07-18 Buildkite self-hosted agents design.
|
|
18
18
|
*
|
|
19
19
|
* A Construct, not a Stack: instantiate via `App.addBuildkite(props)`, which
|
|
20
20
|
* scopes it under the default compute stack so deploy-core's fixed
|
|
@@ -21,7 +21,7 @@ import { buildBuildkiteUserData } from "./userData.js";
|
|
|
21
21
|
* Self-hosted Buildkite agent fleet on the pinned Elastic CI Stack AMIs —
|
|
22
22
|
* scale-to-zero ASG + buildkite-agent-scaler, no secret ever transiting
|
|
23
23
|
* synth, allowlist-only instance IAM. Design:
|
|
24
|
-
*
|
|
24
|
+
* the 2026-07-18 Buildkite self-hosted agents design.
|
|
25
25
|
*
|
|
26
26
|
* A Construct, not a Stack: instantiate via `App.addBuildkite(props)`, which
|
|
27
27
|
* scopes it under the default compute stack so deploy-core's fixed
|
|
@@ -5,8 +5,8 @@ import type { BuildkitePropsInput } from "./schema.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* Thunk returned by `BuildkiteFactory.build` — materialised only by
|
|
7
7
|
* `App.addBuildkite`, which owns stack placement (the fleet has exactly one
|
|
8
|
-
* legal home, `${stackPrefix}Compute`; design
|
|
9
|
-
*
|
|
8
|
+
* legal home, `${stackPrefix}Compute`; design:
|
|
9
|
+
* the 2026-07-18 `fjall add buildkite` design, § D2).
|
|
10
10
|
*/
|
|
11
11
|
export type BuildkiteFactoryFn = (app: App, scope: Construct) => Buildkite;
|
|
12
12
|
/**
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* release. AMI ids, the elastic-stack version, the scaler version and the
|
|
5
5
|
* secrets-plugin floor MUST only change together, regenerated from the
|
|
6
6
|
* upstream template for the new version (runbook:
|
|
7
|
-
*
|
|
7
|
+
* the Buildkite stack-bump runbook).
|
|
8
8
|
*
|
|
9
9
|
* AMI ids come from the `Mappings.AWSRegion2AMI` block of
|
|
10
10
|
* `https://s3.amazonaws.com/buildkite-aws-stack/<version>/aws-stack.yml` and
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* floats the AMI underneath a pinned stack version, needs lookup credentials
|
|
19
19
|
* at synth time (unavailable in worker synth), and makes synth
|
|
20
20
|
* non-deterministic. Design:
|
|
21
|
-
*
|
|
21
|
+
* the 2026-07-18 Buildkite self-hosted agents design, § D2.
|
|
22
22
|
*/
|
|
23
23
|
export declare const BUILDKITE_AMI_OWNER_ACCOUNT_ID = "172840064832";
|
|
24
24
|
export declare const BUILDKITE_CPU_ARCHITECTURES: readonly ["arm64", "amd64"];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* release. AMI ids, the elastic-stack version, the scaler version and the
|
|
5
5
|
* secrets-plugin floor MUST only change together, regenerated from the
|
|
6
6
|
* upstream template for the new version (runbook:
|
|
7
|
-
*
|
|
7
|
+
* the Buildkite stack-bump runbook).
|
|
8
8
|
*
|
|
9
9
|
* AMI ids come from the `Mappings.AWSRegion2AMI` block of
|
|
10
10
|
* `https://s3.amazonaws.com/buildkite-aws-stack/<version>/aws-stack.yml` and
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* floats the AMI underneath a pinned stack version, needs lookup credentials
|
|
19
19
|
* at synth time (unavailable in worker synth), and makes synth
|
|
20
20
|
* non-deterministic. Design:
|
|
21
|
-
*
|
|
21
|
+
* the 2026-07-18 Buildkite self-hosted agents design, § D2.
|
|
22
22
|
*/
|
|
23
23
|
export const BUILDKITE_AMI_OWNER_ACCOUNT_ID = "172840064832";
|
|
24
24
|
export const BUILDKITE_CPU_ARCHITECTURES = ["arm64", "amd64"];
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Buildkite props schema — re-export barrel. The canonical declaration lives
|
|
3
3
|
* in `@fjall/generator` (`src/schemas/buildkiteSchemas.ts`) so construct
|
|
4
4
|
* validation, the codemod fragment, and the LLM JSON schema all consume one
|
|
5
|
-
* source (design
|
|
5
|
+
* source (design: the 2026-07-18 `fjall add buildkite` design, § D4).
|
|
6
6
|
* Do NOT redeclare here — the cross-package reference-identity test pins it.
|
|
7
7
|
*/
|
|
8
8
|
export { BuildkitePropsObjectSchema, BuildkitePropsSchema, validateBuildkiteProps, type BuildkiteProps, type BuildkitePropsInput, type BuildkitePropsObject } from "@fjall/generator";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Buildkite props schema — re-export barrel. The canonical declaration lives
|
|
3
3
|
* in `@fjall/generator` (`src/schemas/buildkiteSchemas.ts`) so construct
|
|
4
4
|
* validation, the codemod fragment, and the LLM JSON schema all consume one
|
|
5
|
-
* source (design
|
|
5
|
+
* source (design: the 2026-07-18 `fjall add buildkite` design, § D4).
|
|
6
6
|
* Do NOT redeclare here — the cross-package reference-identity test pins it.
|
|
7
7
|
*/
|
|
8
8
|
export { BuildkitePropsObjectSchema, BuildkitePropsSchema, validateBuildkiteProps } from "@fjall/generator";
|
|
@@ -29,7 +29,7 @@ export interface BuildkiteUserDataContext {
|
|
|
29
29
|
* vendored template in both directions: a key we emit that upstream does not
|
|
30
30
|
* pass is silently ignored; a key upstream passes that we omit is the
|
|
31
31
|
* boot-loop. Bumping the pins regenerates the fixture
|
|
32
|
-
* (runbook:
|
|
32
|
+
* (runbook: the Buildkite stack-bump runbook).
|
|
33
33
|
*/
|
|
34
34
|
export declare const BUILDKITE_MOUNT_PART_ENV_KEYS: readonly ["BUILDKITE_ENABLE_INSTANCE_STORAGE", "BUILDKITE_MOUNT_TMPFS_AT_TMP"];
|
|
35
35
|
export declare const BUILDKITE_DOCKER_PART_ENV_KEYS: readonly ["DOCKER_USERNS_REMAP", "DOCKER_EXPERIMENTAL", "DOCKER_PRUNE_UNTIL", "ENABLE_PRE_EXIT_DISK_CLEANUP", "DOCKER_BUILDER_PRUNE_ENABLED", "DOCKER_NETWORKING_PROTOCOL", "DOCKER_IPV4_ADDRESS_POOL_1", "DOCKER_IPV4_ADDRESS_POOL_2", "DOCKER_IPV6_ADDRESS_POOL", "DOCKER_FIXED_CIDR_V4", "DOCKER_FIXED_CIDR_V6", "BUILDKITE_ENABLE_INSTANCE_STORAGE"];
|
|
@@ -10,7 +10,7 @@ import { BUILDKITE_STACK_PINS } from "./pins.js";
|
|
|
10
10
|
* vendored template in both directions: a key we emit that upstream does not
|
|
11
11
|
* pass is silently ignored; a key upstream passes that we omit is the
|
|
12
12
|
* boot-loop. Bumping the pins regenerates the fixture
|
|
13
|
-
* (runbook:
|
|
13
|
+
* (runbook: the Buildkite stack-bump runbook).
|
|
14
14
|
*/
|
|
15
15
|
export const BUILDKITE_MOUNT_PART_ENV_KEYS = [
|
|
16
16
|
"BUILDKITE_ENABLE_INSTANCE_STORAGE",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Self-hosted Buildkite agent fleet — barrel for the `buildkite/` modules.
|
|
3
3
|
* The pre-2026-07 `Buildkite extends Stack` implementation is replaced by a
|
|
4
4
|
* Construct instantiated via `App.addBuildkite()`; design:
|
|
5
|
-
*
|
|
5
|
+
* the 2026-07-18 Buildkite self-hosted agents design.
|
|
6
6
|
*/
|
|
7
7
|
export { AGENT_TOKEN_SECRET_NAME, BUILDKITE_SECRETS_CLUSTER, Buildkite, FJALL_API_KEY_SECRET_NAME, FJALL_ENV_HOOK_OBJECT_KEY, buildAgentSecretsEnvHookScript, type AgentSecretsEnvHookOptions, type BuildkiteConstructProps } from "./buildkite/buildkite.js";
|
|
8
8
|
export { BUILDKITE_AMI_OWNER_ACCOUNT_ID, BUILDKITE_CPU_ARCHITECTURES, BUILDKITE_STACK_PINS, resolvePinnedAmiId, resolveScalerSarApplicationArn, type BuildkiteCpuArchitecture } from "./buildkite/pins.js";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Self-hosted Buildkite agent fleet — barrel for the `buildkite/` modules.
|
|
3
3
|
* The pre-2026-07 `Buildkite extends Stack` implementation is replaced by a
|
|
4
4
|
* Construct instantiated via `App.addBuildkite()`; design:
|
|
5
|
-
*
|
|
5
|
+
* the 2026-07-18 Buildkite self-hosted agents design.
|
|
6
6
|
*/
|
|
7
7
|
export { AGENT_TOKEN_SECRET_NAME, BUILDKITE_SECRETS_CLUSTER, Buildkite, FJALL_API_KEY_SECRET_NAME, FJALL_ENV_HOOK_OBJECT_KEY, buildAgentSecretsEnvHookScript } from "./buildkite/buildkite.js";
|
|
8
8
|
export { BUILDKITE_AMI_OWNER_ACCOUNT_ID, BUILDKITE_CPU_ARCHITECTURES, BUILDKITE_STACK_PINS, resolvePinnedAmiId, resolveScalerSarApplicationArn } from "./buildkite/pins.js";
|
|
@@ -381,7 +381,10 @@ export class ClickHouseDatabase extends Construct {
|
|
|
381
381
|
const coldTierBucket = coldTierEnabled
|
|
382
382
|
? (props.coldTierBucket ??
|
|
383
383
|
new S3Bucket(this, "ClickHouseColdTierBucket", {
|
|
384
|
-
|
|
384
|
+
// Tiered table parts, re-tiered from hot storage — versioning would
|
|
385
|
+
// only bill for churn; the exemption stamp tells posture so.
|
|
386
|
+
versioned: false,
|
|
387
|
+
versioningExemption: "cold-tier"
|
|
385
388
|
}))
|
|
386
389
|
: undefined;
|
|
387
390
|
this.#backupBucket = backupBucket;
|
|
@@ -17,7 +17,7 @@ export interface ClickHouseSelfSignedTls {
|
|
|
17
17
|
* supplied the construct surfaces it as a CFN env-var token so consumers
|
|
18
18
|
* can wire it into containers for rotation-triggers-task-replacement
|
|
19
19
|
* parity with self-signed mode. Omit it and rotation requires manual task
|
|
20
|
-
* restart (documented in
|
|
20
|
+
* restart (documented in the ClickHouse TLS pattern, § "Imported mode").
|
|
21
21
|
*/
|
|
22
22
|
export interface ClickHouseImportedTls {
|
|
23
23
|
readonly mode: "imported";
|
|
@@ -182,8 +182,8 @@ export interface EcsContainerConfig {
|
|
|
182
182
|
* per service. Suitable for high-replica services where the init-container
|
|
183
183
|
* tax dominates rollout time.
|
|
184
184
|
*
|
|
185
|
-
* @see
|
|
186
|
-
* @see
|
|
185
|
+
* @see the 2026-04-29 decision: ECS init container over RunTask
|
|
186
|
+
* @see the 2026-04-29 ECS factory-hardening plan, § 4.3.4 — threshold
|
|
187
187
|
* guidance for choosing between modes.
|
|
188
188
|
* @see https://aws.amazon.com/blogs/containers/announcing-amazon-ecs-deployment-lifecycle-hooks/
|
|
189
189
|
*/
|
|
@@ -223,7 +223,7 @@ export type EcsMigrationsMode = "init-container" | "lifecycle-hook" | "post-depl
|
|
|
223
223
|
* mode: "lifecycle-hook"
|
|
224
224
|
* }
|
|
225
225
|
*
|
|
226
|
-
* @see
|
|
226
|
+
* @see the 2026-04-29 decision: ECS init container over RunTask
|
|
227
227
|
*/
|
|
228
228
|
/**
|
|
229
229
|
* Discriminated on `mode`. The init-container variant keeps its narrow surface
|
|
@@ -237,8 +237,8 @@ export type EcsMigrationsMode = "init-container" | "lifecycle-hook" | "post-depl
|
|
|
237
237
|
* lifecycle-hook-only field — is a typecheck error. This protects against
|
|
238
238
|
* the Pitfall-5 trap (silent field drift across union variants).
|
|
239
239
|
*
|
|
240
|
-
* @see
|
|
241
|
-
* @see
|
|
240
|
+
* @see the 2026-05-12 migration-runner abstraction-choice design
|
|
241
|
+
* @see the TypeScript standards, Zod Pitfall 5 (three-way option drift)
|
|
242
242
|
*/
|
|
243
243
|
export type EcsMigrationsConfig = EcsInitContainerMigrationsConfig | EcsLifecycleHookMigrationsConfig | EcsPostDeployMigrationsConfig;
|
|
244
244
|
/**
|
|
@@ -217,8 +217,10 @@ export class Payload extends Construct {
|
|
|
217
217
|
createAssetsBucket() {
|
|
218
218
|
const assetsConfig = this.props.storage?.assets ?? {};
|
|
219
219
|
const assetsProps = {
|
|
220
|
-
// Build output, pruned on every deploy — versioning would only bill for
|
|
220
|
+
// Build output, pruned on every deploy — versioning would only bill for
|
|
221
|
+
// churn; the exemption stamp tells posture the omission is by design.
|
|
221
222
|
versioned: assetsConfig.versioned ?? false,
|
|
223
|
+
versioningExemption: "build-output",
|
|
222
224
|
deployment: {
|
|
223
225
|
source: `${PAYLOAD_DEFAULTS.SOURCE}/${PAYLOAD_DEFAULTS.OPENNEXT.ASSETS}`,
|
|
224
226
|
prune: true,
|
|
@@ -233,8 +235,10 @@ export class Payload extends Construct {
|
|
|
233
235
|
createCacheBucket() {
|
|
234
236
|
const cacheConfig = this.props.storage?.cache ?? {};
|
|
235
237
|
const cacheProps = {
|
|
236
|
-
// ISR cache, regenerated at runtime — versioning would only bill for
|
|
238
|
+
// ISR cache, regenerated at runtime — versioning would only bill for
|
|
239
|
+
// churn; the exemption stamp tells posture the omission is by design.
|
|
237
240
|
versioned: cacheConfig.versioned ?? false,
|
|
241
|
+
versioningExemption: "isr-cache",
|
|
238
242
|
deployment: {
|
|
239
243
|
source: `${PAYLOAD_DEFAULTS.SOURCE}/${PAYLOAD_DEFAULTS.OPENNEXT.CACHE}`,
|
|
240
244
|
prune: false // ISR adds files at runtime
|
|
@@ -2,6 +2,7 @@ import { Construct } from "constructs";
|
|
|
2
2
|
import { type EventType, type IBucketNotificationDestination, type NotificationKeyFilter } from "aws-cdk-lib/aws-s3";
|
|
3
3
|
import { type IDistribution } from "aws-cdk-lib/aws-cloudfront";
|
|
4
4
|
import { type IGrantable, type Grant } from "aws-cdk-lib/aws-iam";
|
|
5
|
+
import { type S3VersioningExemption } from "@fjall/util/aws";
|
|
5
6
|
import type App from "../../app.js";
|
|
6
7
|
import { BucketDeployment, S3Bucket, type ResourcePolicyStatement, type WebsiteHostingConfig } from "../../resources/aws/storage/index.js";
|
|
7
8
|
import { type BackupTier } from "../../utils/backupTierMapping.js";
|
|
@@ -39,6 +40,13 @@ export interface S3Props {
|
|
|
39
40
|
* `resilient`/`enterprise`, off otherwise. An explicit value always wins.
|
|
40
41
|
*/
|
|
41
42
|
readonly versioned?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Why this bucket runs unversioned by design (`build-output`, `isr-cache`,
|
|
45
|
+
* `cold-tier`) — see `S3BucketProps.versioningExemption`. Stamped as the
|
|
46
|
+
* `fjall:s3:versioning-exempt` tag when versioning resolves off; a bucket
|
|
47
|
+
* that versions after all is not stamped.
|
|
48
|
+
*/
|
|
49
|
+
readonly versioningExemption?: S3VersioningExemption;
|
|
42
50
|
readonly encryption?: "AES256" | "KMS";
|
|
43
51
|
readonly kmsKeyArn?: string;
|
|
44
52
|
/**
|
|
@@ -78,6 +78,7 @@ export class Storage extends Construct {
|
|
|
78
78
|
aliasTargetName: props.bucketName ?? id,
|
|
79
79
|
appName: props.appName,
|
|
80
80
|
versioned: props.versioned,
|
|
81
|
+
versioningExemption: props.versioningExemption,
|
|
81
82
|
encryption: toBucketEncryption(props.encryption),
|
|
82
83
|
encryptionKey,
|
|
83
84
|
...(props.bucketKeyEnabled !== undefined && {
|
|
@@ -40,7 +40,7 @@ export interface SecurityHeadersPolicyProps {
|
|
|
40
40
|
* Wrapped on the description + SOC2-defaults trigger (NOT taggability — the
|
|
41
41
|
* resource is not taggable): it owns Fjall's uniform security-header defaults
|
|
42
42
|
* so every consumer inherits the same posture in one edit. Per
|
|
43
|
-
*
|
|
43
|
+
* the Wrapper Routing Discipline rule (generator standards),
|
|
44
44
|
* `lib/{config,patterns}/` instantiate this class, never the raw L2.
|
|
45
45
|
*
|
|
46
46
|
* Defaults (all `override:true`): HSTS 730d+includeSubdomains+preload,
|
|
@@ -18,7 +18,7 @@ const DEFAULT_COMMENT = "Fjall security headers policy";
|
|
|
18
18
|
* Wrapped on the description + SOC2-defaults trigger (NOT taggability — the
|
|
19
19
|
* resource is not taggable): it owns Fjall's uniform security-header defaults
|
|
20
20
|
* so every consumer inherits the same posture in one edit. Per
|
|
21
|
-
*
|
|
21
|
+
* the Wrapper Routing Discipline rule (generator standards),
|
|
22
22
|
* `lib/{config,patterns}/` instantiate this class, never the raw L2.
|
|
23
23
|
*
|
|
24
24
|
* Defaults (all `override:true`): HSTS 730d+includeSubdomains+preload,
|
|
@@ -27,7 +27,7 @@ export type Ec2InstancePersistentDataVolumeConfig = Omit<PersistentDataVolumePro
|
|
|
27
27
|
* `AutoScalingScheduledAction.IgnoreUnmodifiedGroupSizeProperties`
|
|
28
28
|
* regardless. For callers owning rollout externally.
|
|
29
29
|
*
|
|
30
|
-
* See
|
|
30
|
+
* See the ClickHouse rolling-update-window troubleshooting note for the
|
|
31
31
|
* ClickHouse-specific downtime expectations.
|
|
32
32
|
*/
|
|
33
33
|
export type Ec2InstanceUpdatePolicyConfig = {
|
|
@@ -127,7 +127,7 @@ export interface Ec2InstanceProps extends StackProps {
|
|
|
127
127
|
* ASG `UpdatePolicy` resolution. Absent → `UpdatePolicy.instanceRefresh`
|
|
128
128
|
* (0/100 with `persistentDataVolume`, 100/200 otherwise). See
|
|
129
129
|
* `Ec2InstanceUpdatePolicyConfig` for the variant menu and
|
|
130
|
-
*
|
|
130
|
+
* the ClickHouse rolling-update-window troubleshooting note for the
|
|
131
131
|
* downtime-window runbook.
|
|
132
132
|
*/
|
|
133
133
|
updatePolicy?: Ec2InstanceUpdatePolicyConfig;
|
|
@@ -17,7 +17,7 @@ import { PersistentDataVolume } from "./persistentDataVolume.js";
|
|
|
17
17
|
* `encrypted: true` enforces EBS encryption at the wrapper layer rather than
|
|
18
18
|
* relying on the AWS account-level "encryption by default" setting — the
|
|
19
19
|
* propagation contract documented in
|
|
20
|
-
*
|
|
20
|
+
* the Wrapper Routing Discipline rule (generator standards).
|
|
21
21
|
*/
|
|
22
22
|
const DEFAULT_ROOT_DEVICE_NAME = "/dev/xvda";
|
|
23
23
|
const DEFAULT_ROOT_VOLUME_SIZE_GIB = 30;
|
|
@@ -155,7 +155,7 @@ export declare const CLICKHOUSE_NATIVE_PORT = 9000;
|
|
|
155
155
|
export declare const CLICKHOUSE_PROMETHEUS_PORT = 9363;
|
|
156
156
|
/** TLS-mode ClickHouse ports.
|
|
157
157
|
* HTTPS replaces 8123; secure native protocol replaces 9000.
|
|
158
|
-
* See
|
|
158
|
+
* See the ClickHouse TLS pattern, § "The contract". */
|
|
159
159
|
export declare const CLICKHOUSE_HTTPS_PORT = 8443;
|
|
160
160
|
export declare const CLICKHOUSE_TCP_SECURE_PORT = 9440;
|
|
161
161
|
/** Mount path inside the ClickHouse container for the materialised TLS cert
|
|
@@ -188,8 +188,8 @@ export declare function clickHouseUserSecretName(userName: string): string;
|
|
|
188
188
|
* Canonical source is `@fjall/util/migration § userPasswordEnvName` — re-exported
|
|
189
189
|
* here so the construct-side import chain stays unchanged while the runner
|
|
190
190
|
* (`webapp/scripts/migration-runner.mjs`) and any future consumer share a single
|
|
191
|
-
* declaration. Coupled values
|
|
192
|
-
*
|
|
191
|
+
* declaration. Coupled values (the shared-source-at-two-occurrences
|
|
192
|
+
* rule). */
|
|
193
193
|
export { userPasswordEnvName } from "@fjall/util/migration";
|
|
194
194
|
/** Env var name carrying the SHA-256 of a user's plaintext password.
|
|
195
195
|
* The container entrypoint wrapper derives this name from the
|
|
@@ -305,8 +305,8 @@ export declare const BACKUP_RETENTION_DAYS = 14;
|
|
|
305
305
|
* wrote can be read back. Dropped on the way in and on the way out; never
|
|
306
306
|
* queried by the application. Canonical source is `@fjall/util/migration`
|
|
307
307
|
* because `@fjall/clickhouse` grants `fjall_maintenance` DROP on exactly
|
|
308
|
-
* this database — coupled values
|
|
309
|
-
*
|
|
308
|
+
* this database — coupled values (the shared-source-at-two-occurrences
|
|
309
|
+
* rule). */
|
|
310
310
|
export { CLICKHOUSE_BACKUP_SCRATCH_DATABASE } from "@fjall/util/migration";
|
|
311
311
|
/** The two scheduled maintenance jobs that authenticate as
|
|
312
312
|
* `fjall_maintenance`. Drives the per-job log-group → metric-filter wiring
|
|
@@ -175,7 +175,7 @@ export const CLICKHOUSE_NATIVE_PORT = 9000;
|
|
|
175
175
|
export const CLICKHOUSE_PROMETHEUS_PORT = 9363;
|
|
176
176
|
/** TLS-mode ClickHouse ports.
|
|
177
177
|
* HTTPS replaces 8123; secure native protocol replaces 9000.
|
|
178
|
-
* See
|
|
178
|
+
* See the ClickHouse TLS pattern, § "The contract". */
|
|
179
179
|
export const CLICKHOUSE_HTTPS_PORT = 8443;
|
|
180
180
|
export const CLICKHOUSE_TCP_SECURE_PORT = 9440;
|
|
181
181
|
/** Mount path inside the ClickHouse container for the materialised TLS cert
|
|
@@ -210,8 +210,8 @@ export function clickHouseUserSecretName(userName) {
|
|
|
210
210
|
* Canonical source is `@fjall/util/migration § userPasswordEnvName` — re-exported
|
|
211
211
|
* here so the construct-side import chain stays unchanged while the runner
|
|
212
212
|
* (`webapp/scripts/migration-runner.mjs`) and any future consumer share a single
|
|
213
|
-
* declaration. Coupled values
|
|
214
|
-
*
|
|
213
|
+
* declaration. Coupled values (the shared-source-at-two-occurrences
|
|
214
|
+
* rule). */
|
|
215
215
|
export { userPasswordEnvName } from "@fjall/util/migration";
|
|
216
216
|
/** Env var name carrying the SHA-256 of a user's plaintext password.
|
|
217
217
|
* The container entrypoint wrapper derives this name from the
|
|
@@ -347,8 +347,8 @@ export const BACKUP_RETENTION_DAYS = 14;
|
|
|
347
347
|
* wrote can be read back. Dropped on the way in and on the way out; never
|
|
348
348
|
* queried by the application. Canonical source is `@fjall/util/migration`
|
|
349
349
|
* because `@fjall/clickhouse` grants `fjall_maintenance` DROP on exactly
|
|
350
|
-
* this database — coupled values
|
|
351
|
-
*
|
|
350
|
+
* this database — coupled values (the shared-source-at-two-occurrences
|
|
351
|
+
* rule). */
|
|
352
352
|
export { CLICKHOUSE_BACKUP_SCRATCH_DATABASE } from "@fjall/util/migration";
|
|
353
353
|
/** The two scheduled maintenance jobs that authenticate as
|
|
354
354
|
* `fjall_maintenance`. Drives the per-job log-group → metric-filter wiring
|
|
@@ -8,7 +8,7 @@ export interface IdentityStoreUserProviderProps {
|
|
|
8
8
|
* Shared Provider-framework backend for Custom::FjallIdentityStoreUser —
|
|
9
9
|
* one handler + provider pair serves every declared user in the stack. A
|
|
10
10
|
* plain AwsCustomResource cannot express the create-or-adopt branching the
|
|
11
|
-
* handler implements (
|
|
11
|
+
* handler implements (the 2026-07-04 organisation user-management design, § 2).
|
|
12
12
|
*/
|
|
13
13
|
export declare class IdentityStoreUserProvider extends Construct {
|
|
14
14
|
readonly serviceToken: string;
|
|
@@ -23,7 +23,7 @@ export function identityStoreUserArnPattern(partition) {
|
|
|
23
23
|
* Shared Provider-framework backend for Custom::FjallIdentityStoreUser —
|
|
24
24
|
* one handler + provider pair serves every declared user in the stack. A
|
|
25
25
|
* plain AwsCustomResource cannot express the create-or-adopt branching the
|
|
26
|
-
* handler implements (
|
|
26
|
+
* handler implements (the 2026-07-04 organisation user-management design, § 2).
|
|
27
27
|
*/
|
|
28
28
|
export class IdentityStoreUserProvider extends Construct {
|
|
29
29
|
serviceToken;
|
|
@@ -5,9 +5,8 @@ import { type Construct } from "constructs";
|
|
|
5
5
|
*
|
|
6
6
|
* Applies one default: an explicit, stack-shared log group for the deployment
|
|
7
7
|
* handler lambda, so it is CloudFormation-managed and tagged rather than
|
|
8
|
-
* service-auto-created. Per
|
|
9
|
-
*
|
|
10
|
-
* `patterns/infrastructure-wrapper-routing-pattern.md § A3`, `lib/{config,
|
|
8
|
+
* service-auto-created. Per the Wrapper Routing Discipline rule (generator
|
|
9
|
+
* standards) and the infrastructure wrapper-routing pattern (§ A3), `lib/{config,
|
|
11
10
|
* patterns}/` MUST instantiate this class rather than the raw CDK construct.
|
|
12
11
|
*/
|
|
13
12
|
export declare class BucketDeployment extends CdkBucketDeployment {
|
|
@@ -5,9 +5,8 @@ import { stackSingletonLogGroup } from "../logging/singletonLogGroup.js";
|
|
|
5
5
|
*
|
|
6
6
|
* Applies one default: an explicit, stack-shared log group for the deployment
|
|
7
7
|
* handler lambda, so it is CloudFormation-managed and tagged rather than
|
|
8
|
-
* service-auto-created. Per
|
|
9
|
-
*
|
|
10
|
-
* `patterns/infrastructure-wrapper-routing-pattern.md § A3`, `lib/{config,
|
|
8
|
+
* service-auto-created. Per the Wrapper Routing Discipline rule (generator
|
|
9
|
+
* standards) and the infrastructure wrapper-routing pattern (§ A3), `lib/{config,
|
|
11
10
|
* patterns}/` MUST instantiate this class rather than the raw CDK construct.
|
|
12
11
|
*/
|
|
13
12
|
export class BucketDeployment extends CdkBucketDeployment {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { type S3VersioningExemption } from "@fjall/util/aws";
|
|
1
2
|
import { Bucket, type BucketProps } from "aws-cdk-lib/aws-s3";
|
|
2
3
|
import { type Construct } from "constructs";
|
|
3
4
|
import { type BackupTier } from "../../../utils/backupTierMapping.js";
|
|
4
|
-
export { SDK_PRE_EMPTY_TAG_KEY } from "@fjall/util/aws";
|
|
5
|
+
export { S3_VERSIONING_EXEMPT_TAG_KEY, SDK_PRE_EMPTY_TAG_KEY } from "@fjall/util/aws";
|
|
5
6
|
/**
|
|
6
7
|
* Days a noncurrent object version is retained before lifecycle expiry.
|
|
7
8
|
* The wrapper pairs this automatically when it enables versioning; constructs
|
|
@@ -59,6 +60,17 @@ export interface S3BucketProps extends BucketProps {
|
|
|
59
60
|
* direct `new S3Bucket` construction needs to pass it.
|
|
60
61
|
*/
|
|
61
62
|
appBackupTier?: BackupTier;
|
|
63
|
+
/**
|
|
64
|
+
* Why this bucket runs unversioned by design. Stamped as the
|
|
65
|
+
* `fjall:s3:versioning-exempt` tag only when versioning resolves off — a
|
|
66
|
+
* bucket that versions after all (an explicit `versioned: true`, or a tier
|
|
67
|
+
* that turns it on) has nothing to exempt — so posture lands the
|
|
68
|
+
* `S3_VERSIONING_DISABLED` finding `mitigated` rather than `open` on
|
|
69
|
+
* buckets whose contents are rebuilt, not kept. Constructs pass it for the
|
|
70
|
+
* buckets they own (Payload build output and ISR cache, ClickHouse cold
|
|
71
|
+
* tier); an author may pass it for a disposable bucket of their own.
|
|
72
|
+
*/
|
|
73
|
+
versioningExemption?: S3VersioningExemption;
|
|
62
74
|
publicReadAccess?: boolean;
|
|
63
75
|
websiteHosting?: WebsiteHostingConfig;
|
|
64
76
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SDK_PRE_EMPTY_TAG_KEY } from "@fjall/util/aws";
|
|
1
|
+
import { S3_VERSIONING_EXEMPT_TAG_KEY, SDK_PRE_EMPTY_TAG_KEY } from "@fjall/util/aws";
|
|
2
2
|
import { Annotations, CfnOutput, Duration, RemovalPolicy, Tags } from "aws-cdk-lib";
|
|
3
3
|
import { BlockPublicAccess, Bucket, BucketEncryption } from "aws-cdk-lib/aws-s3";
|
|
4
4
|
import { ArnPrincipal, Effect, PolicyStatement, StarPrincipal } from "aws-cdk-lib/aws-iam";
|
|
@@ -7,7 +7,7 @@ import { resolveEffectiveBackupTier, shouldAutoVersion } from "../../../utils/ba
|
|
|
7
7
|
import { toPascalCase } from "../../../utils/capitaliseString.js";
|
|
8
8
|
import { bucketWebsiteEndpointExportName, bucketWebsiteHostedZoneIdExportName } from "@fjall/util";
|
|
9
9
|
import { envAwareRemovalPolicyDefault, toRemovalPolicy } from "../../../utils/removalPolicy.js";
|
|
10
|
-
export { SDK_PRE_EMPTY_TAG_KEY } from "@fjall/util/aws";
|
|
10
|
+
export { S3_VERSIONING_EXEMPT_TAG_KEY, SDK_PRE_EMPTY_TAG_KEY } from "@fjall/util/aws";
|
|
11
11
|
/**
|
|
12
12
|
* Days a noncurrent object version is retained before lifecycle expiry.
|
|
13
13
|
* The wrapper pairs this automatically when it enables versioning; constructs
|
|
@@ -26,7 +26,7 @@ export class S3Bucket extends Bucket {
|
|
|
26
26
|
/** The tier the bucket runs under: `backupVaultTier`, else `appBackupTier`. */
|
|
27
27
|
effectiveBackupTier;
|
|
28
28
|
constructor(scope, id, props = {}) {
|
|
29
|
-
const { websiteHosting, backupVaultTier, appBackupTier, resourcePolicyStatements, aliasTargetName, appName, ...cdkProps } = props;
|
|
29
|
+
const { websiteHosting, backupVaultTier, appBackupTier, resourcePolicyStatements, aliasTargetName, appName, versioningExemption, ...cdkProps } = props;
|
|
30
30
|
const isPublic = props.publicReadAccess === true || websiteHosting !== undefined;
|
|
31
31
|
const effectiveBackupTier = resolveEffectiveBackupTier(backupVaultTier, appBackupTier);
|
|
32
32
|
const versioned = props.versioned ?? shouldAutoVersion(effectiveBackupTier);
|
|
@@ -112,6 +112,9 @@ export class S3Bucket extends Bucket {
|
|
|
112
112
|
if (removalPolicy === RemovalPolicy.DESTROY) {
|
|
113
113
|
Tags.of(this).add(SDK_PRE_EMPTY_TAG_KEY, "true");
|
|
114
114
|
}
|
|
115
|
+
if (versioningExemption !== undefined && !versioned) {
|
|
116
|
+
Tags.of(this).add(S3_VERSIONING_EXEMPT_TAG_KEY, versioningExemption);
|
|
117
|
+
}
|
|
115
118
|
if (websiteHosting) {
|
|
116
119
|
if (appName === undefined) {
|
|
117
120
|
// Refusing beats falling back to a bucket-only export name: the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/components-infrastructure",
|
|
3
|
-
"version": "33.
|
|
3
|
+
"version": "33.1.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/fjall-tech/fjall.git",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"build:cert-gen-lambda": "node lib/lambda-assets/cert-generator/src/build.mjs",
|
|
42
42
|
"build": "npm run clean && npm run build:cert-gen-lambda && tsc && cp -r lib/layers dist/lib/layers && mkdir -p dist/lib/lambda-assets/cert-generator/asset && cp lib/lambda-assets/cert-generator/asset/index.js dist/lib/lambda-assets/cert-generator/asset/index.js && cp lib/lambda-assets/cert-generator/asset/package.json dist/lib/lambda-assets/cert-generator/asset/package.json && mkdir -p dist/lib/lambda-assets/identity-store-user/asset && cp lib/lambda-assets/identity-store-user/asset/index.js dist/lib/lambda-assets/identity-store-user/asset/index.js && cp lib/lambda-assets/identity-store-user/asset/package.json dist/lib/lambda-assets/identity-store-user/asset/package.json && mkdir -p dist/lib/lambda-assets/static-site-forms/asset && cp lib/lambda-assets/static-site-forms/asset/index.js dist/lib/lambda-assets/static-site-forms/asset/index.js && cp lib/lambda-assets/static-site-forms/asset/package.json dist/lib/lambda-assets/static-site-forms/asset/package.json && cp lib/resources/aws/compute/lifecycleHookLambda.source.cjs dist/lib/resources/aws/compute/lifecycleHookLambda.source.cjs && cp lib/resources/aws/compute/ec2GracefulTerminationLambda.source.cjs dist/lib/resources/aws/compute/ec2GracefulTerminationLambda.source.cjs && cp lib/resources/aws/compute/persistentDataVolumeLambda.source.cjs dist/lib/resources/aws/compute/persistentDataVolumeLambda.source.cjs && cp lib/patterns/aws/devSubstrate.waker.source.cjs dist/lib/patterns/aws/devSubstrate.waker.source.cjs && node ../../scripts/stamp-build.mjs",
|
|
43
43
|
"prepack": "node ../../scripts/check-dist-freshness.mjs",
|
|
44
|
+
"prepublishOnly": "node ../../scripts/audit-package-tarball.mjs",
|
|
44
45
|
"watch": "tsc -w",
|
|
45
46
|
"watch:only": "tsc -w",
|
|
46
47
|
"test": "vitest run",
|
|
@@ -78,8 +79,8 @@
|
|
|
78
79
|
},
|
|
79
80
|
"dependencies": {
|
|
80
81
|
"@aws-sdk/client-organizations": "^3.1098.0",
|
|
81
|
-
"@fjall/generator": "^33.
|
|
82
|
-
"@fjall/util": "^33.
|
|
82
|
+
"@fjall/generator": "^33.1.0",
|
|
83
|
+
"@fjall/util": "^33.1.0",
|
|
83
84
|
"constructs": "^10.7.2",
|
|
84
85
|
"zod": "^4.4.3"
|
|
85
86
|
},
|