@composurecdk/cloudfront 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 +182 -0
- package/dist/alarm-config.d.ts +45 -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 +31 -0
- package/dist/alarm-defaults.js.map +1 -0
- package/dist/distribution-alarms.d.ts +26 -0
- package/dist/distribution-alarms.d.ts.map +1 -0
- package/dist/distribution-alarms.js +82 -0
- package/dist/distribution-alarms.js.map +1 -0
- package/dist/distribution-builder.d.ts +46 -1
- package/dist/distribution-builder.d.ts.map +1 -1
- package/dist/distribution-builder.js +23 -2
- package/dist/distribution-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,182 @@
|
|
|
1
|
+
# @composurecdk/cloudfront
|
|
2
|
+
|
|
3
|
+
CloudFront builders for [ComposureCDK](../../README.md).
|
|
4
|
+
|
|
5
|
+
This package provides a fluent builder for CloudFront distributions with secure, AWS-recommended defaults. It wraps the CDK [Distribution](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudfront.Distribution.html) construct — refer to the CDK documentation for the full set of configurable properties.
|
|
6
|
+
|
|
7
|
+
## Distribution Builder
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { createDistributionBuilder } from "@composurecdk/cloudfront";
|
|
11
|
+
import { S3BucketOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
|
|
12
|
+
|
|
13
|
+
const cdn = createDistributionBuilder()
|
|
14
|
+
.origin(S3BucketOrigin.withOriginAccessControl(bucket))
|
|
15
|
+
.comment("My website CDN")
|
|
16
|
+
.build(stack, "CDN");
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Every [DistributionProps](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudfront.DistributionProps.html) property (except `defaultBehavior.origin`) is available as a fluent setter on the builder. The origin is set via the dedicated `.origin()` method, which supports `Ref` for cross-component wiring.
|
|
20
|
+
|
|
21
|
+
### Cross-component wiring
|
|
22
|
+
|
|
23
|
+
The `origin` method accepts a `Ref` for use in composed systems:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { compose, ref } from "@composurecdk/core";
|
|
27
|
+
import type { BucketBuilderResult } from "@composurecdk/s3";
|
|
28
|
+
|
|
29
|
+
const cdn = createDistributionBuilder().origin(
|
|
30
|
+
ref<BucketBuilderResult>("site", (r) => S3BucketOrigin.withOriginAccessControl(r.bucket)),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
compose({ site: createBucketBuilder(), cdn }, { site: [], cdn: ["site"] }).build(stack, "Website");
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Secure Defaults
|
|
37
|
+
|
|
38
|
+
`createDistributionBuilder` applies the following defaults. Each can be overridden via the builder's fluent API.
|
|
39
|
+
|
|
40
|
+
| Property | Default | Rationale |
|
|
41
|
+
| --------------------------------------- | ------------------- | ------------------------------------------------------------------------ |
|
|
42
|
+
| `accessLogging` | `true` | Auto-creates an S3 logging bucket for access log audit trail. |
|
|
43
|
+
| `priceClass` | `PRICE_CLASS_100` | North America and Europe edge locations — sufficient and cost-effective. |
|
|
44
|
+
| `httpVersion` | `HTTP2_AND_3` | Enables HTTP/2 and HTTP/3 (QUIC) for improved performance. |
|
|
45
|
+
| `defaultRootObject` | `"index.html"` | Standard for static website hosting. |
|
|
46
|
+
| `minimumProtocolVersion` | `TLS_V1_2_2021` | Requires TLS 1.2+ to prevent older, less secure protocol negotiation. |
|
|
47
|
+
| `defaultBehavior.viewerProtocolPolicy` | `REDIRECT_TO_HTTPS` | Ensures all viewer traffic is encrypted in transit. |
|
|
48
|
+
| `defaultBehavior.responseHeadersPolicy` | `SECURITY_HEADERS` | Applies managed security headers (HSTS, X-Content-Type-Options, etc.). |
|
|
49
|
+
|
|
50
|
+
These defaults are guided by the [AWS Well-Architected Security Pillar](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/protecting-data-in-transit.html).
|
|
51
|
+
|
|
52
|
+
The defaults are exported as `DISTRIBUTION_DEFAULTS` for visibility and testing:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { DISTRIBUTION_DEFAULTS } from "@composurecdk/cloudfront";
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Overriding defaults
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { PriceClass, ViewerProtocolPolicy } from "aws-cdk-lib/aws-cloudfront";
|
|
62
|
+
|
|
63
|
+
const cdn = createDistributionBuilder()
|
|
64
|
+
.origin(myOrigin)
|
|
65
|
+
.priceClass(PriceClass.PRICE_CLASS_ALL)
|
|
66
|
+
.accessLogging(false)
|
|
67
|
+
.defaultBehavior({ viewerProtocolPolicy: ViewerProtocolPolicy.ALLOW_ALL })
|
|
68
|
+
.build(stack, "CDN");
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Access logging
|
|
72
|
+
|
|
73
|
+
By default, the builder creates an S3 logging bucket (using `@composurecdk/s3` with its secure defaults) and configures it as the distribution's log destination. The created bucket is returned in the build result:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
const result = createDistributionBuilder().origin(myOrigin).build(stack, "CDN");
|
|
77
|
+
|
|
78
|
+
result.distribution; // Distribution
|
|
79
|
+
result.accessLogsBucket; // Bucket | undefined
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
To provide your own bucket instead, set `logBucket` — the auto-created logging bucket is skipped. To disable access logging entirely, set `.accessLogging(false)`.
|
|
83
|
+
|
|
84
|
+
## Recommended Alarms
|
|
85
|
+
|
|
86
|
+
The builder creates [AWS-recommended CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront) by default. No alarm actions are configured — access alarms from the build result to add SNS topics or other actions.
|
|
87
|
+
|
|
88
|
+
| Alarm | Metric | Default threshold | Created when |
|
|
89
|
+
| --------------- | ----------------------------- | ----------------- | ------------ |
|
|
90
|
+
| `errorRate` | 5xxErrorRate (Average, 1 min) | > 5 (5%) | Always |
|
|
91
|
+
| `originLatency` | OriginLatency (p90, 1 min) | > 5000ms | Always |
|
|
92
|
+
|
|
93
|
+
The `originLatency` alarm requires [additional CloudFront metrics](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/viewing-cloudfront-metrics.html#monitoring-console.distributions-additional) to be enabled on the distribution. With the default `treatMissingData: NOT_BREACHING`, the alarm will not fire when additional metrics are not enabled.
|
|
94
|
+
|
|
95
|
+
Function-level alarms (FunctionValidationErrors, FunctionExecutionErrors, FunctionThrottles) require per-function dimensions. Use `addAlarm` to add them — see [Custom alarms](#custom-alarms) below.
|
|
96
|
+
|
|
97
|
+
The defaults are exported as `DISTRIBUTION_ALARM_DEFAULTS` for visibility and testing:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { DISTRIBUTION_ALARM_DEFAULTS } from "@composurecdk/cloudfront";
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Customizing thresholds
|
|
104
|
+
|
|
105
|
+
Override individual alarm properties via `recommendedAlarms`. Unspecified fields keep their defaults.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const cdn = createDistributionBuilder()
|
|
109
|
+
.origin(myOrigin)
|
|
110
|
+
.recommendedAlarms({
|
|
111
|
+
errorRate: { threshold: 2, evaluationPeriods: 3 },
|
|
112
|
+
originLatency: { threshold: 3000 },
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Disabling alarms
|
|
117
|
+
|
|
118
|
+
Disable all recommended alarms:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
builder.recommendedAlarms(false);
|
|
122
|
+
// or
|
|
123
|
+
builder.recommendedAlarms({ enabled: false });
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Disable individual alarms:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
builder.recommendedAlarms({ errorRate: false });
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Custom alarms
|
|
133
|
+
|
|
134
|
+
Add custom alarms alongside the recommended ones via `addAlarm`. The callback receives an `AlarmDefinitionBuilder` typed to the CloudFront `Distribution`.
|
|
135
|
+
|
|
136
|
+
For function-level alarms, provide the function name dimension:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { Metric } from "aws-cdk-lib/aws-cloudwatch";
|
|
140
|
+
|
|
141
|
+
const cdn = createDistributionBuilder()
|
|
142
|
+
.origin(myOrigin)
|
|
143
|
+
.addAlarm("functionErrors", (alarm) =>
|
|
144
|
+
alarm
|
|
145
|
+
.metric(
|
|
146
|
+
(dist) =>
|
|
147
|
+
new Metric({
|
|
148
|
+
namespace: "AWS/CloudFront",
|
|
149
|
+
metricName: "FunctionExecutionErrors",
|
|
150
|
+
dimensionsMap: {
|
|
151
|
+
DistributionId: dist.distributionId,
|
|
152
|
+
FunctionName: "MyViewerRequestFn",
|
|
153
|
+
Region: "Global",
|
|
154
|
+
},
|
|
155
|
+
statistic: "Sum",
|
|
156
|
+
period: Duration.minutes(1),
|
|
157
|
+
}),
|
|
158
|
+
)
|
|
159
|
+
.threshold(0)
|
|
160
|
+
.greaterThan()
|
|
161
|
+
.evaluationPeriods(5)
|
|
162
|
+
.datapointsToAlarm(5)
|
|
163
|
+
.description("CloudFront function execution errors detected"),
|
|
164
|
+
);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Applying alarm actions
|
|
168
|
+
|
|
169
|
+
Alarms are returned in the build result as `Record<string, Alarm>`:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
const result = cdn.build(stack, "CDN");
|
|
173
|
+
|
|
174
|
+
const alertTopic = new Topic(stack, "AlertTopic");
|
|
175
|
+
for (const alarm of Object.values(result.alarms)) {
|
|
176
|
+
alarm.addAlarmAction(new SnsAction(alertTopic));
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Examples
|
|
181
|
+
|
|
182
|
+
- [StaticWebsiteStack](../examples/src/static-website/app.ts) — S3 + CloudFront static website with OAC, error pages, and content deployment
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { AlarmConfig } from "@composurecdk/cloudwatch";
|
|
2
|
+
/**
|
|
3
|
+
* Controls which recommended alarms are created for a CloudFront distribution.
|
|
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
|
+
* Function-level alarms (FunctionValidationErrors, FunctionExecutionErrors,
|
|
9
|
+
* FunctionThrottles) require per-function dimensions and are not created
|
|
10
|
+
* automatically. Use {@link IDistributionBuilder.addAlarm} to add them.
|
|
11
|
+
*
|
|
12
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
13
|
+
*/
|
|
14
|
+
export interface DistributionAlarmConfig {
|
|
15
|
+
/**
|
|
16
|
+
* Master switch: set to `false` to disable all recommended alarms.
|
|
17
|
+
* Individual alarms can also be disabled via their own entry.
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Alarm when the distribution's 5xx error rate is elevated.
|
|
23
|
+
*
|
|
24
|
+
* Metric: `AWS/CloudFront 5xxErrorRate`, statistic Average, period 1 minute.
|
|
25
|
+
* Default threshold: > 5 (5% error rate).
|
|
26
|
+
*
|
|
27
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
28
|
+
*/
|
|
29
|
+
errorRate?: AlarmConfig | false;
|
|
30
|
+
/**
|
|
31
|
+
* Alarm when origin response latency is elevated.
|
|
32
|
+
*
|
|
33
|
+
* Metric: `AWS/CloudFront OriginLatency`, statistic p90, period 1 minute.
|
|
34
|
+
* Default threshold: > 5000ms (5 seconds).
|
|
35
|
+
*
|
|
36
|
+
* Requires [additional CloudFront metrics](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/viewing-cloudfront-metrics.html#monitoring-console.distributions-additional)
|
|
37
|
+
* to be enabled on the distribution for this alarm to receive data.
|
|
38
|
+
* With the default `treatMissingData: NOT_BREACHING`, the alarm will
|
|
39
|
+
* not fire when additional metrics are not enabled.
|
|
40
|
+
*
|
|
41
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
42
|
+
*/
|
|
43
|
+
originLatency?: AlarmConfig | false;
|
|
44
|
+
}
|
|
45
|
+
//# 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;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;CACrC"}
|
|
@@ -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 DistributionAlarmDefaults {
|
|
3
|
+
enabled: true;
|
|
4
|
+
errorRate: Required<AlarmConfig>;
|
|
5
|
+
originLatency: Required<AlarmConfig>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* AWS-recommended default alarm configuration for CloudFront distributions.
|
|
9
|
+
*
|
|
10
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
11
|
+
*/
|
|
12
|
+
export declare const DISTRIBUTION_ALARM_DEFAULTS: DistributionAlarmDefaults;
|
|
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,yBAAyB;IACjC,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACjC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CACtC;AAED;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,yBAyBzC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
|
|
2
|
+
/**
|
|
3
|
+
* AWS-recommended default alarm configuration for CloudFront distributions.
|
|
4
|
+
*
|
|
5
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
6
|
+
*/
|
|
7
|
+
export const DISTRIBUTION_ALARM_DEFAULTS = {
|
|
8
|
+
enabled: true,
|
|
9
|
+
/**
|
|
10
|
+
* Elevated 5xx error rate indicates origin or CloudFront issues.
|
|
11
|
+
* Threshold set above 0 to avoid excessive sensitivity from transient errors.
|
|
12
|
+
*/
|
|
13
|
+
errorRate: {
|
|
14
|
+
threshold: 5,
|
|
15
|
+
evaluationPeriods: 5,
|
|
16
|
+
datapointsToAlarm: 5,
|
|
17
|
+
treatMissingData: TreatMissingData.NOT_BREACHING,
|
|
18
|
+
},
|
|
19
|
+
/**
|
|
20
|
+
* Origin taking too long to respond can lead to 504 errors.
|
|
21
|
+
* Default 5000ms threshold provides a reasonable starting point;
|
|
22
|
+
* ideally set to ~80% of your origin response timeout.
|
|
23
|
+
*/
|
|
24
|
+
originLatency: {
|
|
25
|
+
threshold: 5000,
|
|
26
|
+
evaluationPeriods: 5,
|
|
27
|
+
datapointsToAlarm: 5,
|
|
28
|
+
treatMissingData: TreatMissingData.NOT_BREACHING,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
//# 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,2BAA2B,GAA8B;IACpE,OAAO,EAAE,IAAI;IAEb;;;OAGG;IACH,SAAS,EAAE;QACT,SAAS,EAAE,CAAC;QACZ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;IAED;;;;OAIG;IACH,aAAa,EAAE;QACb,SAAS,EAAE,IAAI;QACf,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,CAAC;QACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;KACjD;CACF,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
|
|
2
|
+
import type { Distribution } from "aws-cdk-lib/aws-cloudfront";
|
|
3
|
+
import type { IConstruct } from "constructs";
|
|
4
|
+
import type { AlarmDefinition } from "@composurecdk/cloudwatch";
|
|
5
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
6
|
+
import type { DistributionAlarmConfig } from "./alarm-config.js";
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the recommended alarm configuration into fully-resolved
|
|
9
|
+
* {@link AlarmDefinition}s for a CloudFront distribution.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveDistributionAlarmDefinitions(distribution: Distribution, config: DistributionAlarmConfig | undefined): AlarmDefinition[];
|
|
12
|
+
/**
|
|
13
|
+
* Creates AWS-recommended CloudWatch alarms for a CloudFront distribution,
|
|
14
|
+
* merging recommended definitions with any custom alarm builders.
|
|
15
|
+
*
|
|
16
|
+
* @param scope - CDK construct scope for creating alarm constructs.
|
|
17
|
+
* @param id - Base identifier for alarm construct ids.
|
|
18
|
+
* @param distribution - The CloudFront distribution to create alarms for.
|
|
19
|
+
* @param config - User-provided alarm configuration, or `false` to disable all.
|
|
20
|
+
* @param customAlarms - Custom alarm builders added via `addAlarm()`.
|
|
21
|
+
* @returns A record mapping alarm keys to their created Alarm constructs.
|
|
22
|
+
*
|
|
23
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
24
|
+
*/
|
|
25
|
+
export declare function createDistributionAlarms(scope: IConstruct, id: string, distribution: Distribution, config: DistributionAlarmConfig | false | undefined, customAlarms?: AlarmDefinitionBuilder<Distribution>[]): Record<string, Alarm>;
|
|
26
|
+
//# sourceMappingURL=distribution-alarms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distribution-alarms.d.ts","sourceRoot":"","sources":["../src/distribution-alarms.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,KAAK,EAAqC,MAAM,4BAA4B,CAAC;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAoC,MAAM,0BAA0B,CAAC;AACpG,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AA2BjE;;;GAGG;AACH,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,uBAAuB,GAAG,SAAS,GAC1C,eAAe,EAAE,CAqCnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,uBAAuB,GAAG,KAAK,GAAG,SAAS,EACnD,YAAY,GAAE,sBAAsB,CAAC,YAAY,CAAC,EAAO,GACxD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAUvB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
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 { DISTRIBUTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
5
|
+
const METRIC_PERIOD = Duration.minutes(1);
|
|
6
|
+
const METRIC_PERIOD_LABEL = `${String(METRIC_PERIOD.toMinutes())} minute`;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a CloudFront distribution metric with the correct namespace and
|
|
9
|
+
* dimensions (DistributionId + Region=Global).
|
|
10
|
+
*/
|
|
11
|
+
function distributionMetric(distribution, metricName, statistic) {
|
|
12
|
+
return new Metric({
|
|
13
|
+
namespace: "AWS/CloudFront",
|
|
14
|
+
metricName,
|
|
15
|
+
dimensionsMap: {
|
|
16
|
+
DistributionId: distribution.distributionId,
|
|
17
|
+
Region: "Global",
|
|
18
|
+
},
|
|
19
|
+
statistic,
|
|
20
|
+
period: METRIC_PERIOD,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolves the recommended alarm configuration into fully-resolved
|
|
25
|
+
* {@link AlarmDefinition}s for a CloudFront distribution.
|
|
26
|
+
*/
|
|
27
|
+
export function resolveDistributionAlarmDefinitions(distribution, config) {
|
|
28
|
+
if (config?.enabled === false)
|
|
29
|
+
return [];
|
|
30
|
+
const definitions = [];
|
|
31
|
+
if (config?.errorRate !== false) {
|
|
32
|
+
const cfg = resolveAlarmConfig(config?.errorRate, DISTRIBUTION_ALARM_DEFAULTS.errorRate);
|
|
33
|
+
definitions.push({
|
|
34
|
+
key: "errorRate",
|
|
35
|
+
metric: distributionMetric(distribution, "5xxErrorRate", Stats.AVERAGE),
|
|
36
|
+
threshold: cfg.threshold,
|
|
37
|
+
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
38
|
+
evaluationPeriods: cfg.evaluationPeriods,
|
|
39
|
+
datapointsToAlarm: cfg.datapointsToAlarm,
|
|
40
|
+
treatMissingData: cfg.treatMissingData,
|
|
41
|
+
description: `CloudFront distribution 5xx error rate is elevated. Threshold: > ${String(cfg.threshold)}% in ${METRIC_PERIOD_LABEL}.`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (config?.originLatency !== false) {
|
|
45
|
+
const cfg = resolveAlarmConfig(config?.originLatency, DISTRIBUTION_ALARM_DEFAULTS.originLatency);
|
|
46
|
+
definitions.push({
|
|
47
|
+
key: "originLatency",
|
|
48
|
+
metric: distributionMetric(distribution, "OriginLatency", Stats.percentile(90)),
|
|
49
|
+
threshold: cfg.threshold,
|
|
50
|
+
comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
51
|
+
evaluationPeriods: cfg.evaluationPeriods,
|
|
52
|
+
datapointsToAlarm: cfg.datapointsToAlarm,
|
|
53
|
+
treatMissingData: cfg.treatMissingData,
|
|
54
|
+
description: `CloudFront origin latency is elevated. Threshold: > ${String(cfg.threshold)}ms p90 in ${METRIC_PERIOD_LABEL}.`,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return definitions;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Creates AWS-recommended CloudWatch alarms for a CloudFront distribution,
|
|
61
|
+
* merging recommended definitions with any custom alarm builders.
|
|
62
|
+
*
|
|
63
|
+
* @param scope - CDK construct scope for creating alarm constructs.
|
|
64
|
+
* @param id - Base identifier for alarm construct ids.
|
|
65
|
+
* @param distribution - The CloudFront distribution to create alarms for.
|
|
66
|
+
* @param config - User-provided alarm configuration, or `false` to disable all.
|
|
67
|
+
* @param customAlarms - Custom alarm builders added via `addAlarm()`.
|
|
68
|
+
* @returns A record mapping alarm keys to their created Alarm constructs.
|
|
69
|
+
*
|
|
70
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
71
|
+
*/
|
|
72
|
+
export function createDistributionAlarms(scope, id, distribution, config, customAlarms = []) {
|
|
73
|
+
if (config === false)
|
|
74
|
+
return {};
|
|
75
|
+
const enabled = config?.enabled ?? DISTRIBUTION_ALARM_DEFAULTS.enabled;
|
|
76
|
+
if (!enabled)
|
|
77
|
+
return {};
|
|
78
|
+
const recommended = resolveDistributionAlarmDefinitions(distribution, config);
|
|
79
|
+
const custom = customAlarms.map((b) => b.resolve(distribution));
|
|
80
|
+
return createAlarms(scope, id, [...recommended, ...custom]);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=distribution-alarms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"distribution-alarms.js","sourceRoot":"","sources":["../src/distribution-alarms.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Distribution, type DistributionProps, type IOrigin, type AddBehaviorOptions } from "aws-cdk-lib/aws-cloudfront";
|
|
2
|
+
import { type ICertificate } from "aws-cdk-lib/aws-certificatemanager";
|
|
3
|
+
import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
|
|
2
4
|
import { type Bucket } from "aws-cdk-lib/aws-s3";
|
|
3
5
|
import { type IConstruct } from "constructs";
|
|
4
6
|
import { type IBuilder, type Lifecycle, type Resolvable } from "@composurecdk/core";
|
|
7
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
8
|
+
import type { DistributionAlarmConfig } from "./alarm-config.js";
|
|
5
9
|
/**
|
|
6
10
|
* Configuration properties for the CloudFront distribution builder.
|
|
7
11
|
*
|
|
@@ -14,7 +18,7 @@ import { type IBuilder, type Lifecycle, type Resolvable } from "@composurecdk/co
|
|
|
14
18
|
* The `enableLogging` CDK prop is replaced by {@link accessLogging}, which
|
|
15
19
|
* auto-creates a logging bucket with secure defaults when enabled.
|
|
16
20
|
*/
|
|
17
|
-
export interface DistributionBuilderProps extends Omit<DistributionProps, "defaultBehavior" | "enableLogging"> {
|
|
21
|
+
export interface DistributionBuilderProps extends Omit<DistributionProps, "defaultBehavior" | "enableLogging" | "certificate"> {
|
|
18
22
|
/**
|
|
19
23
|
* Whether to automatically create an S3 bucket for CloudFront standard
|
|
20
24
|
* access logging.
|
|
@@ -31,6 +35,14 @@ export interface DistributionBuilderProps extends Omit<DistributionProps, "defau
|
|
|
31
35
|
* bucket takes precedence.
|
|
32
36
|
*/
|
|
33
37
|
accessLogging?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The ACM certificate to associate with the distribution for HTTPS.
|
|
40
|
+
*
|
|
41
|
+
* Accepts a concrete {@link ICertificate} or a {@link Resolvable} —
|
|
42
|
+
* typically a {@link Ref} produced by a composed `@composurecdk/acm`
|
|
43
|
+
* certificate builder. The certificate must be issued in `us-east-1`.
|
|
44
|
+
*/
|
|
45
|
+
certificate?: Resolvable<ICertificate>;
|
|
34
46
|
/**
|
|
35
47
|
* Options for the default cache behavior, excluding `origin`.
|
|
36
48
|
*
|
|
@@ -40,6 +52,24 @@ export interface DistributionBuilderProps extends Omit<DistributionProps, "defau
|
|
|
40
52
|
* configured here.
|
|
41
53
|
*/
|
|
42
54
|
defaultBehavior?: AddBehaviorOptions;
|
|
55
|
+
/**
|
|
56
|
+
* Configuration for AWS-recommended CloudWatch alarms.
|
|
57
|
+
*
|
|
58
|
+
* By default, the builder creates recommended alarms for 5xx error rate
|
|
59
|
+
* and origin latency. Individual alarms can be customized or disabled.
|
|
60
|
+
* Set to `false` to disable all alarms.
|
|
61
|
+
*
|
|
62
|
+
* No alarm actions are configured by default since notification
|
|
63
|
+
* methods are user-specific. Access alarms from the build result
|
|
64
|
+
* or use an `afterBuild` hook to apply actions.
|
|
65
|
+
*
|
|
66
|
+
* Function-level alarms (FunctionValidationErrors, FunctionExecutionErrors,
|
|
67
|
+
* FunctionThrottles) require per-function dimensions. Use
|
|
68
|
+
* {@link IDistributionBuilder.addAlarm} to add them.
|
|
69
|
+
*
|
|
70
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
71
|
+
*/
|
|
72
|
+
recommendedAlarms?: DistributionAlarmConfig | false;
|
|
43
73
|
}
|
|
44
74
|
/**
|
|
45
75
|
* The build output of a {@link IDistributionBuilder}. Contains the CDK constructs
|
|
@@ -53,6 +83,19 @@ export interface DistributionBuilderResult {
|
|
|
53
83
|
* logging was disabled or the user provided their own bucket.
|
|
54
84
|
*/
|
|
55
85
|
accessLogsBucket?: Bucket;
|
|
86
|
+
/**
|
|
87
|
+
* CloudWatch alarms created for the distribution, keyed by alarm name.
|
|
88
|
+
*
|
|
89
|
+
* Includes both AWS-recommended alarms and any custom alarms added
|
|
90
|
+
* via {@link IDistributionBuilder.addAlarm}. Access individual alarms
|
|
91
|
+
* by key (e.g., `result.alarms.errorRate`).
|
|
92
|
+
*
|
|
93
|
+
* No alarm actions are configured — apply them via the result or an
|
|
94
|
+
* `afterBuild` hook.
|
|
95
|
+
*
|
|
96
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CloudFront
|
|
97
|
+
*/
|
|
98
|
+
alarms: Record<string, Alarm>;
|
|
56
99
|
}
|
|
57
100
|
/**
|
|
58
101
|
* A fluent builder for configuring and creating a CloudFront distribution.
|
|
@@ -83,6 +126,8 @@ export type IDistributionBuilder = IBuilder<DistributionBuilderProps, Distributi
|
|
|
83
126
|
declare class DistributionBuilder implements Lifecycle<DistributionBuilderResult> {
|
|
84
127
|
props: Partial<DistributionBuilderProps>;
|
|
85
128
|
private _origin?;
|
|
129
|
+
private readonly customAlarms;
|
|
130
|
+
addAlarm(key: string, configure: (alarm: AlarmDefinitionBuilder<Distribution>) => AlarmDefinitionBuilder<Distribution>): this;
|
|
86
131
|
/**
|
|
87
132
|
* Sets the default origin for the distribution.
|
|
88
133
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distribution-builder.d.ts","sourceRoot":"","sources":["../src/distribution-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"distribution-builder.d.ts","sourceRoot":"","sources":["../src/distribution-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,KAAK,MAAM,EAAmB,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,SAAS,EAEd,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAIjE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,iBAAiB,EACjB,iBAAiB,GAAG,eAAe,GAAG,aAAa,CACpD;IACC;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAEvC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,kBAAkB,CAAC;IAErC;;;;;;;;;;;;;;;;OAgBG;IACH,iBAAiB,CAAC,EAAE,uBAAuB,GAAG,KAAK,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,oEAAoE;IACpE,YAAY,EAAE,YAAY,CAAC;IAE3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC,wBAAwB,EAAE,mBAAmB,CAAC,CAAC;AAE3F,cAAM,mBAAoB,YAAW,SAAS,CAAC,yBAAyB,CAAC;IACvE,KAAK,EAAE,OAAO,CAAC,wBAAwB,CAAC,CAAM;IAC9C,OAAO,CAAC,OAAO,CAAC,CAAsB;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA8C;IAE3E,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CACT,KAAK,EAAE,sBAAsB,CAAC,YAAY,CAAC,KACxC,sBAAsB,CAAC,YAAY,CAAC,GACxC,IAAI;IAKP;;;;;;;;OAQG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI;IAKzC,KAAK,CACH,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,yBAAyB;CA4E7B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,yBAAyB,IAAI,oBAAoB,CAEhE"}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { Distribution, } from "aws-cdk-lib/aws-cloudfront";
|
|
2
|
+
import { ObjectOwnership } from "aws-cdk-lib/aws-s3";
|
|
2
3
|
import { RemovalPolicy } from "aws-cdk-lib";
|
|
3
4
|
import { Builder, resolve, } from "@composurecdk/core";
|
|
5
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
4
6
|
import { createBucketBuilder } from "@composurecdk/s3";
|
|
7
|
+
import { createDistributionAlarms } from "./distribution-alarms.js";
|
|
5
8
|
import { DISTRIBUTION_DEFAULTS } from "./defaults.js";
|
|
6
9
|
class DistributionBuilder {
|
|
7
10
|
props = {};
|
|
8
11
|
_origin;
|
|
12
|
+
customAlarms = [];
|
|
13
|
+
addAlarm(key, configure) {
|
|
14
|
+
this.customAlarms.push(configure(new AlarmDefinitionBuilder(key)));
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
9
17
|
/**
|
|
10
18
|
* Sets the default origin for the distribution.
|
|
11
19
|
*
|
|
@@ -25,7 +33,8 @@ class DistributionBuilder {
|
|
|
25
33
|
throw new Error(`DistributionBuilder "${id}" requires an origin. ` +
|
|
26
34
|
`Call .origin() with an IOrigin or a Ref to one.`);
|
|
27
35
|
}
|
|
28
|
-
const { accessLogging, defaultBehavior: userBehavior, ...distProps } = this.props;
|
|
36
|
+
const { accessLogging, certificate, defaultBehavior: userBehavior, recommendedAlarms: alarmConfig, ...distProps } = this.props;
|
|
37
|
+
const resolvedCertificate = certificate ? resolve(certificate, context ?? {}) : undefined;
|
|
29
38
|
const { accessLogging: defaultAccessLogging, defaultBehavior: defaultBehavior, ...cdkDefaults } = DISTRIBUTION_DEFAULTS;
|
|
30
39
|
const autoAccessLog = (accessLogging ?? defaultAccessLogging) && !distProps.logBucket;
|
|
31
40
|
let accessLogsBucket;
|
|
@@ -33,6 +42,9 @@ class DistributionBuilder {
|
|
|
33
42
|
if (autoAccessLog) {
|
|
34
43
|
accessLogsBucket = createBucketBuilder()
|
|
35
44
|
.accessLogging(false)
|
|
45
|
+
.versioned(false)
|
|
46
|
+
// CloudFront standard logging writes via ACLs, which requires BucketOwnerPreferred.
|
|
47
|
+
.objectOwnership(ObjectOwnership.BUCKET_OWNER_PREFERRED)
|
|
36
48
|
.removalPolicy(RemovalPolicy.RETAIN)
|
|
37
49
|
.build(scope, `${id}AccessLogs`).bucket;
|
|
38
50
|
accessLogProps = {
|
|
@@ -44,15 +56,24 @@ class DistributionBuilder {
|
|
|
44
56
|
...cdkDefaults,
|
|
45
57
|
...accessLogProps,
|
|
46
58
|
...distProps,
|
|
59
|
+
...(resolvedCertificate ? { certificate: resolvedCertificate } : {}),
|
|
47
60
|
defaultBehavior: {
|
|
48
61
|
...defaultBehavior,
|
|
49
62
|
...userBehavior,
|
|
50
63
|
origin: resolvedOrigin,
|
|
51
64
|
},
|
|
52
65
|
};
|
|
66
|
+
const distribution = new Distribution(scope, id, mergedProps);
|
|
67
|
+
// Ensure CloudFront is deleted before the access logs bucket during stack teardown.
|
|
68
|
+
// Without this, CloudFront may still be writing logs while the bucket is being emptied/deleted.
|
|
69
|
+
if (accessLogsBucket) {
|
|
70
|
+
distribution.node.addDependency(accessLogsBucket);
|
|
71
|
+
}
|
|
72
|
+
const alarms = createDistributionAlarms(scope, id, distribution, alarmConfig, this.customAlarms);
|
|
53
73
|
return {
|
|
54
|
-
distribution
|
|
74
|
+
distribution,
|
|
55
75
|
accessLogsBucket,
|
|
76
|
+
alarms,
|
|
56
77
|
};
|
|
57
78
|
}
|
|
58
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distribution-builder.js","sourceRoot":"","sources":["../src/distribution-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAIb,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"distribution-builder.js","sourceRoot":"","sources":["../src/distribution-builder.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { createDistributionBuilder, type DistributionBuilderResult, type IDistributionBuilder, } from "./distribution-builder.js";
|
|
2
2
|
export { DISTRIBUTION_DEFAULTS } from "./defaults.js";
|
|
3
|
+
export { type DistributionAlarmConfig } from "./alarm-config.js";
|
|
4
|
+
export { DISTRIBUTION_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
3
5
|
//# 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,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,GAG1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,GAG1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@composurecdk/cloudfront",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Composable CloudFront distribution 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/s3": "^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
|
}
|