Skip to content

Commit 80b4ac9

Browse files
nmussymergify[bot]
authored andcommitted
feat(cloudfront): complete viewerCertificate support (#4579)
* feat(cloudfront): complete viewerCertificate support * chore: tslint errors * feat(certificatemanager): add getCertificateRegion method * chore: more tslint * chore(acm): export utils * chore(acm): add fromCertificateArn test * feat(cloudfront): throw cert not in us-east-1 * chore: remove eroneous import * chore: more tslint fixes * chore: fix integ test arn * chore: more integ test arn * chore: fix cert region * chore: refactor static X -> fromX * chore: refactor arrow into classic functions * chore: refactor fromCertificate apis * chore: viewer certificate docs * chore: fix README link
1 parent 3202720 commit 80b4ac9

File tree

12 files changed

+674
-35
lines changed

12 files changed

+674
-35
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './certificate';
22
export * from './dns-validated-certificate';
3+
export * from './util';
34

45
// AWS::CertificateManager CloudFormation Resources:
56
export * from './certificatemanager.generated';

packages/@aws-cdk/aws-certificatemanager/lib/util.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { Arn, Stack, Token } from '@aws-cdk/core';
2+
import { ICertificate } from './certificate';
3+
import { DnsValidatedCertificate } from './dns-validated-certificate';
14
import publicSuffixes = require('./public-suffixes');
25

36
/**
@@ -16,3 +19,33 @@ export function apexDomain(domainName: string): string {
1619
}
1720
return accumulated.reverse().join('.');
1821
}
22+
23+
export function isDnsValidatedCertificate(cert: ICertificate): cert is DnsValidatedCertificate {
24+
return cert.hasOwnProperty('domainName');
25+
}
26+
27+
export function getCertificateRegion(cert: ICertificate): string | undefined {
28+
const { certificateArn, stack } = cert;
29+
30+
if (isDnsValidatedCertificate(cert)) {
31+
const requestResource = cert.node.findChild('CertificateRequestorResource').node.defaultChild;
32+
33+
// @ts-ignore
34+
const { _cfnProperties: properties } = requestResource;
35+
const { Region: region } = properties;
36+
37+
if (region && !Token.isUnresolved(region)) {
38+
return region;
39+
}
40+
}
41+
42+
{
43+
const { region } = Arn.parse(certificateArn);
44+
45+
if (region && !Token.isUnresolved(region)) {
46+
return region;
47+
}
48+
}
49+
50+
return Stack.of(stack).region;
51+
}
Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,108 @@
1+
import { PublicHostedZone } from '@aws-cdk/aws-route53';
2+
import { App, Stack } from '@aws-cdk/core';
13
import { Test } from 'nodeunit';
2-
import { apexDomain } from '../lib/util';
4+
import { Certificate, DnsValidatedCertificate } from '../lib';
5+
import { apexDomain, getCertificateRegion, isDnsValidatedCertificate } from '../lib/util';
36

47
export = {
5-
'apex domain returns right domain'(test: Test) {
6-
test.equals('domain.com', apexDomain('domain.com'));
7-
test.equals('domain.com', apexDomain('test.domain.com'));
8-
test.done();
8+
'apex domain': {
9+
'returns right domain'(test: Test) {
10+
test.equals('domain.com', apexDomain('domain.com'));
11+
test.equals('domain.com', apexDomain('test.domain.com'));
12+
test.done();
13+
},
14+
15+
'understands eTLDs'(test: Test) {
16+
test.equals('domain.co.uk', apexDomain('test.domain.co.uk'));
17+
test.done();
18+
},
19+
},
20+
'isDnsValidatedCertificate': {
21+
'new DnsValidatedCertificate is a DnsValidatedCertificate'(test: Test) {
22+
const stack = new Stack();
23+
24+
const hostedZone = new PublicHostedZone(stack, 'ExampleDotCom', {
25+
zoneName: 'example.com'
26+
});
27+
const cert = new DnsValidatedCertificate(stack, 'Certificate', {
28+
domainName: 'test.example.com',
29+
hostedZone
30+
});
31+
32+
test.ok(isDnsValidatedCertificate(cert));
33+
test.done();
34+
},
35+
'new Certificate is not a DnsValidatedCertificate'(test: Test) {
36+
const stack = new Stack();
37+
38+
const cert = new Certificate(stack, 'Certificate', {
39+
domainName: 'test.example.com'
40+
});
41+
42+
test.ok(!isDnsValidatedCertificate(cert));
43+
test.done();
44+
},
45+
'fromCertificateArn is not a DnsValidatedCertificate'(test: Test) {
46+
const stack = new Stack();
47+
48+
const cert = Certificate.fromCertificateArn(stack, 'Certificate', 'cert-arn');
49+
50+
test.ok(!isDnsValidatedCertificate(cert));
51+
test.done();
52+
},
953
},
54+
'getCertificateRegion': {
55+
'from stack'(test: Test) {
56+
// GIVEN
57+
const app = new App();
58+
const stack = new Stack(app, 'RegionStack', {env: {region: 'eu-west-1'}});
1059

11-
'apex domain understands eTLDs'(test: Test) {
12-
test.equals('domain.co.uk', apexDomain('test.domain.co.uk'));
13-
test.done();
14-
}
60+
const certificate = new Certificate(stack, 'TestCertificate', {
61+
domainName: 'www.example.com',
62+
});
63+
64+
test.equals(getCertificateRegion(certificate), 'eu-west-1');
65+
test.done();
66+
},
67+
'from DnsValidatedCertificate region'(test: Test) {
68+
// GIVEN
69+
const app = new App();
70+
const stack = new Stack(app, 'RegionStack', {env: {region: 'eu-west-1'}});
71+
const hostedZone = new PublicHostedZone(stack, 'ExampleDotCom', {
72+
zoneName: 'example.com'
73+
});
74+
75+
const certificate = new DnsValidatedCertificate(stack, 'TestCertificate', {
76+
domainName: 'www.example.com',
77+
hostedZone,
78+
region: 'eu-west-3'
79+
});
80+
81+
test.equals(getCertificateRegion(certificate), 'eu-west-3');
82+
test.done();
83+
},
84+
'fromCertificateArn'(test: Test) {
85+
// GIVEN
86+
const app = new App();
87+
const stack = new Stack(app, 'RegionStack', {env: {region: 'eu-west-1'}});
88+
89+
const certificate = Certificate.fromCertificateArn(
90+
stack, 'TestCertificate', 'arn:aws:acm:us-east-2:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'
91+
);
92+
93+
test.equals(getCertificateRegion(certificate), 'us-east-2');
94+
test.done();
95+
},
96+
'region agnostic stack'(test: Test) {
97+
// GIVEN
98+
const stack = new Stack();
99+
100+
const certificate = new Certificate(stack, 'TestCertificate', {
101+
domainName: 'www.example.com',
102+
});
103+
104+
test.equals(getCertificateRegion(certificate), '${Token[AWS::Region.4]}');
105+
test.done();
106+
},
107+
},
15108
};

packages/@aws-cdk/aws-cloudfront/README.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Example usage:
2121

2222
```ts
2323
const sourceBucket = new Bucket(this, 'Bucket');
24-
24+
2525
const distribution = new CloudFrontWebDistribution(this, 'MyDistribution', {
2626
originConfigs: [
2727
{
@@ -33,3 +33,39 @@ const distribution = new CloudFrontWebDistribution(this, 'MyDistribution', {
3333
]
3434
});
3535
```
36+
37+
### Viewer certificate
38+
39+
By default, CloudFront Web Distributions will answer HTTPS requests with CloudFront's default certificate, only containing the distribution `domainName` (e.g. d111111abcdef8.cloudfront.net).
40+
You can customize the viewer certificate property to provide a custom certificate and/or list of domain name aliases to fit your needs.
41+
42+
See [Using Alternate Domain Names and HTTPS](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-https-alternate-domain-names.html) in the CloudFront User Guide.
43+
44+
#### Default certificate
45+
46+
You can customize the default certificate aliases. This is intended to be used in combination with CNAME records in your DNS zone.
47+
48+
Example:
49+
50+
[create a distrubution with an default certificiate example](test/example.default-cert-alias.lit.ts)
51+
52+
#### ACM certificate
53+
54+
You can change the default certificate by one stored Amazon Certificate Manager, or ACM.
55+
Those certificate can either be generated by AWS, or purchased by another CA imported into ACM.
56+
57+
For more information, see [the aws-certificatemanager module documentation](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-certificatemanager-readme.html) or [Importing Certificates into AWS Certificate Manager](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate.html) in the AWS Certificate Manager User Guide.
58+
59+
Example:
60+
61+
[create a distrubution with an acm certificate example](test/example.acm-cert-alias.lit.ts)
62+
63+
#### IAM certificate
64+
65+
You can also import a certificate into the IAM certificate store.
66+
67+
See [Importing an SSL/TLS Certificate](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-procedures.html#cnames-and-https-uploading-certificates) in the CloudFront User Guide.
68+
69+
Example:
70+
71+
[create a distrubution with an iam certificate example](test/example.iam-cert-alias.lit.ts)

0 commit comments

Comments
 (0)