UNPKG

37.6 kBMarkdownView Raw
1# Amazon CloudFront Construct Library
2<!--BEGIN STABILITY BANNER-->
3
4---
5
6![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)
7
8![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge)
9
10---
11
12<!--END STABILITY BANNER-->
13
14Amazon CloudFront is a web service that speeds up distribution of your static and dynamic web content, such as .html, .css, .js, and image files, to
15your users. CloudFront delivers your content through a worldwide network of data centers called edge locations. When a user requests content that
16you're serving with CloudFront, the user is routed to the edge location that provides the lowest latency, so that content is delivered with the best
17possible performance.
18
19## Distribution API
20
21The `Distribution` API is currently being built to replace the existing `CloudFrontWebDistribution` API. The `Distribution` API is optimized for the
22most common use cases of CloudFront distributions (e.g., single origin and behavior, few customizations) while still providing the ability for more
23advanced use cases. The API focuses on simplicity for the common use cases, and convenience methods for creating the behaviors and origins necessary
24for more complex use cases.
25
26### Creating a distribution
27
28CloudFront distributions deliver your content from one or more origins; an origin is the location where you store the original version of your
29content. Origins can be created from S3 buckets or a custom origin (HTTP server). Constructs to define origins are in the `@aws-cdk/aws-cloudfront-origins` module.
30
31Each distribution has a default behavior which applies to all requests to that distribution, and routes requests to a primary origin.
32Additional behaviors may be specified for an origin with a given URL path pattern. Behaviors allow routing with multiple origins,
33controlling which HTTP methods to support, whether to require users to use HTTPS, and what query strings or cookies to forward to your origin,
34among other settings.
35
36#### From an S3 Bucket
37
38An S3 bucket can be added as an origin. If the bucket is configured as a website endpoint, the distribution can use S3 redirects and S3 custom error
39documents.
40
41```ts
42// Creates a distribution from an S3 bucket.
43const myBucket = new s3.Bucket(this, 'myBucket');
44new cloudfront.Distribution(this, 'myDist', {
45 defaultBehavior: { origin: new origins.S3Origin(myBucket) },
46});
47```
48
49The above will treat the bucket differently based on if `IBucket.isWebsite` is set or not. If the bucket is configured as a website, the bucket is
50treated as an HTTP origin, and the built-in S3 redirects and error pages can be used. Otherwise, the bucket is handled as a bucket origin and
51CloudFront's redirect and error handling will be used. In the latter case, the Origin will create an origin access identity and grant it access to the
52underlying bucket. This can be used in conjunction with a bucket that is not public to require that your users access your content using CloudFront
53URLs and not S3 URLs directly.
54
55#### ELBv2 Load Balancer
56
57An Elastic Load Balancing (ELB) v2 load balancer may be used as an origin. In order for a load balancer to serve as an origin, it must be publicly
58accessible (`internetFacing` is true). Both Application and Network load balancers are supported.
59
60```ts
61// Creates a distribution from an ELBv2 load balancer
62declare const vpc: ec2.Vpc;
63// Create an application load balancer in a VPC. 'internetFacing' must be 'true'
64// for CloudFront to access the load balancer and use it as an origin.
65const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
66 vpc,
67 internetFacing: true,
68});
69new cloudfront.Distribution(this, 'myDist', {
70 defaultBehavior: { origin: new origins.LoadBalancerV2Origin(lb) },
71});
72```
73
74#### From an HTTP endpoint
75
76Origins can also be created from any other HTTP endpoint, given the domain name, and optionally, other origin properties.
77
78```ts
79// Creates a distribution from an HTTP endpoint
80new cloudfront.Distribution(this, 'myDist', {
81 defaultBehavior: { origin: new origins.HttpOrigin('www.example.com') },
82});
83```
84
85### Domain Names and Certificates
86
87When you create a distribution, CloudFront assigns a domain name for the distribution, for example: `d111111abcdef8.cloudfront.net`; this value can
88be retrieved from `distribution.distributionDomainName`. CloudFront distributions use a default certificate (`*.cloudfront.net`) to support HTTPS by
89default. If you want to use your own domain name, such as `www.example.com`, you must associate a certificate with your distribution that contains
90your domain name, and provide one (or more) domain names from the certificate for the distribution.
91
92The certificate must be present in the AWS Certificate Manager (ACM) service in the US East (N. Virginia) region; the certificate
93may either be created by ACM, or created elsewhere and imported into ACM. When a certificate is used, the distribution will support HTTPS connections
94from SNI only and a minimum protocol version of TLSv1.2_2021 if the `@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021` feature flag is set, and TLSv1.2_2019 otherwise.
95
96```ts
97// To use your own domain name in a Distribution, you must associate a certificate
98import * as acm from '@aws-cdk/aws-certificatemanager';
99import * as route53 from '@aws-cdk/aws-route53';
100
101declare const hostedZone: route53.HostedZone;
102const myCertificate = new acm.DnsValidatedCertificate(this, 'mySiteCert', {
103 domainName: 'www.example.com',
104 hostedZone,
105});
106
107declare const myBucket: s3.Bucket;
108new cloudfront.Distribution(this, 'myDist', {
109 defaultBehavior: { origin: new origins.S3Origin(myBucket) },
110 domainNames: ['www.example.com'],
111 certificate: myCertificate,
112});
113```
114
115However, you can customize the minimum protocol version for the certificate while creating the distribution using `minimumProtocolVersion` property.
116
117```ts
118// Create a Distribution with a custom domain name and a minimum protocol version.
119declare const myBucket: s3.Bucket;
120new cloudfront.Distribution(this, 'myDist', {
121 defaultBehavior: { origin: new origins.S3Origin(myBucket) },
122 domainNames: ['www.example.com'],
123 minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2016,
124 sslSupportMethod: cloudfront.SSLMethod.SNI,
125});
126```
127
128### Multiple Behaviors & Origins
129
130Each distribution has a default behavior which applies to all requests to that distribution; additional behaviors may be specified for a
131given URL path pattern. Behaviors allow routing with multiple origins, controlling which HTTP methods to support, whether to require users to
132use HTTPS, and what query strings or cookies to forward to your origin, among others.
133
134The properties of the default behavior can be adjusted as part of the distribution creation. The following example shows configuring the HTTP
135methods and viewer protocol policy of the cache.
136
137```ts
138// Create a Distribution with configured HTTP methods and viewer protocol policy of the cache.
139declare const myBucket: s3.Bucket;
140const myWebDistribution = new cloudfront.Distribution(this, 'myDist', {
141 defaultBehavior: {
142 origin: new origins.S3Origin(myBucket),
143 allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
144 viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
145 },
146});
147```
148
149Additional behaviors can be specified at creation, or added after the initial creation. Each additional behavior is associated with an origin,
150and enable customization for a specific set of resources based on a URL path pattern. For example, we can add a behavior to `myWebDistribution` to
151override the default viewer protocol policy for all of the images.
152
153```ts
154// Add a behavior to a Distribution after initial creation.
155declare const myBucket: s3.Bucket;
156declare const myWebDistribution: cloudfront.Distribution;
157myWebDistribution.addBehavior('/images/*.jpg', new origins.S3Origin(myBucket), {
158 viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
159});
160```
161
162These behaviors can also be specified at distribution creation time.
163
164```ts
165// Create a Distribution with additional behaviors at creation time.
166declare const myBucket: s3.Bucket;
167const bucketOrigin = new origins.S3Origin(myBucket);
168new cloudfront.Distribution(this, 'myDist', {
169 defaultBehavior: {
170 origin: bucketOrigin,
171 allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
172 viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
173 },
174 additionalBehaviors: {
175 '/images/*.jpg': {
176 origin: bucketOrigin,
177 viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
178 },
179 },
180});
181```
182
183### Customizing Cache Keys and TTLs with Cache Policies
184
185You can use a cache policy to improve your cache hit ratio by controlling the values (URL query strings, HTTP headers, and cookies)
186that are included in the cache key, and/or adjusting how long items remain in the cache via the time-to-live (TTL) settings.
187CloudFront provides some predefined cache policies, known as managed policies, for common use cases. You can use these managed policies,
188or you can create your own cache policy that’s specific to your needs.
189See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-the-cache-key.html for more details.
190
191```ts
192// Using an existing cache policy for a Distribution
193declare const bucketOrigin: origins.S3Origin;
194new cloudfront.Distribution(this, 'myDistManagedPolicy', {
195 defaultBehavior: {
196 origin: bucketOrigin,
197 cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
198 },
199});
200```
201
202```ts
203// Creating a custom cache policy for a Distribution -- all parameters optional
204declare const bucketOrigin: origins.S3Origin;
205const myCachePolicy = new cloudfront.CachePolicy(this, 'myCachePolicy', {
206 cachePolicyName: 'MyPolicy',
207 comment: 'A default policy',
208 defaultTtl: Duration.days(2),
209 minTtl: Duration.minutes(1),
210 maxTtl: Duration.days(10),
211 cookieBehavior: cloudfront.CacheCookieBehavior.all(),
212 headerBehavior: cloudfront.CacheHeaderBehavior.allowList('X-CustomHeader'),
213 queryStringBehavior: cloudfront.CacheQueryStringBehavior.denyList('username'),
214 enableAcceptEncodingGzip: true,
215 enableAcceptEncodingBrotli: true,
216});
217new cloudfront.Distribution(this, 'myDistCustomPolicy', {
218 defaultBehavior: {
219 origin: bucketOrigin,
220 cachePolicy: myCachePolicy,
221 },
222});
223```
224
225### Customizing Origin Requests with Origin Request Policies
226
227When CloudFront makes a request to an origin, the URL path, request body (if present), and a few standard headers are included.
228Other information from the viewer request, such as URL query strings, HTTP headers, and cookies, is not included in the origin request by default.
229You can use an origin request policy to control the information that’s included in an origin request.
230CloudFront provides some predefined origin request policies, known as managed policies, for common use cases. You can use these managed policies,
231or you can create your own origin request policy that’s specific to your needs.
232See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html for more details.
233
234```ts
235// Using an existing origin request policy for a Distribution
236declare const bucketOrigin: origins.S3Origin;
237new cloudfront.Distribution(this, 'myDistManagedPolicy', {
238 defaultBehavior: {
239 origin: bucketOrigin,
240 originRequestPolicy: cloudfront.OriginRequestPolicy.CORS_S3_ORIGIN,
241 },
242});
243```
244
245```ts
246// Creating a custom origin request policy for a Distribution -- all parameters optional
247declare const bucketOrigin: origins.S3Origin;
248const myOriginRequestPolicy = new cloudfront.OriginRequestPolicy(this, 'OriginRequestPolicy', {
249 originRequestPolicyName: 'MyPolicy',
250 comment: 'A default policy',
251 cookieBehavior: cloudfront.OriginRequestCookieBehavior.none(),
252 headerBehavior: cloudfront.OriginRequestHeaderBehavior.all('CloudFront-Is-Android-Viewer'),
253 queryStringBehavior: cloudfront.OriginRequestQueryStringBehavior.allowList('username'),
254});
255
256new cloudfront.Distribution(this, 'myDistCustomPolicy', {
257 defaultBehavior: {
258 origin: bucketOrigin,
259 originRequestPolicy: myOriginRequestPolicy,
260 },
261});
262```
263
264### Customizing Response Headers with Response Headers Policies
265
266You can configure CloudFront to add one or more HTTP headers to the responses that it sends to viewers (web browsers or other clients), without making any changes to the origin or writing any code.
267To specify the headers that CloudFront adds to HTTP responses, you use a response headers policy. CloudFront adds the headers regardless of whether it serves the object from the cache or has to retrieve the object from the origin. If the origin response includes one or more of the headers that’s in a response headers policy, the policy can specify whether CloudFront uses the header it received from the origin or overwrites it with the one in the policy.
268See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-response-headers.html
269
270```ts
271// Using an existing managed response headers policy
272declare const bucketOrigin: origins.S3Origin;
273new cloudfront.Distribution(this, 'myDistManagedPolicy', {
274 defaultBehavior: {
275 origin: bucketOrigin,
276 responseHeadersPolicy: cloudfront.ResponseHeadersPolicy.CORS_ALLOW_ALL_ORIGINS,
277 },
278});
279
280// Creating a custom response headers policy -- all parameters optional
281const myResponseHeadersPolicy = new cloudfront.ResponseHeadersPolicy(this, 'ResponseHeadersPolicy', {
282 responseHeadersPolicyName: 'MyPolicy',
283 comment: 'A default policy',
284 corsBehavior: {
285 accessControlAllowCredentials: false,
286 accessControlAllowHeaders: ['X-Custom-Header-1', 'X-Custom-Header-2'],
287 accessControlAllowMethods: ['GET', 'POST'],
288 accessControlAllowOrigins: ['*'],
289 accessControlExposeHeaders: ['X-Custom-Header-1', 'X-Custom-Header-2'],
290 accessControlMaxAge: Duration.seconds(600),
291 originOverride: true,
292 },
293 customHeadersBehavior: {
294 customHeaders: [
295 { header: 'X-Amz-Date', value: 'some-value', override: true },
296 { header: 'X-Amz-Security-Token', value: 'some-value', override: false },
297 ],
298 },
299 securityHeadersBehavior: {
300 contentSecurityPolicy: { contentSecurityPolicy: 'default-src https:;', override: true },
301 contentTypeOptions: { override: true },
302 frameOptions: { frameOption: cloudfront.HeadersFrameOption.DENY, override: true },
303 referrerPolicy: { referrerPolicy: cloudfront.HeadersReferrerPolicy.NO_REFERRER, override: true },
304 strictTransportSecurity: { accessControlMaxAge: Duration.seconds(600), includeSubdomains: true, override: true },
305 xssProtection: { protection: true, modeBlock: true, reportUri: 'https://example.com/csp-report', override: true },
306 },
307});
308new cloudfront.Distribution(this, 'myDistCustomPolicy', {
309 defaultBehavior: {
310 origin: bucketOrigin,
311 responseHeadersPolicy: myResponseHeadersPolicy,
312 },
313});
314```
315
316### Validating signed URLs or signed cookies with Trusted Key Groups
317
318CloudFront Distribution supports validating signed URLs or signed cookies using key groups.
319When a cache behavior contains trusted key groups, CloudFront requires signed URLs or signed
320cookies for all requests that match the cache behavior.
321
322```ts
323// Validating signed URLs or signed cookies with Trusted Key Groups
324
325// public key in PEM format
326declare const publicKey: string;
327const pubKey = new cloudfront.PublicKey(this, 'MyPubKey', {
328 encodedKey: publicKey,
329});
330
331const keyGroup = new cloudfront.KeyGroup(this, 'MyKeyGroup', {
332 items: [
333 pubKey,
334 ],
335});
336
337new cloudfront.Distribution(this, 'Dist', {
338 defaultBehavior: {
339 origin: new origins.HttpOrigin('www.example.com'),
340 trustedKeyGroups: [
341 keyGroup,
342 ],
343 },
344});
345```
346
347### Lambda@Edge
348
349Lambda@Edge is an extension of AWS Lambda, a compute service that lets you execute
350functions that customize the content that CloudFront delivers. You can author Node.js
351or Python functions in the US East (N. Virginia) region, and then execute them in AWS
352locations globally that are closer to the viewer, without provisioning or managing servers.
353Lambda@Edge functions are associated with a specific behavior and event type. Lambda@Edge
354can be used to rewrite URLs, alter responses based on headers or cookies, or authorize
355requests based on headers or authorization tokens.
356
357The following shows a Lambda@Edge function added to the default behavior and triggered
358on every request:
359
360```ts
361// A Lambda@Edge function added to default behavior of a Distribution
362// and triggered on every request
363const myFunc = new cloudfront.experimental.EdgeFunction(this, 'MyFunction', {
364 runtime: lambda.Runtime.NODEJS_12_X,
365 handler: 'index.handler',
366 code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),
367});
368
369declare const myBucket: s3.Bucket;
370new cloudfront.Distribution(this, 'myDist', {
371 defaultBehavior: {
372 origin: new origins.S3Origin(myBucket),
373 edgeLambdas: [
374 {
375 functionVersion: myFunc.currentVersion,
376 eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
377 }
378 ],
379 },
380});
381```
382
383> **Note:** Lambda@Edge functions must be created in the `us-east-1` region, regardless of the region of the CloudFront distribution and stack.
384> To make it easier to request functions for Lambda@Edge, the `EdgeFunction` construct can be used.
385> The `EdgeFunction` construct will automatically request a function in `us-east-1`, regardless of the region of the current stack.
386> `EdgeFunction` has the same interface as `Function` and can be created and used interchangeably.
387> Please note that using `EdgeFunction` requires that the `us-east-1` region has been bootstrapped.
388> See https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html for more about bootstrapping regions.
389
390If the stack is in `us-east-1`, a "normal" `lambda.Function` can be used instead of an `EdgeFunction`.
391
392```ts
393// Using a lambda Function instead of an EdgeFunction for stacks in `us-east-`.
394const myFunc = new lambda.Function(this, 'MyFunction', {
395 runtime: lambda.Runtime.NODEJS_12_X,
396 handler: 'index.handler',
397 code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),
398});
399```
400
401If the stack is not in `us-east-1`, and you need references from different applications on the same account,
402you can also set a specific stack ID for each Lambda@Edge.
403
404```ts
405// Setting stackIds for EdgeFunctions that can be referenced from different applications
406// on the same account.
407const myFunc1 = new cloudfront.experimental.EdgeFunction(this, 'MyFunction1', {
408 runtime: lambda.Runtime.NODEJS_12_X,
409 handler: 'index.handler',
410 code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler1')),
411 stackId: 'edge-lambda-stack-id-1',
412});
413
414const myFunc2 = new cloudfront.experimental.EdgeFunction(this, 'MyFunction2', {
415 runtime: lambda.Runtime.NODEJS_12_X,
416 handler: 'index.handler',
417 code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler2')),
418 stackId: 'edge-lambda-stack-id-2',
419});
420```
421
422Lambda@Edge functions can also be associated with additional behaviors,
423either at or after Distribution creation time.
424
425```ts
426// Associating a Lambda@Edge function with additional behaviors.
427
428declare const myFunc: cloudfront.experimental.EdgeFunction;
429// assigning at Distribution creation
430declare const myBucket: s3.Bucket;
431const myOrigin = new origins.S3Origin(myBucket);
432const myDistribution = new cloudfront.Distribution(this, 'myDist', {
433 defaultBehavior: { origin: myOrigin },
434 additionalBehaviors: {
435 'images/*': {
436 origin: myOrigin,
437 edgeLambdas: [
438 {
439 functionVersion: myFunc.currentVersion,
440 eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
441 includeBody: true, // Optional - defaults to false
442 },
443 ],
444 },
445 },
446});
447
448// assigning after creation
449myDistribution.addBehavior('images/*', myOrigin, {
450 edgeLambdas: [
451 {
452 functionVersion: myFunc.currentVersion,
453 eventType: cloudfront.LambdaEdgeEventType.VIEWER_RESPONSE,
454 },
455 ],
456});
457```
458
459Adding an existing Lambda@Edge function created in a different stack to a CloudFront distribution.
460
461```ts
462// Adding an existing Lambda@Edge function created in a different stack
463// to a CloudFront distribution.
464declare const s3Bucket: s3.Bucket;
465const functionVersion = lambda.Version.fromVersionArn(this, 'Version', 'arn:aws:lambda:us-east-1:123456789012:function:functionName:1');
466
467new cloudfront.Distribution(this, 'distro', {
468 defaultBehavior: {
469 origin: new origins.S3Origin(s3Bucket),
470 edgeLambdas: [
471 {
472 functionVersion,
473 eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
474 },
475 ],
476 },
477});
478```
479
480### CloudFront Function
481
482You can also deploy CloudFront functions and add them to a CloudFront distribution.
483
484```ts
485// Add a cloudfront Function to a Distribution
486const cfFunction = new cloudfront.Function(this, 'Function', {
487 code: cloudfront.FunctionCode.fromInline('function handler(event) { return event.request }'),
488});
489
490declare const s3Bucket: s3.Bucket;
491new cloudfront.Distribution(this, 'distro', {
492 defaultBehavior: {
493 origin: new origins.S3Origin(s3Bucket),
494 functionAssociations: [{
495 function: cfFunction,
496 eventType: cloudfront.FunctionEventType.VIEWER_REQUEST,
497 }],
498 },
499});
500```
501
502It will auto-generate the name of the function and deploy it to the `live` stage.
503
504Additionally, you can load the function's code from a file using the `FunctionCode.fromFile()` method.
505
506### Logging
507
508You can configure CloudFront to create log files that contain detailed information about every user request that CloudFront receives.
509The logs can go to either an existing bucket, or a bucket will be created for you.
510
511```ts
512// Configure logging for Distributions
513
514// Simplest form - creates a new bucket and logs to it.
515new cloudfront.Distribution(this, 'myDist', {
516 defaultBehavior: { origin: new origins.HttpOrigin('www.example.com') },
517 enableLogging: true,
518});
519
520// You can optionally log to a specific bucket, configure whether cookies are logged, and give the log files a prefix.
521new cloudfront.Distribution(this, 'myDist', {
522 defaultBehavior: { origin: new origins.HttpOrigin('www.example.com') },
523 enableLogging: true, // Optional, this is implied if logBucket is specified
524 logBucket: new s3.Bucket(this, 'LogBucket'),
525 logFilePrefix: 'distribution-access-logs/',
526 logIncludesCookies: true,
527});
528```
529
530### Importing Distributions
531
532Existing distributions can be imported as well; note that like most imported constructs, an imported distribution cannot be modified.
533However, it can be used as a reference for other higher-level constructs.
534
535```ts
536// Using a reference to an imported Distribution
537const distribution = cloudfront.Distribution.fromDistributionAttributes(this, 'ImportedDist', {
538 domainName: 'd111111abcdef8.cloudfront.net',
539 distributionId: '012345ABCDEF',
540});
541```
542
543## Migrating from the original CloudFrontWebDistribution to the newer Distribution construct
544
545It's possible to migrate a distribution from the original to the modern API.
546The changes necessary are the following:
547
548### The Distribution
549
550Replace `new CloudFrontWebDistribution` with `new Distribution`. Some
551configuration properties have been changed:
552
553| Old API | New API |
554|--------------------------------|------------------------------------------------------------------------------------------------|
555| `originConfigs` | `defaultBehavior`; use `additionalBehaviors` if necessary |
556| `viewerCertificate` | `certificate`; use `domainNames` for aliases |
557| `errorConfigurations` | `errorResponses` |
558| `loggingConfig` | `enableLogging`; configure with `logBucket` `logFilePrefix` and `logIncludesCookies` |
559| `viewerProtocolPolicy` | removed; set on each behavior instead. default changed from `REDIRECT_TO_HTTPS` to `ALLOW_ALL` |
560
561After switching constructs, you need to maintain the same logical ID for the underlying [CfnDistribution](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-cloudfront.CfnDistribution.html) if you wish to avoid the deletion and recreation of your distribution.
562To do this, use [escape hatches](https://docs.aws.amazon.com/cdk/v2/guide/cfn_layer.html) to override the logical ID created by the new Distribution construct with the logical ID created by the old construct.
563
564Example:
565
566```ts
567declare const sourceBucket: s3.Bucket;
568
569const myDistribution = new cloudfront.Distribution(this, 'MyCfWebDistribution', {
570 defaultBehavior: {
571 origin: new origins.S3Origin(sourceBucket),
572 },
573});
574const cfnDistribution = myDistribution.node.defaultChild as cloudfront.CfnDistribution;
575cfnDistribution.overrideLogicalId('MyDistributionCFDistribution3H55TI9Q');
576```
577
578### Behaviors
579
580The modern API makes use of the [CloudFront Origins](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudfront_origins-readme.html) module to easily configure your origin. Replace your origin configuration with the relevant CloudFront Origins class. For example, here's a behavior with an S3 origin:
581
582```ts
583declare const sourceBucket: s3.Bucket;
584declare const oai: cloudfront.OriginAccessIdentity;
585
586new cloudfront.CloudFrontWebDistribution(this, 'MyCfWebDistribution', {
587 originConfigs: [
588 {
589 s3OriginSource: {
590 s3BucketSource: sourceBucket,
591 originAccessIdentity: oai,
592 },
593 behaviors : [ {isDefaultBehavior: true}],
594 },
595 ],
596});
597```
598
599Becomes:
600
601```ts
602declare const sourceBucket: s3.Bucket;
603
604const distribution = new cloudfront.Distribution(this, 'MyCfWebDistribution', {
605 defaultBehavior: {
606 origin: new origins.S3Origin(sourceBucket) // This class automatically creates an Origin Access Identity
607 },
608});
609```
610
611In the original API all behaviors are defined in the `originConfigs` property. The new API is optimized for a single origin and behavior, so the default behavior and additional behaviors will be defined separately.
612
613```ts
614declare const sourceBucket: s3.Bucket;
615declare const oai: cloudfront.OriginAccessIdentity;
616
617new cloudfront.CloudFrontWebDistribution(this, 'MyCfWebDistribution', {
618 originConfigs: [
619 {
620 s3OriginSource: {
621 s3BucketSource: sourceBucket,
622 originAccessIdentity: oai,
623 },
624 behaviors: [ {isDefaultBehavior: true}],
625 },
626 {
627 customOriginSource: {
628 domainName: 'MYALIAS',
629 },
630 behaviors: [{ pathPattern: '/somewhere' }]
631 }
632 ],
633});
634```
635
636Becomes:
637
638```ts
639declare const sourceBucket: s3.Bucket;
640
641const distribution = new cloudfront.Distribution(this, 'MyCfWebDistribution', {
642 defaultBehavior: {
643 origin: new origins.S3Origin(sourceBucket) // This class automatically creates an Origin Access Identity
644 },
645 additionalBehaviors: {
646 '/somewhere': {
647 origin: new origins.HttpOrigin('MYALIAS'),
648 }
649 }
650});
651```
652
653### Certificates
654
655If you are using an ACM certificate, you can pass the certificate directly to the `certificate` prop.
656Any aliases used before in the `ViewerCertificate` class should be passed in to the `domainNames` prop in the modern API.
657
658```ts
659import * as acm from '@aws-cdk/aws-certificatemanager';
660declare const certificate: acm.Certificate;
661declare const sourceBucket: s3.Bucket;
662
663const viewerCertificate = cloudfront.ViewerCertificate.fromAcmCertificate(certificate, {
664 aliases: ['MYALIAS'],
665});
666
667new cloudfront.CloudFrontWebDistribution(this, 'MyCfWebDistribution', {
668 originConfigs: [
669 {
670 s3OriginSource: {
671 s3BucketSource: sourceBucket,
672 },
673 behaviors : [ {isDefaultBehavior: true} ],
674 },
675 ],
676 viewerCertificate: viewerCertificate,
677});
678```
679
680Becomes:
681
682```ts
683import * as acm from '@aws-cdk/aws-certificatemanager';
684declare const certificate: acm.Certificate;
685declare const sourceBucket: s3.Bucket;
686
687const distribution = new cloudfront.Distribution(this, 'MyCfWebDistribution', {
688 defaultBehavior: {
689 origin: new origins.S3Origin(sourceBucket),
690 },
691 domainNames: ['MYALIAS'],
692 certificate: certificate,
693});
694```
695
696IAM certificates aren't directly supported by the new API, but can be easily configured through [escape hatches](https://docs.aws.amazon.com/cdk/v2/guide/cfn_layer.html)
697
698```ts
699declare const sourceBucket: s3.Bucket;
700const viewerCertificate = cloudfront.ViewerCertificate.fromIamCertificate('MYIAMROLEIDENTIFIER', {
701 aliases: ['MYALIAS'],
702});
703
704new cloudfront.CloudFrontWebDistribution(this, 'MyCfWebDistribution', {
705 originConfigs: [
706 {
707 s3OriginSource: {
708 s3BucketSource: sourceBucket,
709 },
710 behaviors : [ {isDefaultBehavior: true} ],
711 },
712 ],
713 viewerCertificate: viewerCertificate,
714});
715```
716
717Becomes:
718
719```ts
720declare const sourceBucket: s3.Bucket;
721const distribution = new cloudfront.Distribution(this, 'MyCfWebDistribution', {
722 defaultBehavior: {
723 origin: new origins.S3Origin(sourceBucket),
724 },
725 domainNames: ['MYALIAS'],
726});
727
728const cfnDistribution = distribution.node.defaultChild as cloudfront.CfnDistribution;
729
730cfnDistribution.addPropertyOverride('ViewerCertificate.IamCertificateId', 'MYIAMROLEIDENTIFIER');
731cfnDistribution.addPropertyOverride('ViewerCertificate.SslSupportMethod', 'sni-only');
732```
733
734### Other changes
735
736A number of default settings have changed on the new API when creating a new distribution, behavior, and origin.
737After making the major changes needed for the migration, run `cdk diff` to see what settings have changed.
738If no changes are desired during migration, you will at the least be able to use [escape hatches](https://docs.aws.amazon.com/cdk/v2/guide/cfn_layer.html) to override what the CDK synthesizes, if you can't change the properties directly.
739
740## CloudFrontWebDistribution API
741
742> The `CloudFrontWebDistribution` construct is the original construct written for working with CloudFront distributions.
743> Users are encouraged to use the newer `Distribution` instead, as it has a simpler interface and receives new features faster.
744
745Example usage:
746
747```ts
748// Using a CloudFrontWebDistribution construct.
749
750declare const sourceBucket: s3.Bucket;
751const distribution = new cloudfront.CloudFrontWebDistribution(this, 'MyDistribution', {
752 originConfigs: [
753 {
754 s3OriginSource: {
755 s3BucketSource: sourceBucket,
756 },
757 behaviors : [ {isDefaultBehavior: true}],
758 },
759 ],
760});
761```
762
763### Viewer certificate
764
765By default, CloudFront Web Distributions will answer HTTPS requests with CloudFront's default certificate,
766only containing the distribution `domainName` (e.g. d111111abcdef8.cloudfront.net).
767You can customize the viewer certificate property to provide a custom certificate and/or list of domain name aliases to fit your needs.
768
769See [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.
770
771#### Default certificate
772
773You can customize the default certificate aliases. This is intended to be used in combination with CNAME records in your DNS zone.
774
775Example:
776
777[create a distribution with an default certificate example](test/example.default-cert-alias.lit.ts)
778
779#### ACM certificate
780
781You can change the default certificate by one stored AWS Certificate Manager, or ACM.
782Those certificate can either be generated by AWS, or purchased by another CA imported into ACM.
783
784For more information, see
785[the aws-certificatemanager module documentation](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-certificatemanager-readme.html)
786or [Importing Certificates into AWS Certificate Manager](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate.html)
787in the AWS Certificate Manager User Guide.
788
789Example:
790
791[create a distribution with an acm certificate example](test/example.acm-cert-alias.lit.ts)
792
793#### IAM certificate
794
795You can also import a certificate into the IAM certificate store.
796
797See [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.
798
799Example:
800
801[create a distribution with an iam certificate example](test/example.iam-cert-alias.lit.ts)
802
803### Trusted Key Groups
804
805CloudFront Web Distributions supports validating signed URLs or signed cookies using key groups.
806When a cache behavior contains trusted key groups, CloudFront requires signed URLs or signed cookies for all requests that match the cache behavior.
807
808Example:
809
810```ts
811// Using trusted key groups for Cloudfront Web Distributions.
812declare const sourceBucket: s3.Bucket;
813declare const publicKey: string;
814const pubKey = new cloudfront.PublicKey(this, 'MyPubKey', {
815 encodedKey: publicKey,
816});
817
818const keyGroup = new cloudfront.KeyGroup(this, 'MyKeyGroup', {
819 items: [
820 pubKey,
821 ],
822});
823
824new cloudfront.CloudFrontWebDistribution(this, 'AnAmazingWebsiteProbably', {
825 originConfigs: [
826 {
827 s3OriginSource: {
828 s3BucketSource: sourceBucket,
829 },
830 behaviors: [
831 {
832 isDefaultBehavior: true,
833 trustedKeyGroups: [
834 keyGroup,
835 ],
836 },
837 ],
838 },
839 ],
840});
841```
842
843### Restrictions
844
845CloudFront supports adding restrictions to your distribution.
846
847See [Restricting the Geographic Distribution of Your Content](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/georestrictions.html) in the CloudFront User Guide.
848
849Example:
850
851```ts
852// Adding restrictions to a Cloudfront Web Distribution.
853declare const sourceBucket: s3.Bucket;
854new cloudfront.CloudFrontWebDistribution(this, 'MyDistribution', {
855 originConfigs: [
856 {
857 s3OriginSource: {
858 s3BucketSource: sourceBucket,
859 },
860 behaviors : [ {isDefaultBehavior: true}],
861 },
862 ],
863 geoRestriction: cloudfront.GeoRestriction.allowlist('US', 'GB'),
864});
865```
866
867### Connection behaviors between CloudFront and your origin
868
869CloudFront provides you even more control over the connection behaviors between CloudFront and your origin.
870You can now configure the number of connection attempts CloudFront will make to your origin and the origin connection timeout for each attempt.
871
872See [Origin Connection Attempts](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#origin-connection-attempts)
873
874See [Origin Connection Timeout](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#origin-connection-timeout)
875
876Example usage:
877
878```ts
879// Configuring connection behaviors between Cloudfront and your origin
880const distribution = new cloudfront.CloudFrontWebDistribution(this, 'MyDistribution', {
881 originConfigs: [
882 {
883 connectionAttempts: 3,
884 connectionTimeout: Duration.seconds(10),
885 behaviors: [
886 {
887 isDefaultBehavior: true,
888 },
889 ],
890 },
891 ],
892});
893```
894
895#### Origin Fallback
896
897In case the origin source is not available and answers with one of the
898specified status codes the failover origin source will be used.
899
900```ts
901// Configuring origin fallback options for the CloudFrontWebDistribution
902new cloudfront.CloudFrontWebDistribution(this, 'ADistribution', {
903 originConfigs: [
904 {
905 s3OriginSource: {
906 s3BucketSource: s3.Bucket.fromBucketName(this, 'aBucket', 'myoriginbucket'),
907 originPath: '/',
908 originHeaders: {
909 'myHeader': '42',
910 },
911 originShieldRegion: 'us-west-2',
912 },
913 failoverS3OriginSource: {
914 s3BucketSource: s3.Bucket.fromBucketName(this, 'aBucketFallback', 'myoriginbucketfallback'),
915 originPath: '/somewhere',
916 originHeaders: {
917 'myHeader2': '21',
918 },
919 originShieldRegion: 'us-east-1',
920 },
921 failoverCriteriaStatusCodes: [cloudfront.FailoverStatusCode.INTERNAL_SERVER_ERROR],
922 behaviors: [
923 {
924 isDefaultBehavior: true,
925 },
926 ],
927 },
928 ],
929});
930```
931
932## KeyGroup & PublicKey API
933
934You can create a key group to use with CloudFront signed URLs and signed cookies
935You can add public keys to use with CloudFront features such as signed URLs, signed cookies, and field-level encryption.
936
937The following example command uses OpenSSL to generate an RSA key pair with a length of 2048 bits and save to the file named `private_key.pem`.
938
939```bash
940openssl genrsa -out private_key.pem 2048
941```
942
943The resulting file contains both the public and the private key. The following example command extracts the public key from the file named `private_key.pem` and stores it in `public_key.pem`.
944
945```bash
946openssl rsa -pubout -in private_key.pem -out public_key.pem
947```
948
949Note: Don't forget to copy/paste the contents of `public_key.pem` file including `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----` lines into `encodedKey` parameter when creating a `PublicKey`.
950
951Example:
952
953```ts
954// Create a key group to use with CloudFront signed URLs and signed cookies.
955new cloudfront.KeyGroup(this, 'MyKeyGroup', {
956 items: [
957 new cloudfront.PublicKey(this, 'MyPublicKey', {
958 encodedKey: '...', // contents of public_key.pem file
959 // comment: 'Key is expiring on ...',
960 }),
961 ],
962 // comment: 'Key group containing public keys ...',
963});
964```
965
966See:
967
968* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html
969* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html