@composurecdk/s3 0.1.3 → 0.3.2
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 +226 -0
- package/dist/alarm-config.d.ts +48 -0
- package/dist/alarm-config.d.ts.map +1 -0
- package/dist/alarm-config.js +2 -0
- package/dist/alarm-config.js.map +1 -0
- package/dist/alarm-defaults.d.ts +14 -0
- package/dist/alarm-defaults.d.ts.map +1 -0
- package/dist/alarm-defaults.js +24 -0
- package/dist/alarm-defaults.js.map +1 -0
- package/dist/bucket-alarms.d.ts +34 -0
- package/dist/bucket-alarms.d.ts.map +1 -0
- package/dist/bucket-alarms.js +94 -0
- package/dist/bucket-alarms.js.map +1 -0
- package/dist/bucket-builder.d.ts +33 -0
- package/dist/bucket-builder.d.ts.map +1 -1
- package/dist/bucket-builder.js +13 -2
- package/dist/bucket-builder.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
package/README.md
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# @composurecdk/s3
|
|
2
|
+
|
|
3
|
+
S3 builders for [ComposureCDK](../../README.md).
|
|
4
|
+
|
|
5
|
+
This package provides fluent builders for S3 buckets and bucket deployments with secure, AWS-recommended defaults. It wraps the CDK [Bucket](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) and [BucketDeployment](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_deployment.BucketDeployment.html) constructs — refer to the CDK documentation for the full set of configurable properties.
|
|
6
|
+
|
|
7
|
+
## Bucket Builder
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { createBucketBuilder } from "@composurecdk/s3";
|
|
11
|
+
|
|
12
|
+
const site = createBucketBuilder().bucketName("my-website-bucket").build(stack, "SiteBucket");
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Every [BucketProps](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.BucketProps.html) property is available as a fluent setter on the builder.
|
|
16
|
+
|
|
17
|
+
### Secure Defaults
|
|
18
|
+
|
|
19
|
+
`createBucketBuilder` applies the following defaults. Each can be overridden via the builder's fluent API.
|
|
20
|
+
|
|
21
|
+
| Property | Default | Rationale |
|
|
22
|
+
| ------------------- | ------------ | ---------------------------------------------------------------- |
|
|
23
|
+
| `accessLogging` | `true` | Auto-creates a logging bucket for server access log audit trail. |
|
|
24
|
+
| `accessLogsPrefix` | `"logs/"` | Default prefix for access log object keys. |
|
|
25
|
+
| `blockPublicAccess` | `BLOCK_ALL` | Prevents public access unless explicitly required. |
|
|
26
|
+
| `encryption` | `S3_MANAGED` | Enables server-side encryption with S3-managed keys (SSE-S3). |
|
|
27
|
+
| `enforceSSL` | `true` | Requires SSL/TLS for all requests to the bucket. |
|
|
28
|
+
| `versioned` | `true` | Protects against accidental deletions and supports rollback. |
|
|
29
|
+
| `removalPolicy` | `RETAIN` | Retains the bucket on stack deletion to prevent data loss. |
|
|
30
|
+
|
|
31
|
+
These defaults are guided by the [AWS Well-Architected Security Pillar](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/protecting-data-at-rest.html).
|
|
32
|
+
|
|
33
|
+
The defaults are exported as `BUCKET_DEFAULTS` for visibility and testing:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { BUCKET_DEFAULTS } from "@composurecdk/s3";
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Overriding defaults
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { RemovalPolicy } from "aws-cdk-lib";
|
|
43
|
+
import { BlockPublicAccess } from "aws-cdk-lib/aws-s3";
|
|
44
|
+
|
|
45
|
+
const bucket = createBucketBuilder()
|
|
46
|
+
.blockPublicAccess(BlockPublicAccess.BLOCK_ACLS)
|
|
47
|
+
.versioned(false)
|
|
48
|
+
.removalPolicy(RemovalPolicy.DESTROY)
|
|
49
|
+
.build(stack, "MyBucket");
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
When `removalPolicy` is set to `DESTROY`, the builder automatically enables `autoDeleteObjects` (unless explicitly set to `false`) so that non-empty buckets can be cleanly removed during stack deletion.
|
|
53
|
+
|
|
54
|
+
### Access logging
|
|
55
|
+
|
|
56
|
+
By default, the builder creates a dedicated logging bucket with secure defaults and configures it as the server access logs destination. The created bucket is returned in the build result:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
const result = createBucketBuilder().build(stack, "MyBucket");
|
|
60
|
+
|
|
61
|
+
result.bucket; // Bucket
|
|
62
|
+
result.accessLogsBucket; // Bucket | undefined
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
To provide your own destination instead, set `serverAccessLogsBucket` — the auto-created logging bucket is skipped. To disable access logging entirely, set `.accessLogging(false)`.
|
|
66
|
+
|
|
67
|
+
## Recommended Alarms
|
|
68
|
+
|
|
69
|
+
The builder creates [AWS-recommended CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3) automatically when [CloudWatch request metrics](https://docs.aws.amazon.com/AmazonS3/latest/userguide/configure-request-metrics-bucket.html) are configured on the bucket via `.metrics()`. One alarm per metric is created for each metrics configuration entry. No alarm actions are configured — access alarms from the build result to add SNS topics or other actions.
|
|
70
|
+
|
|
71
|
+
| Alarm | Metric | Default threshold | Created when |
|
|
72
|
+
| -------------- | ---------------------- | ----------------- | -------------------------- |
|
|
73
|
+
| `serverErrors` | 5xxErrors (Sum, 5 min) | > 0 | `.metrics()` is configured |
|
|
74
|
+
| `clientErrors` | 4xxErrors (Sum, 5 min) | > 0 | `.metrics()` is configured |
|
|
75
|
+
|
|
76
|
+
Alarm keys include the metrics filter ID (e.g. `serverErrors:EntireBucket`). When multiple metrics configurations are provided, alarms are created for each one.
|
|
77
|
+
|
|
78
|
+
The defaults are exported as `BUCKET_ALARM_DEFAULTS` for visibility and testing:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { BUCKET_ALARM_DEFAULTS } from "@composurecdk/s3";
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Enabling alarms
|
|
85
|
+
|
|
86
|
+
Configure request metrics on the bucket — alarms are created automatically:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const site = createBucketBuilder().metrics([{ id: "EntireBucket" }]);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Multiple metrics configurations
|
|
93
|
+
|
|
94
|
+
Alarms are created for each metrics configuration entry:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const site = createBucketBuilder().metrics([
|
|
98
|
+
{ id: "EntireBucket" },
|
|
99
|
+
{ id: "UploadsOnly", prefix: "uploads/" },
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
// Creates: serverErrors:EntireBucket, clientErrors:EntireBucket,
|
|
103
|
+
// serverErrors:UploadsOnly, clientErrors:UploadsOnly
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Customizing thresholds
|
|
107
|
+
|
|
108
|
+
Override individual alarm properties via `recommendedAlarms`. Unspecified fields keep their defaults.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
builder.metrics([{ id: "EntireBucket" }]).recommendedAlarms({
|
|
112
|
+
serverErrors: { threshold: 5, evaluationPeriods: 3 },
|
|
113
|
+
clientErrors: { threshold: 50 },
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Disabling alarms
|
|
118
|
+
|
|
119
|
+
Disable all recommended alarms:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
builder.recommendedAlarms(false);
|
|
123
|
+
// or
|
|
124
|
+
builder.recommendedAlarms({ enabled: false });
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Disable individual alarms:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
builder.metrics([{ id: "EntireBucket" }]).recommendedAlarms({ clientErrors: false });
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Custom alarms
|
|
134
|
+
|
|
135
|
+
Add custom alarms alongside the recommended ones via `addAlarm`. The callback receives an `AlarmDefinitionBuilder` typed to the S3 `Bucket`, so the metric factory has access to the bucket's metric helpers.
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { Metric } from "aws-cdk-lib/aws-cloudwatch";
|
|
139
|
+
|
|
140
|
+
const site = createBucketBuilder()
|
|
141
|
+
.metrics([{ id: "EntireBucket" }])
|
|
142
|
+
.addAlarm("lowTraffic", (alarm) =>
|
|
143
|
+
alarm
|
|
144
|
+
.metric(
|
|
145
|
+
(bucket) =>
|
|
146
|
+
new Metric({
|
|
147
|
+
namespace: "AWS/S3",
|
|
148
|
+
metricName: "GetRequests",
|
|
149
|
+
dimensionsMap: {
|
|
150
|
+
BucketName: bucket.bucketName,
|
|
151
|
+
FilterId: "EntireBucket",
|
|
152
|
+
},
|
|
153
|
+
period: Duration.minutes(5),
|
|
154
|
+
}),
|
|
155
|
+
)
|
|
156
|
+
.threshold(10)
|
|
157
|
+
.lessThan()
|
|
158
|
+
.description("Bucket traffic has dropped below expected level"),
|
|
159
|
+
);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Applying alarm actions
|
|
163
|
+
|
|
164
|
+
Alarms are returned in the build result as `Record<string, Alarm>`:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
const result = site.build(stack, "SiteBucket");
|
|
168
|
+
|
|
169
|
+
const alertTopic = new Topic(stack, "AlertTopic");
|
|
170
|
+
for (const alarm of Object.values(result.alarms)) {
|
|
171
|
+
alarm.addAlarmAction(new SnsAction(alertTopic));
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Bucket Deployment Builder
|
|
176
|
+
|
|
177
|
+
Deploys local assets to an S3 bucket with optional CloudFront cache invalidation.
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import { createBucketDeploymentBuilder } from "@composurecdk/s3";
|
|
181
|
+
import { Source } from "aws-cdk-lib/aws-s3-deployment";
|
|
182
|
+
|
|
183
|
+
const deploy = createBucketDeploymentBuilder()
|
|
184
|
+
.sources([Source.asset("./site")])
|
|
185
|
+
.destinationBucket(myBucket)
|
|
186
|
+
.build(stack, "Deploy");
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The `destinationBucket` and `distribution` methods accept `Ref` values for cross-component wiring:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { compose, ref } from "@composurecdk/core";
|
|
193
|
+
|
|
194
|
+
const deploy = createBucketDeploymentBuilder()
|
|
195
|
+
.sources([Source.asset("./site")])
|
|
196
|
+
.destinationBucket(ref("site", (r) => r.bucket))
|
|
197
|
+
.distribution(ref("cdn", (r) => r.distribution));
|
|
198
|
+
|
|
199
|
+
compose(
|
|
200
|
+
{ site: createBucketBuilder(), cdn: createDistributionBuilder(), deploy },
|
|
201
|
+
{ site: [], cdn: ["site"], deploy: ["site", "cdn"] },
|
|
202
|
+
).build(stack, "Website");
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Secure Defaults
|
|
206
|
+
|
|
207
|
+
`createBucketDeploymentBuilder` applies the following defaults. Each can be overridden via the builder's fluent API.
|
|
208
|
+
|
|
209
|
+
| Property | Default | Rationale |
|
|
210
|
+
| ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
211
|
+
| `prune` | `true` | Removes stale files from the destination, keeping it in sync with the source. |
|
|
212
|
+
| `memoryLimit` | `256` | Allocates 256 MiB to the deployment Lambda (CDK default of 128 MiB is insufficient for larger deployments). |
|
|
213
|
+
| `retainOnDelete` | `false` | Does not retain deployed files on stack deletion, consistent with prune semantics. |
|
|
214
|
+
| `distributionPaths` | `["/*"]` | Invalidates all CloudFront paths so content is immediately visible. Only applied when a distribution is configured. |
|
|
215
|
+
|
|
216
|
+
The builder also auto-creates a managed CloudWatch LogGroup (using `@composurecdk/logs` with its secure defaults) for the deployment's backing Lambda, preventing the auto-created log group with infinite retention.
|
|
217
|
+
|
|
218
|
+
The defaults are exported as `BUCKET_DEPLOYMENT_DEFAULTS` for visibility and testing:
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
import { BUCKET_DEPLOYMENT_DEFAULTS } from "@composurecdk/s3";
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Examples
|
|
225
|
+
|
|
226
|
+
- [StaticWebsiteStack](../examples/src/static-website/app.ts) — S3 + CloudFront static website with OAC, error pages, and content deployment
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AlarmConfig } from "@composurecdk/cloudwatch";
|
|
2
|
+
/**
|
|
3
|
+
* Controls which recommended alarms are created for an S3 bucket.
|
|
4
|
+
* All applicable alarms are enabled by default with AWS-recommended thresholds.
|
|
5
|
+
* Set individual alarms to `false` to disable them, or provide an
|
|
6
|
+
* {@link AlarmConfig} to tune thresholds.
|
|
7
|
+
*
|
|
8
|
+
* S3 request metric alarms (5xxErrors, 4xxErrors) require
|
|
9
|
+
* [CloudWatch request metrics](https://docs.aws.amazon.com/AmazonS3/latest/userguide/configure-request-metrics-bucket.html)
|
|
10
|
+
* to be enabled on the bucket. Alarms are automatically created for each
|
|
11
|
+
* entry in the bucket's {@link BucketProps.metrics} array, keyed by the
|
|
12
|
+
* metrics configuration ID (e.g. `serverErrors:EntireBucket`).
|
|
13
|
+
*
|
|
14
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
15
|
+
*/
|
|
16
|
+
export interface BucketAlarmConfig {
|
|
17
|
+
/**
|
|
18
|
+
* Master switch: set to `false` to disable all recommended alarms.
|
|
19
|
+
* Individual alarms can also be disabled via their own entry.
|
|
20
|
+
* @default true
|
|
21
|
+
*/
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Alarm when S3 returns server-side errors (5xx HTTP status codes).
|
|
25
|
+
*
|
|
26
|
+
* Metric: `AWS/S3 5xxErrors`, statistic Sum, period 5 minutes.
|
|
27
|
+
* Default threshold: > 0 errors.
|
|
28
|
+
*
|
|
29
|
+
* Only created when the bucket has request metrics configured via
|
|
30
|
+
* {@link BucketProps.metrics}. One alarm per metrics configuration.
|
|
31
|
+
*
|
|
32
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
33
|
+
*/
|
|
34
|
+
serverErrors?: AlarmConfig | false;
|
|
35
|
+
/**
|
|
36
|
+
* Alarm when S3 returns client-side errors (4xx HTTP status codes).
|
|
37
|
+
*
|
|
38
|
+
* Metric: `AWS/S3 4xxErrors`, statistic Sum, period 5 minutes.
|
|
39
|
+
* Default threshold: > 0 errors.
|
|
40
|
+
*
|
|
41
|
+
* Only created when the bucket has request metrics configured via
|
|
42
|
+
* {@link BucketProps.metrics}. One alarm per metrics configuration.
|
|
43
|
+
*
|
|
44
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
45
|
+
*/
|
|
46
|
+
clientErrors?: AlarmConfig | false;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=alarm-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-config.d.ts","sourceRoot":"","sources":["../src/alarm-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAEnC;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;CACpC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-config.js","sourceRoot":"","sources":["../src/alarm-config.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AlarmConfig } from "@composurecdk/cloudwatch";
|
|
2
|
+
interface BucketAlarmDefaults {
|
|
3
|
+
enabled: true;
|
|
4
|
+
serverErrors: Required<AlarmConfig>;
|
|
5
|
+
clientErrors: Required<AlarmConfig>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* AWS-recommended default alarm configuration for S3 buckets.
|
|
9
|
+
*
|
|
10
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
11
|
+
*/
|
|
12
|
+
export declare const BUCKET_ALARM_DEFAULTS: BucketAlarmDefaults;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=alarm-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-defaults.d.ts","sourceRoot":"","sources":["../src/alarm-defaults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,UAAU,mBAAmB;IAC3B,OAAO,EAAE,IAAI,CAAC;IACd,YAAY,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpC,YAAY,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CACrC;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAkBnC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
|
|
2
|
+
/**
|
|
3
|
+
* AWS-recommended default alarm configuration for S3 buckets.
|
|
4
|
+
*
|
|
5
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
6
|
+
*/
|
|
7
|
+
export const BUCKET_ALARM_DEFAULTS = {
|
|
8
|
+
enabled: true,
|
|
9
|
+
/** Any server-side error is worth investigating; threshold 0. */
|
|
10
|
+
serverErrors: {
|
|
11
|
+
threshold: 0,
|
|
12
|
+
evaluationPeriods: 1,
|
|
13
|
+
datapointsToAlarm: 1,
|
|
14
|
+
treatMissingData: TreatMissingData.NOT_BREACHING,
|
|
15
|
+
},
|
|
16
|
+
/** Any client-side error pattern is worth investigating; threshold 0. */
|
|
17
|
+
clientErrors: {
|
|
18
|
+
threshold: 0,
|
|
19
|
+
evaluationPeriods: 1,
|
|
20
|
+
datapointsToAlarm: 1,
|
|
21
|
+
treatMissingData: TreatMissingData.NOT_BREACHING,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=alarm-defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alarm-defaults.js","sourceRoot":"","sources":["../src/alarm-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAS9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAwB;IACxD,OAAO,EAAE,IAAI;IAEb,iEAAiE;IACjE,YAAY,EAAE;QACZ,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED,yEAAyE;IACzE,YAAY,EAAE;QACZ,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;CACF,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
|
|
2
|
+
import type { Bucket, BucketMetrics } from "aws-cdk-lib/aws-s3";
|
|
3
|
+
import type { IConstruct } from "constructs";
|
|
4
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
5
|
+
import type { AlarmDefinition } from "@composurecdk/cloudwatch";
|
|
6
|
+
import type { BucketAlarmConfig } from "./alarm-config.js";
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the recommended alarm configuration into fully-resolved
|
|
9
|
+
* {@link AlarmDefinition}s for an S3 bucket.
|
|
10
|
+
*
|
|
11
|
+
* Creates alarms for each entry in `metricsConfigs`, keyed as
|
|
12
|
+
* `{alarmType}:{filterId}` (e.g. `serverErrors:EntireBucket`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveBucketAlarmDefinitions(bucket: Bucket, config: BucketAlarmConfig | undefined, metricsConfigs: BucketMetrics[]): AlarmDefinition[];
|
|
15
|
+
/**
|
|
16
|
+
* Creates AWS-recommended CloudWatch alarms for an S3 bucket,
|
|
17
|
+
* merging recommended definitions with any custom alarm builders.
|
|
18
|
+
*
|
|
19
|
+
* Alarms are created for each entry in `metricsConfigs` (from
|
|
20
|
+
* {@link BucketProps.metrics}). If no metrics configurations are
|
|
21
|
+
* provided, only custom alarms are created.
|
|
22
|
+
*
|
|
23
|
+
* @param scope - CDK construct scope for creating alarm constructs.
|
|
24
|
+
* @param id - Base identifier for alarm construct ids.
|
|
25
|
+
* @param bucket - The S3 bucket to create alarms for.
|
|
26
|
+
* @param config - User-provided alarm configuration, or `false` to disable all.
|
|
27
|
+
* @param metricsConfigs - The bucket's request metrics configurations.
|
|
28
|
+
* @param customAlarms - Custom alarm builders added via `addAlarm()`.
|
|
29
|
+
* @returns A record mapping alarm keys to their created Alarm constructs.
|
|
30
|
+
*
|
|
31
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
32
|
+
*/
|
|
33
|
+
export declare function createBucketAlarms(scope: IConstruct, id: string, bucket: Bucket, config: BucketAlarmConfig | false | undefined, metricsConfigs: BucketMetrics[], customAlarms?: AlarmDefinitionBuilder<Bucket>[]): Record<string, Alarm>;
|
|
34
|
+
//# sourceMappingURL=bucket-alarms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bucket-alarms.d.ts","sourceRoot":"","sources":["../src/bucket-alarms.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,KAAK,EAAqC,MAAM,4BAA4B,CAAC;AAC3F,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAoC,MAAM,0BAA0B,CAAC;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AA2B3D;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,iBAAiB,GAAG,SAAS,EACrC,cAAc,EAAE,aAAa,EAAE,GAC9B,eAAe,EAAE,CAuCnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,iBAAiB,GAAG,KAAK,GAAG,SAAS,EAC7C,cAAc,EAAE,aAAa,EAAE,EAC/B,YAAY,GAAE,sBAAsB,CAAC,MAAM,CAAC,EAAO,GAClD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAUvB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Duration } from "aws-cdk-lib";
|
|
2
|
+
import { ComparisonOperator, Metric, Stats } from "aws-cdk-lib/aws-cloudwatch";
|
|
3
|
+
import { createAlarms, resolveAlarmConfig } from "@composurecdk/cloudwatch";
|
|
4
|
+
import { BUCKET_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
5
|
+
const METRIC_PERIOD = Duration.minutes(5);
|
|
6
|
+
const METRIC_PERIOD_LABEL = `${String(METRIC_PERIOD.toMinutes())} minutes`;
|
|
7
|
+
/**
|
|
8
|
+
* Creates an S3 request metric with the correct namespace and dimensions.
|
|
9
|
+
*/
|
|
10
|
+
function s3RequestMetric(bucket, filterId, metricName, statistic) {
|
|
11
|
+
return new Metric({
|
|
12
|
+
namespace: "AWS/S3",
|
|
13
|
+
metricName,
|
|
14
|
+
dimensionsMap: {
|
|
15
|
+
BucketName: bucket.bucketName,
|
|
16
|
+
FilterId: filterId,
|
|
17
|
+
},
|
|
18
|
+
statistic,
|
|
19
|
+
period: METRIC_PERIOD,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolves the recommended alarm configuration into fully-resolved
|
|
24
|
+
* {@link AlarmDefinition}s for an S3 bucket.
|
|
25
|
+
*
|
|
26
|
+
* Creates alarms for each entry in `metricsConfigs`, keyed as
|
|
27
|
+
* `{alarmType}:{filterId}` (e.g. `serverErrors:EntireBucket`).
|
|
28
|
+
*/
|
|
29
|
+
export function resolveBucketAlarmDefinitions(bucket, config, metricsConfigs) {
|
|
30
|
+
if (config?.enabled === false)
|
|
31
|
+
return [];
|
|
32
|
+
if (metricsConfigs.length === 0)
|
|
33
|
+
return [];
|
|
34
|
+
const definitions = [];
|
|
35
|
+
for (const metrics of metricsConfigs) {
|
|
36
|
+
const filterId = metrics.id;
|
|
37
|
+
if (config?.serverErrors !== false) {
|
|
38
|
+
const cfg = resolveAlarmConfig(config?.serverErrors, BUCKET_ALARM_DEFAULTS.serverErrors);
|
|
39
|
+
definitions.push({
|
|
40
|
+
key: `serverErrors:${filterId}`,
|
|
41
|
+
metric: s3RequestMetric(bucket, filterId, "5xxErrors", Stats.SUM),
|
|
42
|
+
threshold: cfg.threshold,
|
|
43
|
+
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
44
|
+
evaluationPeriods: cfg.evaluationPeriods,
|
|
45
|
+
datapointsToAlarm: cfg.datapointsToAlarm,
|
|
46
|
+
treatMissingData: cfg.treatMissingData,
|
|
47
|
+
description: `S3 bucket is returning server-side errors (filter: ${filterId}). Threshold: > ${String(cfg.threshold)} 5xx errors in ${METRIC_PERIOD_LABEL}.`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (config?.clientErrors !== false) {
|
|
51
|
+
const cfg = resolveAlarmConfig(config?.clientErrors, BUCKET_ALARM_DEFAULTS.clientErrors);
|
|
52
|
+
definitions.push({
|
|
53
|
+
key: `clientErrors:${filterId}`,
|
|
54
|
+
metric: s3RequestMetric(bucket, filterId, "4xxErrors", Stats.SUM),
|
|
55
|
+
threshold: cfg.threshold,
|
|
56
|
+
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
57
|
+
evaluationPeriods: cfg.evaluationPeriods,
|
|
58
|
+
datapointsToAlarm: cfg.datapointsToAlarm,
|
|
59
|
+
treatMissingData: cfg.treatMissingData,
|
|
60
|
+
description: `S3 bucket is returning client-side errors (filter: ${filterId}). Threshold: > ${String(cfg.threshold)} 4xx errors in ${METRIC_PERIOD_LABEL}.`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return definitions;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Creates AWS-recommended CloudWatch alarms for an S3 bucket,
|
|
68
|
+
* merging recommended definitions with any custom alarm builders.
|
|
69
|
+
*
|
|
70
|
+
* Alarms are created for each entry in `metricsConfigs` (from
|
|
71
|
+
* {@link BucketProps.metrics}). If no metrics configurations are
|
|
72
|
+
* provided, only custom alarms are created.
|
|
73
|
+
*
|
|
74
|
+
* @param scope - CDK construct scope for creating alarm constructs.
|
|
75
|
+
* @param id - Base identifier for alarm construct ids.
|
|
76
|
+
* @param bucket - The S3 bucket to create alarms for.
|
|
77
|
+
* @param config - User-provided alarm configuration, or `false` to disable all.
|
|
78
|
+
* @param metricsConfigs - The bucket's request metrics configurations.
|
|
79
|
+
* @param customAlarms - Custom alarm builders added via `addAlarm()`.
|
|
80
|
+
* @returns A record mapping alarm keys to their created Alarm constructs.
|
|
81
|
+
*
|
|
82
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
83
|
+
*/
|
|
84
|
+
export function createBucketAlarms(scope, id, bucket, config, metricsConfigs, customAlarms = []) {
|
|
85
|
+
if (config === false)
|
|
86
|
+
return {};
|
|
87
|
+
const enabled = config?.enabled ?? BUCKET_ALARM_DEFAULTS.enabled;
|
|
88
|
+
if (!enabled)
|
|
89
|
+
return {};
|
|
90
|
+
const recommended = resolveBucketAlarmDefinitions(bucket, config, metricsConfigs);
|
|
91
|
+
const custom = customAlarms.map((b) => b.resolve(bucket));
|
|
92
|
+
return createAlarms(scope, id, [...recommended, ...custom]);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=bucket-alarms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bucket-alarms.js","sourceRoot":"","sources":["../src/bucket-alarms.ts"],"names":[],"mappings":"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"}
|
package/dist/bucket-builder.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
|
|
1
2
|
import { Bucket, type BucketProps } from "aws-cdk-lib/aws-s3";
|
|
2
3
|
import { type IConstruct } from "constructs";
|
|
3
4
|
import { type IBuilder, type Lifecycle } from "@composurecdk/core";
|
|
5
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
6
|
+
import type { BucketAlarmConfig } from "./alarm-config.js";
|
|
4
7
|
/**
|
|
5
8
|
* Configuration properties for the S3 bucket builder.
|
|
6
9
|
*
|
|
@@ -35,6 +38,21 @@ export interface BucketBuilderProps extends BucketProps {
|
|
|
35
38
|
* @default "logs/"
|
|
36
39
|
*/
|
|
37
40
|
accessLogsPrefix?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Configuration for AWS-recommended CloudWatch alarms.
|
|
43
|
+
*
|
|
44
|
+
* S3 request metric alarms (5xxErrors, 4xxErrors) require
|
|
45
|
+
* [CloudWatch request metrics](https://docs.aws.amazon.com/AmazonS3/latest/userguide/configure-request-metrics-bucket.html)
|
|
46
|
+
* to be enabled on the bucket. Set {@link BucketAlarmConfig.requestMetricsFilterId}
|
|
47
|
+
* to the ID of the request metrics configuration to create these alarms.
|
|
48
|
+
*
|
|
49
|
+
* No alarm actions are configured by default since notification
|
|
50
|
+
* methods are user-specific. Access alarms from the build result
|
|
51
|
+
* or use an `afterBuild` hook to apply actions.
|
|
52
|
+
*
|
|
53
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
54
|
+
*/
|
|
55
|
+
recommendedAlarms?: BucketAlarmConfig | false;
|
|
38
56
|
}
|
|
39
57
|
/**
|
|
40
58
|
* The build output of a {@link IBucketBuilder}. Contains the CDK constructs
|
|
@@ -48,6 +66,19 @@ export interface BucketBuilderResult {
|
|
|
48
66
|
* logging was disabled or the user provided their own destination.
|
|
49
67
|
*/
|
|
50
68
|
accessLogsBucket?: Bucket;
|
|
69
|
+
/**
|
|
70
|
+
* CloudWatch alarms created for the bucket, keyed by alarm name.
|
|
71
|
+
*
|
|
72
|
+
* Includes both AWS-recommended alarms and any custom alarms added
|
|
73
|
+
* via {@link IBucketBuilder.addAlarm}. Access individual alarms
|
|
74
|
+
* by key (e.g., `result.alarms.serverErrors`).
|
|
75
|
+
*
|
|
76
|
+
* No alarm actions are configured — apply them via the result or an
|
|
77
|
+
* `afterBuild` hook.
|
|
78
|
+
*
|
|
79
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#S3
|
|
80
|
+
*/
|
|
81
|
+
alarms: Record<string, Alarm>;
|
|
51
82
|
}
|
|
52
83
|
/**
|
|
53
84
|
* A fluent builder for configuring and creating an Amazon S3 bucket.
|
|
@@ -71,6 +102,8 @@ export interface BucketBuilderResult {
|
|
|
71
102
|
export type IBucketBuilder = IBuilder<BucketBuilderProps, BucketBuilder>;
|
|
72
103
|
declare class BucketBuilder implements Lifecycle<BucketBuilderResult> {
|
|
73
104
|
props: Partial<BucketBuilderProps>;
|
|
105
|
+
private readonly customAlarms;
|
|
106
|
+
addAlarm(key: string, configure: (alarm: AlarmDefinitionBuilder<Bucket>) => AlarmDefinitionBuilder<Bucket>): this;
|
|
74
107
|
build(scope: IConstruct, id: string): BucketBuilderResult;
|
|
75
108
|
}
|
|
76
109
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bucket-builder.d.ts","sourceRoot":"","sources":["../src/bucket-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAW,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"bucket-builder.d.ts","sourceRoot":"","sources":["../src/bucket-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAW,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI3D;;;;GAIG;AACH,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD;;;;;;;;;;;;;;;;OAgBG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;;;;;;;OAaG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAC;CAC/C;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;AAEzE,cAAM,aAAc,YAAW,SAAS,CAAC,mBAAmB,CAAC;IAC3D,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAM;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;IAErE,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CAAC,KAAK,EAAE,sBAAsB,CAAC,MAAM,CAAC,KAAK,sBAAsB,CAAC,MAAM,CAAC,GACnF,IAAI;IAKP,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,mBAAmB;CA8D1D;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAEpD"}
|
package/dist/bucket-builder.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { RemovalPolicy } from "aws-cdk-lib";
|
|
2
2
|
import { Bucket } from "aws-cdk-lib/aws-s3";
|
|
3
3
|
import { Builder } from "@composurecdk/core";
|
|
4
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
5
|
+
import { createBucketAlarms } from "./bucket-alarms.js";
|
|
4
6
|
import { BUCKET_DEFAULTS } from "./defaults.js";
|
|
5
7
|
class BucketBuilder {
|
|
6
8
|
props = {};
|
|
9
|
+
customAlarms = [];
|
|
10
|
+
addAlarm(key, configure) {
|
|
11
|
+
this.customAlarms.push(configure(new AlarmDefinitionBuilder(key)));
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
7
14
|
build(scope, id) {
|
|
8
|
-
const { accessLogging, accessLogsPrefix, ...bucketProps } = this.props;
|
|
15
|
+
const { accessLogging, accessLogsPrefix, recommendedAlarms: alarmConfig, ...bucketProps } = this.props;
|
|
9
16
|
const { accessLogging: defaultAccessLogging, accessLogsPrefix: defaultLogsPrefix, ...cdkDefaults } = BUCKET_DEFAULTS;
|
|
10
17
|
const autoAccessLog = (accessLogging ?? defaultAccessLogging) && !bucketProps.serverAccessLogsBucket;
|
|
11
18
|
if (accessLogsPrefix !== undefined && !autoAccessLog) {
|
|
@@ -18,6 +25,7 @@ class BucketBuilder {
|
|
|
18
25
|
if (autoAccessLog) {
|
|
19
26
|
accessLogsBucket = createBucketBuilder()
|
|
20
27
|
.accessLogging(false)
|
|
28
|
+
.versioned(false)
|
|
21
29
|
.removalPolicy(RemovalPolicy.RETAIN)
|
|
22
30
|
.build(scope, `${id}AccessLogs`).bucket;
|
|
23
31
|
accessLogProps = {
|
|
@@ -31,9 +39,12 @@ class BucketBuilder {
|
|
|
31
39
|
...bucketProps,
|
|
32
40
|
...autoDeleteProps(bucketProps, BUCKET_DEFAULTS),
|
|
33
41
|
};
|
|
42
|
+
const bucket = new Bucket(scope, id, mergedProps);
|
|
43
|
+
const alarms = createBucketAlarms(scope, id, bucket, alarmConfig, bucketProps.metrics ?? [], this.customAlarms);
|
|
34
44
|
return {
|
|
35
|
-
bucket
|
|
45
|
+
bucket,
|
|
36
46
|
accessLogsBucket,
|
|
47
|
+
alarms,
|
|
37
48
|
};
|
|
38
49
|
}
|
|
39
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bucket-builder.js","sourceRoot":"","sources":["../src/bucket-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"bucket-builder.js","sourceRoot":"","sources":["../src/bucket-builder.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { createBucketBuilder, type BucketBuilderResult, type IBucketBuilder, } from "./bucket-builder.js";
|
|
2
2
|
export { BUCKET_DEFAULTS } from "./defaults.js";
|
|
3
|
+
export { type BucketAlarmConfig } from "./alarm-config.js";
|
|
4
|
+
export { BUCKET_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
3
5
|
export { createBucketDeploymentBuilder, type BucketDeploymentBuilderResult, type IBucketDeploymentBuilder, } from "./bucket-deployment-builder.js";
|
|
4
6
|
export { BUCKET_DEPLOYMENT_DEFAULTS } from "./bucket-deployment-defaults.js";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,GAC9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,6BAA6B,EAC7B,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,GAC9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { createBucketBuilder, } from "./bucket-builder.js";
|
|
2
2
|
export { BUCKET_DEFAULTS } from "./defaults.js";
|
|
3
|
+
export { BUCKET_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
3
4
|
export { createBucketDeploymentBuilder, } from "./bucket-deployment-builder.js";
|
|
4
5
|
export { BUCKET_DEPLOYMENT_DEFAULTS } from "./bucket-deployment-defaults.js";
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,GAGpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,GAGpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,6BAA6B,GAG9B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@composurecdk/s3",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Composable S3 bucket builder with well-architected defaults",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,16 +35,17 @@
|
|
|
35
35
|
},
|
|
36
36
|
"type": "module",
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@composurecdk/
|
|
39
|
-
"@composurecdk/
|
|
38
|
+
"@composurecdk/cloudwatch": "^0.3.0",
|
|
39
|
+
"@composurecdk/core": "^0.3.0",
|
|
40
|
+
"@composurecdk/logs": "^0.3.0",
|
|
40
41
|
"aws-cdk-lib": "^2.0.0",
|
|
41
42
|
"constructs": "^10.0.0"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
|
-
"@types/node": "^25.
|
|
45
|
-
"aws-cdk-lib": "^2.
|
|
45
|
+
"@types/node": "^25.6.0",
|
|
46
|
+
"aws-cdk-lib": "^2.250.0",
|
|
46
47
|
"constructs": "^10.6.0",
|
|
47
|
-
"typescript": "^6.0.
|
|
48
|
-
"vitest": "^4.1.
|
|
48
|
+
"typescript": "^6.0.3",
|
|
49
|
+
"vitest": "^4.1.4"
|
|
49
50
|
}
|
|
50
51
|
}
|