@composurecdk/acm 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 +144 -0
- package/dist/alarm-config.d.ts +34 -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 +13 -0
- package/dist/alarm-defaults.d.ts.map +1 -0
- package/dist/alarm-defaults.js +26 -0
- package/dist/alarm-defaults.js.map +1 -0
- package/dist/certificate-alarms.d.ts +26 -0
- package/dist/certificate-alarms.d.ts.map +1 -0
- package/dist/certificate-alarms.js +52 -0
- package/dist/certificate-alarms.js.map +1 -0
- package/dist/certificate-builder.d.ts +136 -0
- package/dist/certificate-builder.d.ts.map +1 -0
- package/dist/certificate-builder.js +77 -0
- package/dist/certificate-builder.js.map +1 -0
- package/dist/defaults.d.ts +8 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +24 -0
- package/dist/defaults.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# @composurecdk/acm
|
|
2
|
+
|
|
3
|
+
AWS Certificate Manager builder for [ComposureCDK](../../README.md).
|
|
4
|
+
|
|
5
|
+
This package provides a fluent builder for ACM certificates with secure, AWS-recommended defaults, first-class DNS validation wiring, and a recommended `DaysToExpiry` alarm. It wraps the CDK [Certificate](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_certificatemanager.Certificate.html) construct — refer to the CDK documentation for the full set of configurable properties.
|
|
6
|
+
|
|
7
|
+
## Certificate Builder
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { createCertificateBuilder } from "@composurecdk/acm";
|
|
11
|
+
import { HostedZone } from "aws-cdk-lib/aws-route53";
|
|
12
|
+
|
|
13
|
+
const zone = HostedZone.fromLookup(stack, "Zone", { domainName: "example.com" });
|
|
14
|
+
|
|
15
|
+
const { certificate } = createCertificateBuilder()
|
|
16
|
+
.domainName("example.com")
|
|
17
|
+
.subjectAlternativeNames(["www.example.com"])
|
|
18
|
+
.validationZone(zone)
|
|
19
|
+
.build(stack, "SiteCert");
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Every [CertificateProps](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_certificatemanager.CertificateProps.html) property is available as a fluent setter on the builder.
|
|
23
|
+
|
|
24
|
+
## Secure Defaults
|
|
25
|
+
|
|
26
|
+
`createCertificateBuilder` applies the following defaults. Each can be overridden via the builder's fluent API.
|
|
27
|
+
|
|
28
|
+
| Property | Default | Rationale |
|
|
29
|
+
| ---------------------------- | ----------------------- | ----------------------------------------------------------------------------- |
|
|
30
|
+
| `keyAlgorithm` | `KeyAlgorithm.RSA_2048` | Broadest client and AWS service compatibility (CloudFront, API Gateway, ALB). |
|
|
31
|
+
| `transparencyLoggingEnabled` | `true` | Required by modern browsers; enables public detection of mis-issuance. |
|
|
32
|
+
|
|
33
|
+
These defaults are guided by the [AWS ACM Best Practices](https://docs.aws.amazon.com/acm/latest/userguide/acm-bestpractices.html).
|
|
34
|
+
|
|
35
|
+
The defaults are exported as `CERTIFICATE_DEFAULTS` for visibility and testing:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { CERTIFICATE_DEFAULTS } from "@composurecdk/acm";
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## DNS Validation
|
|
42
|
+
|
|
43
|
+
Email-based validation is not used by default — it blocks stack creation until a human clicks a link in an email. The builder requires one of:
|
|
44
|
+
|
|
45
|
+
- `validationZone(zone)` — the hosted zone that owns every domain on the certificate.
|
|
46
|
+
- `validationZones({ "apex.com": apexZone, "alt.net": altZone })` — when domains span multiple zones.
|
|
47
|
+
- `validation(CertificateValidation.fromEmail())` — explicit opt-in to email validation (not recommended).
|
|
48
|
+
|
|
49
|
+
`validationZone` / `validationZones` accept a `Resolvable<IHostedZone>`, so a hosted zone produced by a sibling component can be wired via `ref()`.
|
|
50
|
+
|
|
51
|
+
## Certificate Lifetime
|
|
52
|
+
|
|
53
|
+
ACM-issued public certificates are valid for [395 days](https://docs.aws.amazon.com/acm/latest/userguide/acm-certificate.html) and auto-renew starting ~60 days before expiry, provided the DNS validation records remain published. Renewal is therefore the happy path — the `daysToExpiry` alarm below is a safety net for the cases where it can't complete (records removed, zone delegation broken, etc.). For imported certificates, which do not auto-renew, `daysToExpiry` is the primary expiry control.
|
|
54
|
+
|
|
55
|
+
## Recommended Alarms
|
|
56
|
+
|
|
57
|
+
The builder creates [AWS-recommended CloudWatch alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CertificateManager) by default. No alarm actions are configured — access alarms from the build result to add SNS topics or other actions.
|
|
58
|
+
|
|
59
|
+
| Alarm | Metric | Default threshold |
|
|
60
|
+
| -------------- | ----------------------------- | ----------------- |
|
|
61
|
+
| `daysToExpiry` | DaysToExpiry (Minimum, 1 day) | ≤ 45 days |
|
|
62
|
+
|
|
63
|
+
`treatMissingData` defaults to `notBreaching`: once a certificate has effectively expired, ACM stops emitting `DaysToExpiry`, and there is nothing left to alarm about.
|
|
64
|
+
|
|
65
|
+
The defaults are exported as `CERTIFICATE_ALARM_DEFAULTS` for visibility and testing:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { CERTIFICATE_ALARM_DEFAULTS } from "@composurecdk/acm";
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Customizing thresholds
|
|
72
|
+
|
|
73
|
+
Override individual alarm properties via `recommendedAlarms`. Unspecified fields keep their defaults.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
const cert = createCertificateBuilder()
|
|
77
|
+
.domainName("example.com")
|
|
78
|
+
.validationZone(zone)
|
|
79
|
+
.recommendedAlarms({
|
|
80
|
+
daysToExpiry: { threshold: 30 },
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Disabling alarms
|
|
85
|
+
|
|
86
|
+
Disable all recommended alarms:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
builder.recommendedAlarms(false);
|
|
90
|
+
// or
|
|
91
|
+
builder.recommendedAlarms({ enabled: false });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Disable the daysToExpiry alarm individually:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
builder.recommendedAlarms({ daysToExpiry: false });
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Custom alarms
|
|
101
|
+
|
|
102
|
+
Add custom alarms alongside the recommended ones via `addAlarm`. The callback receives an `AlarmDefinitionBuilder` typed to `ICertificate`, so the metric factory has access to the certificate at build time.
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { Metric } from "aws-cdk-lib/aws-cloudwatch";
|
|
106
|
+
import { Duration } from "aws-cdk-lib";
|
|
107
|
+
|
|
108
|
+
const cert = createCertificateBuilder()
|
|
109
|
+
.domainName("example.com")
|
|
110
|
+
.validationZone(zone)
|
|
111
|
+
.addAlarm("urgentExpiry", (alarm) =>
|
|
112
|
+
alarm
|
|
113
|
+
.metric(
|
|
114
|
+
(c) =>
|
|
115
|
+
new Metric({
|
|
116
|
+
namespace: "AWS/CertificateManager",
|
|
117
|
+
metricName: "DaysToExpiry",
|
|
118
|
+
dimensionsMap: { CertificateArn: c.certificateArn },
|
|
119
|
+
statistic: "Minimum",
|
|
120
|
+
period: Duration.days(1),
|
|
121
|
+
}),
|
|
122
|
+
)
|
|
123
|
+
.threshold(10)
|
|
124
|
+
.lessThanOrEqual()
|
|
125
|
+
.description("Certificate very close to expiry — page oncall"),
|
|
126
|
+
);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Applying alarm actions
|
|
130
|
+
|
|
131
|
+
Alarms are returned in the build result as `Record<string, Alarm>`:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
const result = cert.build(stack, "SiteCert");
|
|
135
|
+
|
|
136
|
+
const alertTopic = new Topic(stack, "AlertTopic");
|
|
137
|
+
for (const alarm of Object.values(result.alarms)) {
|
|
138
|
+
alarm.addAlarmAction(new SnsAction(alertTopic));
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## CloudFront certificates
|
|
143
|
+
|
|
144
|
+
CloudFront viewer certificates must live in `us-east-1`. The ACM builder cannot enforce this on its own — certificates in other regions are perfectly valid for ALB, API Gateway, and other services. The constraint is enforced by CloudFront at association time, so if your certificate is for CloudFront, place the builder in a stack that targets `us-east-1` (e.g. via [`createStackBuilder`](../cloudformation/README.md) with an `env`).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AlarmConfig } from "@composurecdk/cloudwatch";
|
|
2
|
+
/**
|
|
3
|
+
* Controls which recommended alarms are created for an ACM certificate.
|
|
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
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CertificateManager
|
|
9
|
+
*/
|
|
10
|
+
export interface CertificateAlarmConfig {
|
|
11
|
+
/**
|
|
12
|
+
* Master switch: set to `false` to disable all recommended alarms.
|
|
13
|
+
* Individual alarms can also be disabled via their own entry.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Alarm when the certificate is approaching expiry.
|
|
19
|
+
*
|
|
20
|
+
* ACM public certificates auto-renew, so this alarm is primarily a
|
|
21
|
+
* safety net for the edge cases where renewal cannot complete (for
|
|
22
|
+
* example, when DNS validation records have been removed from the
|
|
23
|
+
* zone). For imported certificates, which do not auto-renew, this
|
|
24
|
+
* alarm is the primary expiry control.
|
|
25
|
+
*
|
|
26
|
+
* Metric: `AWS/CertificateManager DaysToExpiry`, statistic Minimum,
|
|
27
|
+
* period 1 day, dimension `CertificateArn`.
|
|
28
|
+
* Default threshold: ≤ 45 days.
|
|
29
|
+
*
|
|
30
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CertificateManager
|
|
31
|
+
*/
|
|
32
|
+
daysToExpiry?: AlarmConfig | false;
|
|
33
|
+
}
|
|
34
|
+
//# 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;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;;;;;;;;OAcG;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,13 @@
|
|
|
1
|
+
import type { AlarmConfig } from "@composurecdk/cloudwatch";
|
|
2
|
+
interface CertificateAlarmDefaults {
|
|
3
|
+
enabled: true;
|
|
4
|
+
daysToExpiry: Required<AlarmConfig>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* AWS-recommended default alarm configuration for ACM certificates.
|
|
8
|
+
*
|
|
9
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CertificateManager
|
|
10
|
+
*/
|
|
11
|
+
export declare const CERTIFICATE_ALARM_DEFAULTS: CertificateAlarmDefaults;
|
|
12
|
+
export {};
|
|
13
|
+
//# 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,wBAAwB;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,YAAY,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CACrC;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,wBAmBxC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
|
|
2
|
+
/**
|
|
3
|
+
* AWS-recommended default alarm configuration for ACM certificates.
|
|
4
|
+
*
|
|
5
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CertificateManager
|
|
6
|
+
*/
|
|
7
|
+
export const CERTIFICATE_ALARM_DEFAULTS = {
|
|
8
|
+
enabled: true,
|
|
9
|
+
/**
|
|
10
|
+
* Alarm 45 days before expiry — AWS's recommended threshold. For public
|
|
11
|
+
* certificates, ACM begins auto-renewal attempts around 60 days out, so
|
|
12
|
+
* 45 days leaves a two-week window to investigate renewal failures
|
|
13
|
+
* before the certificate expires.
|
|
14
|
+
*
|
|
15
|
+
* `treatMissingData: notBreaching` avoids false alarms after a
|
|
16
|
+
* certificate has effectively expired — at that point ACM stops
|
|
17
|
+
* emitting DaysToExpiry, and there is nothing left to alarm about.
|
|
18
|
+
*/
|
|
19
|
+
daysToExpiry: {
|
|
20
|
+
threshold: 45,
|
|
21
|
+
evaluationPeriods: 1,
|
|
22
|
+
datapointsToAlarm: 1,
|
|
23
|
+
treatMissingData: TreatMissingData.NOT_BREACHING,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
//# 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;AAQ9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAA6B;IAClE,OAAO,EAAE,IAAI;IAEb;;;;;;;;;OASG;IACH,YAAY,EAAE;QACZ,SAAS,EAAE,EAAE;QACb,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 { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
|
|
3
|
+
import type { IConstruct } from "constructs";
|
|
4
|
+
import type { AlarmDefinition } from "@composurecdk/cloudwatch";
|
|
5
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
6
|
+
import type { CertificateAlarmConfig } from "./alarm-config.js";
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the recommended alarm configuration into fully-resolved
|
|
9
|
+
* {@link AlarmDefinition}s for an ACM certificate.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveCertificateAlarmDefinitions(certificate: ICertificate, config: CertificateAlarmConfig | undefined): AlarmDefinition[];
|
|
12
|
+
/**
|
|
13
|
+
* Creates AWS-recommended CloudWatch alarms for an ACM certificate,
|
|
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 certificate - The ACM certificate 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#CertificateManager
|
|
24
|
+
*/
|
|
25
|
+
export declare function createCertificateAlarms(scope: IConstruct, id: string, certificate: ICertificate, config: CertificateAlarmConfig | false | undefined, customAlarms?: AlarmDefinitionBuilder<ICertificate>[]): Record<string, Alarm>;
|
|
26
|
+
//# sourceMappingURL=certificate-alarms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"certificate-alarms.d.ts","sourceRoot":"","sources":["../src/certificate-alarms.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,KAAK,EAAsB,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACvE,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,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAKhE;;;GAGG;AACH,wBAAgB,kCAAkC,CAChD,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,sBAAsB,GAAG,SAAS,GACzC,eAAe,EAAE,CAoBnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,sBAAsB,GAAG,KAAK,GAAG,SAAS,EAClD,YAAY,GAAE,sBAAsB,CAAC,YAAY,CAAC,EAAO,GACxD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAUvB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Duration } from "aws-cdk-lib";
|
|
2
|
+
import { ComparisonOperator } from "aws-cdk-lib/aws-cloudwatch";
|
|
3
|
+
import { createAlarms, resolveAlarmConfig } from "@composurecdk/cloudwatch";
|
|
4
|
+
import { CERTIFICATE_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
5
|
+
const METRIC_PERIOD = Duration.days(1);
|
|
6
|
+
/**
|
|
7
|
+
* Resolves the recommended alarm configuration into fully-resolved
|
|
8
|
+
* {@link AlarmDefinition}s for an ACM certificate.
|
|
9
|
+
*/
|
|
10
|
+
export function resolveCertificateAlarmDefinitions(certificate, config) {
|
|
11
|
+
if (config?.enabled === false)
|
|
12
|
+
return [];
|
|
13
|
+
const definitions = [];
|
|
14
|
+
if (config?.daysToExpiry !== false) {
|
|
15
|
+
const cfg = resolveAlarmConfig(config?.daysToExpiry, CERTIFICATE_ALARM_DEFAULTS.daysToExpiry);
|
|
16
|
+
definitions.push({
|
|
17
|
+
key: "daysToExpiry",
|
|
18
|
+
metric: certificate.metricDaysToExpiry({ period: METRIC_PERIOD }),
|
|
19
|
+
threshold: cfg.threshold,
|
|
20
|
+
comparisonOperator: ComparisonOperator.LESS_THAN_OR_EQUAL_TO_THRESHOLD,
|
|
21
|
+
evaluationPeriods: cfg.evaluationPeriods,
|
|
22
|
+
datapointsToAlarm: cfg.datapointsToAlarm,
|
|
23
|
+
treatMissingData: cfg.treatMissingData,
|
|
24
|
+
description: `ACM certificate is approaching expiry. Threshold: <= ${String(cfg.threshold)} days remaining.`,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return definitions;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates AWS-recommended CloudWatch alarms for an ACM certificate,
|
|
31
|
+
* merging recommended definitions with any custom alarm builders.
|
|
32
|
+
*
|
|
33
|
+
* @param scope - CDK construct scope for creating alarm constructs.
|
|
34
|
+
* @param id - Base identifier for alarm construct ids.
|
|
35
|
+
* @param certificate - The ACM certificate to create alarms for.
|
|
36
|
+
* @param config - User-provided alarm configuration, or `false` to disable all.
|
|
37
|
+
* @param customAlarms - Custom alarm builders added via `addAlarm()`.
|
|
38
|
+
* @returns A record mapping alarm keys to their created Alarm constructs.
|
|
39
|
+
*
|
|
40
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CertificateManager
|
|
41
|
+
*/
|
|
42
|
+
export function createCertificateAlarms(scope, id, certificate, config, customAlarms = []) {
|
|
43
|
+
if (config === false)
|
|
44
|
+
return {};
|
|
45
|
+
const enabled = config?.enabled ?? CERTIFICATE_ALARM_DEFAULTS.enabled;
|
|
46
|
+
if (!enabled)
|
|
47
|
+
return {};
|
|
48
|
+
const recommended = resolveCertificateAlarmDefinitions(certificate, config);
|
|
49
|
+
const custom = customAlarms.map((b) => b.resolve(certificate));
|
|
50
|
+
return createAlarms(scope, id, [...recommended, ...custom]);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=certificate-alarms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"certificate-alarms.js","sourceRoot":"","sources":["../src/certificate-alarms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAc,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAI5E,OAAO,EAA0B,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEpG,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEvC;;;GAGG;AACH,MAAM,UAAU,kCAAkC,CAChD,WAAyB,EACzB,MAA0C;IAE1C,IAAI,MAAM,EAAE,OAAO,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IAEzC,MAAM,WAAW,GAAsB,EAAE,CAAC;IAE1C,IAAI,MAAM,EAAE,YAAY,KAAK,KAAK,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,0BAA0B,CAAC,YAAY,CAAC,CAAC;QAC9F,WAAW,CAAC,IAAI,CAAC;YACf,GAAG,EAAE,cAAc;YACnB,MAAM,EAAE,WAAW,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;YACjE,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,kBAAkB,EAAE,kBAAkB,CAAC,+BAA+B;YACtE,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;YACxC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;YACxC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,WAAW,EAAE,wDAAwD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB;SAC7G,CAAC,CAAC;IACL,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAiB,EACjB,EAAU,EACV,WAAyB,EACzB,MAAkD,EAClD,eAAuD,EAAE;IAEzD,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IAEhC,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,0BAA0B,CAAC,OAAO,CAAC;IACtE,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAExB,MAAM,WAAW,GAAG,kCAAkC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IAE/D,OAAO,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,GAAG,WAAW,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Certificate, type CertificateProps, type ICertificate } from "aws-cdk-lib/aws-certificatemanager";
|
|
2
|
+
import { type Alarm } from "aws-cdk-lib/aws-cloudwatch";
|
|
3
|
+
import type { IHostedZone } from "aws-cdk-lib/aws-route53";
|
|
4
|
+
import { type IConstruct } from "constructs";
|
|
5
|
+
import { type IBuilder, type Lifecycle, type Resolvable } from "@composurecdk/core";
|
|
6
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
7
|
+
import type { CertificateAlarmConfig } from "./alarm-config.js";
|
|
8
|
+
/**
|
|
9
|
+
* Configuration properties for the ACM certificate builder.
|
|
10
|
+
*
|
|
11
|
+
* Extends the CDK {@link CertificateProps} with additional builder-specific
|
|
12
|
+
* options. The `validation` field is augmented by {@link validationZone} /
|
|
13
|
+
* {@link validationZones}, which accept {@link Resolvable} hosted zones so
|
|
14
|
+
* the validation zone can come from a composed component.
|
|
15
|
+
*
|
|
16
|
+
* If neither `validation`, `validationZone`, nor `validationZones` is set,
|
|
17
|
+
* the builder fails fast — falling back to ACM's email-based validation would
|
|
18
|
+
* stall stack creation waiting on a human to click a link.
|
|
19
|
+
*/
|
|
20
|
+
interface CertificateBuilderProps extends CertificateProps {
|
|
21
|
+
/**
|
|
22
|
+
* The hosted zone used to automatically create DNS validation records
|
|
23
|
+
* for every domain on the certificate. Accepts a {@link Resolvable} so
|
|
24
|
+
* a zone produced by a sibling component can be wired in via `ref`.
|
|
25
|
+
*
|
|
26
|
+
* Mutually exclusive with {@link validationZones} and {@link CertificateProps.validation}.
|
|
27
|
+
* When set, the builder configures
|
|
28
|
+
* {@link CertificateValidation.fromDns | CertificateValidation.fromDns(zone)}.
|
|
29
|
+
*/
|
|
30
|
+
validationZone?: Resolvable<IHostedZone>;
|
|
31
|
+
/**
|
|
32
|
+
* A map of domain name to hosted zone, used when the apex and subject
|
|
33
|
+
* alternative names live in different zones. Each value accepts a
|
|
34
|
+
* {@link Resolvable}. When set, the builder configures
|
|
35
|
+
* {@link CertificateValidation.fromDnsMultiZone}.
|
|
36
|
+
*
|
|
37
|
+
* Mutually exclusive with {@link validationZone} and {@link CertificateProps.validation}.
|
|
38
|
+
*/
|
|
39
|
+
validationZones?: Record<string, Resolvable<IHostedZone>>;
|
|
40
|
+
/**
|
|
41
|
+
* Configuration for AWS-recommended CloudWatch alarms.
|
|
42
|
+
*
|
|
43
|
+
* By default, the builder creates a recommended `daysToExpiry` alarm
|
|
44
|
+
* at 45 days. The alarm can be customized or disabled. Set to `false`
|
|
45
|
+
* to disable all alarms.
|
|
46
|
+
*
|
|
47
|
+
* No alarm actions are configured by default since notification
|
|
48
|
+
* methods are user-specific. Access alarms from the build result
|
|
49
|
+
* or use an `afterBuild` hook to apply actions.
|
|
50
|
+
*
|
|
51
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CertificateManager
|
|
52
|
+
*/
|
|
53
|
+
recommendedAlarms?: CertificateAlarmConfig | false;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The build output of an {@link ICertificateBuilder}. Contains the CDK
|
|
57
|
+
* constructs created during {@link Lifecycle.build}, keyed by role.
|
|
58
|
+
*/
|
|
59
|
+
export interface CertificateBuilderResult {
|
|
60
|
+
/** The ACM certificate construct created by the builder. */
|
|
61
|
+
certificate: Certificate;
|
|
62
|
+
/**
|
|
63
|
+
* CloudWatch alarms created for the certificate, keyed by alarm name.
|
|
64
|
+
*
|
|
65
|
+
* Includes both AWS-recommended alarms and any custom alarms added
|
|
66
|
+
* via {@link ICertificateBuilder.addAlarm}. Access individual alarms
|
|
67
|
+
* by key (e.g., `result.alarms.daysToExpiry`).
|
|
68
|
+
*
|
|
69
|
+
* No alarm actions are configured — apply them via the result or an
|
|
70
|
+
* `afterBuild` hook.
|
|
71
|
+
*
|
|
72
|
+
* @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#CertificateManager
|
|
73
|
+
*/
|
|
74
|
+
alarms: Record<string, Alarm>;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A fluent builder for configuring and creating an AWS Certificate Manager
|
|
78
|
+
* certificate.
|
|
79
|
+
*
|
|
80
|
+
* Each configuration property from the CDK {@link CertificateProps} is
|
|
81
|
+
* exposed as an overloaded method: call with a value to set it (returns the
|
|
82
|
+
* builder for chaining), or call with no arguments to read the current value.
|
|
83
|
+
*
|
|
84
|
+
* Validation is DNS-based by default — set
|
|
85
|
+
* {@link CertificateBuilderProps.validationZone | validationZone} (or
|
|
86
|
+
* {@link CertificateBuilderProps.validationZones | validationZones}) with the
|
|
87
|
+
* hosted zone(s) that own the certificate's domains. Accepts a
|
|
88
|
+
* {@link Resolvable} so zones produced by a composed component can be
|
|
89
|
+
* wired in via `ref`.
|
|
90
|
+
*
|
|
91
|
+
* The builder implements {@link Lifecycle}, so it can be used directly as a
|
|
92
|
+
* component in a {@link compose | composed system}. When built, it creates
|
|
93
|
+
* an ACM certificate with the configured properties and returns a
|
|
94
|
+
* {@link CertificateBuilderResult}.
|
|
95
|
+
*
|
|
96
|
+
* The builder also creates AWS-recommended CloudWatch alarms by default
|
|
97
|
+
* (`daysToExpiry` at 45 days). Alarms can be customized or disabled via the
|
|
98
|
+
* `recommendedAlarms` property.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* const cert = createCertificateBuilder()
|
|
103
|
+
* .domainName("example.com")
|
|
104
|
+
* .subjectAlternativeNames(["www.example.com"])
|
|
105
|
+
* .validationZone(zone);
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export type ICertificateBuilder = IBuilder<CertificateBuilderProps, CertificateBuilder>;
|
|
109
|
+
declare class CertificateBuilder implements Lifecycle<CertificateBuilderResult> {
|
|
110
|
+
props: Partial<CertificateBuilderProps>;
|
|
111
|
+
private readonly customAlarms;
|
|
112
|
+
addAlarm(key: string, configure: (alarm: AlarmDefinitionBuilder<ICertificate>) => AlarmDefinitionBuilder<ICertificate>): this;
|
|
113
|
+
build(scope: IConstruct, id: string, context?: Record<string, object>): CertificateBuilderResult;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Creates a new {@link ICertificateBuilder} for configuring an ACM certificate.
|
|
117
|
+
*
|
|
118
|
+
* This is the entry point for defining an ACM certificate component. The
|
|
119
|
+
* returned builder exposes every {@link CertificateBuilderProps} property as
|
|
120
|
+
* a fluent setter/getter and implements {@link Lifecycle} for use with
|
|
121
|
+
* {@link compose}.
|
|
122
|
+
*
|
|
123
|
+
* @returns A fluent builder for an ACM certificate.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* const cert = createCertificateBuilder()
|
|
128
|
+
* .domainName("example.com")
|
|
129
|
+
* .validationZone(zone);
|
|
130
|
+
*
|
|
131
|
+
* const result = cert.build(stack, "SiteCert");
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export declare function createCertificateBuilder(): ICertificateBuilder;
|
|
135
|
+
export {};
|
|
136
|
+
//# sourceMappingURL=certificate-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"certificate-builder.d.ts","sourceRoot":"","sources":["../src/certificate-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAEX,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAClB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,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;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAIhE;;;;;;;;;;;GAWG;AACH,UAAU,uBAAwB,SAAQ,gBAAgB;IACxD;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAEzC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAE1D;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,sBAAsB,GAAG,KAAK,CAAC;CACpD;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,4DAA4D;IAC5D,WAAW,EAAE,WAAW,CAAC;IAEzB;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,uBAAuB,EAAE,kBAAkB,CAAC,CAAC;AAExF,cAAM,kBAAmB,YAAW,SAAS,CAAC,wBAAwB,CAAC;IACrE,KAAK,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAM;IAC7C,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,KAAK,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,wBAAwB;CA4DjG;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,IAAI,mBAAmB,CAE9D"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Certificate, CertificateValidation, } from "aws-cdk-lib/aws-certificatemanager";
|
|
2
|
+
import { Builder, resolve, } from "@composurecdk/core";
|
|
3
|
+
import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
|
|
4
|
+
import { createCertificateAlarms } from "./certificate-alarms.js";
|
|
5
|
+
import { CERTIFICATE_DEFAULTS } from "./defaults.js";
|
|
6
|
+
class CertificateBuilder {
|
|
7
|
+
props = {};
|
|
8
|
+
customAlarms = [];
|
|
9
|
+
addAlarm(key, configure) {
|
|
10
|
+
this.customAlarms.push(configure(new AlarmDefinitionBuilder(key)));
|
|
11
|
+
return this;
|
|
12
|
+
}
|
|
13
|
+
build(scope, id, context) {
|
|
14
|
+
const { validationZone, validationZones, validation: userValidation, recommendedAlarms: alarmConfig, ...certProps } = this.props;
|
|
15
|
+
if (!certProps.domainName) {
|
|
16
|
+
throw new Error(`CertificateBuilder "${id}" requires a domainName. ` +
|
|
17
|
+
`Call .domainName() with the fully-qualified domain.`);
|
|
18
|
+
}
|
|
19
|
+
if ([userValidation, validationZone, validationZones].filter(Boolean).length > 1) {
|
|
20
|
+
throw new Error(`CertificateBuilder "${id}": 'validation', 'validationZone', and 'validationZones' ` +
|
|
21
|
+
`are mutually exclusive. Set exactly one.`);
|
|
22
|
+
}
|
|
23
|
+
const resolvedContext = context ?? {};
|
|
24
|
+
let validation;
|
|
25
|
+
if (userValidation) {
|
|
26
|
+
validation = userValidation;
|
|
27
|
+
}
|
|
28
|
+
else if (validationZones) {
|
|
29
|
+
const resolvedZones = Object.fromEntries(Object.entries(validationZones).map(([domain, zone]) => [
|
|
30
|
+
domain,
|
|
31
|
+
resolve(zone, resolvedContext),
|
|
32
|
+
]));
|
|
33
|
+
validation = CertificateValidation.fromDnsMultiZone(resolvedZones);
|
|
34
|
+
}
|
|
35
|
+
else if (validationZone) {
|
|
36
|
+
validation = CertificateValidation.fromDns(resolve(validationZone, resolvedContext));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw new Error(`CertificateBuilder "${id}" requires DNS validation to be configured. ` +
|
|
40
|
+
`Call .validationZone() with the hosted zone for the certificate's domain, ` +
|
|
41
|
+
`or .validationZones() when domains span multiple zones, ` +
|
|
42
|
+
`or .validation() to configure an explicit CertificateValidation. ` +
|
|
43
|
+
`Email validation is not enabled by default because it blocks stack creation.`);
|
|
44
|
+
}
|
|
45
|
+
const mergedProps = {
|
|
46
|
+
...CERTIFICATE_DEFAULTS,
|
|
47
|
+
...certProps,
|
|
48
|
+
validation,
|
|
49
|
+
};
|
|
50
|
+
const certificate = new Certificate(scope, id, mergedProps);
|
|
51
|
+
const alarms = createCertificateAlarms(scope, id, certificate, alarmConfig, this.customAlarms);
|
|
52
|
+
return { certificate, alarms };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Creates a new {@link ICertificateBuilder} for configuring an ACM certificate.
|
|
57
|
+
*
|
|
58
|
+
* This is the entry point for defining an ACM certificate component. The
|
|
59
|
+
* returned builder exposes every {@link CertificateBuilderProps} property as
|
|
60
|
+
* a fluent setter/getter and implements {@link Lifecycle} for use with
|
|
61
|
+
* {@link compose}.
|
|
62
|
+
*
|
|
63
|
+
* @returns A fluent builder for an ACM certificate.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* const cert = createCertificateBuilder()
|
|
68
|
+
* .domainName("example.com")
|
|
69
|
+
* .validationZone(zone);
|
|
70
|
+
*
|
|
71
|
+
* const result = cert.build(stack, "SiteCert");
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export function createCertificateBuilder() {
|
|
75
|
+
return Builder(CertificateBuilder);
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=certificate-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"certificate-builder.js","sourceRoot":"","sources":["../src/certificate-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,qBAAqB,GAGtB,MAAM,oCAAoC,CAAC;AAI5C,OAAO,EACL,OAAO,EAGP,OAAO,GAER,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AA6GrD,MAAM,kBAAkB;IACtB,KAAK,GAAqC,EAAE,CAAC;IAC5B,YAAY,GAA2C,EAAE,CAAC;IAE3E,QAAQ,CACN,GAAW,EACX,SAEyC;QAEzC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,sBAAsB,CAAe,GAAG,CAAC,CAAC,CAAC,CAAC;QACjF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,KAAiB,EAAE,EAAU,EAAE,OAAgC;QACnE,MAAM,EACJ,cAAc,EACd,eAAe,EACf,UAAU,EAAE,cAAc,EAC1B,iBAAiB,EAAE,WAAW,EAC9B,GAAG,SAAS,EACb,GAAG,IAAI,CAAC,KAAK,CAAC;QAEf,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,uBAAuB,EAAE,2BAA2B;gBAClD,qDAAqD,CACxD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,cAAc,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjF,MAAM,IAAI,KAAK,CACb,uBAAuB,EAAE,2DAA2D;gBAClF,0CAA0C,CAC7C,CAAC;QACJ,CAAC;QAED,MAAM,eAAe,GAAG,OAAO,IAAI,EAAE,CAAC;QACtC,IAAI,UAAiC,CAAC;QAEtC,IAAI,cAAc,EAAE,CAAC;YACnB,UAAU,GAAG,cAAc,CAAC;QAC9B,CAAC;aAAM,IAAI,eAAe,EAAE,CAAC;YAC3B,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CACtC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;gBACtD,MAAM;gBACN,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC;aAC/B,CAAC,CACH,CAAC;YACF,UAAU,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;QACrE,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAC1B,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,CAAC;QACvF,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CACb,uBAAuB,EAAE,8CAA8C;gBACrE,4EAA4E;gBAC5E,0DAA0D;gBAC1D,mEAAmE;gBACnE,8EAA8E,CACjF,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAG;YAClB,GAAG,oBAAoB;YACvB,GAAG,SAAS;YACZ,UAAU;SACS,CAAC;QAEtB,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAE5D,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAE/F,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IACjC,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO,OAAO,CAA8C,kBAAkB,CAAC,CAAC;AAClF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type CertificateProps } from "aws-cdk-lib/aws-certificatemanager";
|
|
2
|
+
/**
|
|
3
|
+
* Secure, AWS-recommended defaults applied to every ACM certificate built
|
|
4
|
+
* with {@link createCertificateBuilder}. Each property can be individually
|
|
5
|
+
* overridden via the builder's fluent API.
|
|
6
|
+
*/
|
|
7
|
+
export declare const CERTIFICATE_DEFAULTS: Partial<CertificateProps>;
|
|
8
|
+
//# sourceMappingURL=defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEzF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,OAAO,CAAC,gBAAgB,CAiB1D,CAAC"}
|
package/dist/defaults.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { KeyAlgorithm } from "aws-cdk-lib/aws-certificatemanager";
|
|
2
|
+
/**
|
|
3
|
+
* Secure, AWS-recommended defaults applied to every ACM certificate built
|
|
4
|
+
* with {@link createCertificateBuilder}. Each property can be individually
|
|
5
|
+
* overridden via the builder's fluent API.
|
|
6
|
+
*/
|
|
7
|
+
export const CERTIFICATE_DEFAULTS = {
|
|
8
|
+
/**
|
|
9
|
+
* Use RSA-2048 as the key algorithm. Widest client/CDN compatibility
|
|
10
|
+
* (CloudFront, API Gateway, ALB) and sufficient for TLS 1.2 and 1.3.
|
|
11
|
+
* For newer workloads, `KeyAlgorithm.EC_PRIME256V1` offers smaller
|
|
12
|
+
* signatures at comparable security — override via `.keyAlgorithm()`.
|
|
13
|
+
* @see https://docs.aws.amazon.com/acm/latest/userguide/acm-certificate.html#algorithms.title
|
|
14
|
+
*/
|
|
15
|
+
keyAlgorithm: KeyAlgorithm.RSA_2048,
|
|
16
|
+
/**
|
|
17
|
+
* Publish certificates to the public Certificate Transparency (CT) logs.
|
|
18
|
+
* CT logging is required by modern browsers to trust a certificate and
|
|
19
|
+
* enables detection of mis-issuance.
|
|
20
|
+
* @see https://docs.aws.amazon.com/acm/latest/userguide/acm-bestpractices.html#best-practices-transparency
|
|
21
|
+
*/
|
|
22
|
+
transparencyLoggingEnabled: true,
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../src/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAyB,MAAM,oCAAoC,CAAC;AAEzF;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA8B;IAC7D;;;;;;OAMG;IACH,YAAY,EAAE,YAAY,CAAC,QAAQ;IAEnC;;;;;OAKG;IACH,0BAA0B,EAAE,IAAI;CACjC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createCertificateBuilder, type CertificateBuilderResult, type ICertificateBuilder, } from "./certificate-builder.js";
|
|
2
|
+
export { CERTIFICATE_DEFAULTS } from "./defaults.js";
|
|
3
|
+
export { type CertificateAlarmConfig } from "./alarm-config.js";
|
|
4
|
+
export { CERTIFICATE_ALARM_DEFAULTS } from "./alarm-defaults.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,GAGzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@composurecdk/acm",
|
|
3
|
+
"version": "0.3.2",
|
|
4
|
+
"description": "Composable AWS Certificate Manager builder with well-architected defaults",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/laazyj/composureCDK",
|
|
8
|
+
"directory": "packages/acm"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"clean": "rm -rf dist",
|
|
25
|
+
"build": "tsc -p tsconfig.build.json",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [],
|
|
31
|
+
"author": "Jason Duffett (https://github.com/laazyj)",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"type": "module",
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@composurecdk/cloudwatch": "^0.3.0",
|
|
39
|
+
"@composurecdk/core": "^0.3.0",
|
|
40
|
+
"aws-cdk-lib": "^2.0.0",
|
|
41
|
+
"constructs": "^10.0.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^25.6.0",
|
|
45
|
+
"aws-cdk-lib": "^2.250.0",
|
|
46
|
+
"constructs": "^10.6.0",
|
|
47
|
+
"typescript": "^6.0.3",
|
|
48
|
+
"vitest": "^4.1.4"
|
|
49
|
+
}
|
|
50
|
+
}
|