Configuring CloudFront to compress objects in AWS CDK
Tags: cdk, cloudfront
Published: 2022-06-01 12:22:52


## CloudFront Serving compressed files

You can use CloudFront to automatically compress certain types of objects (files) and serve the compressed objects when viewers (web browsers or other clients) support them. Viewers indicate their support for compressed objects with the Accept-Encoding HTTP header. CloudFront can compress objects using the [Gzip](https://www.gnu.org/software/gzip/) and [Brotli](https://github.com/google/brotli) compression formats. When the viewer supports both formats, CloudFront prefers Brotli.

## How to do it in AWS CDK

### Step 1: Create a content bucket

```typescript
// content bucket
const bucket = new s3.Bucket(this, 'demo-bucket', {
  publicReadAccess: false, // no public access, user must access via cloudfront
  blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,

  /**
   * The default removal policy is RETAIN, which means that cdk destroy will not attempt to delete
   * the new bucket, and it will remain in your account until manually deleted. By setting the policy to
   * DESTROY, cdk destroy will attempt to delete the bucket, but will error if the bucket is not empty.
   */
  removalPolicy: RemovalPolicy.DESTROY, // NOT recommended for production code

  /**
   * For sample purposes only, if you create an S3 bucket then populate it, stack destruction fails.  This
   * setting will enable full cleanup of the demo.
   */
  autoDeleteObjects: true, // NOT recommended for production code
})
```

### Step 2: Create a cloudfront OAI (origin access identity)

```typescript
// cloudfront OAI (origin access identity)
const cloudfrontOAI = new cloudfront.OriginAccessIdentity(this, 'my-oai', {
  comment: 'demo-bucket origin access identity',
})

// assign get object permission to cloudfront OAI
bucket.addToResourcePolicy(
  new iam.PolicyStatement({
    actions: ['s3:GetObject'],
    resources: [bucket.arnForObjects('*')],
    principals: [
      new iam.CanonicalUserPrincipal(cloudfrontOAI.cloudFrontOriginAccessIdentityS3CanonicalUserId),
    ],
  })
)
```

### Step 3: Create a cloudfront distribution base on the content bucket and OAI

```typescript
const distribution = new cloudfront.Distribution(this, 'my-distribution', {
  comment: 'demo-bucket distribution',
  defaultBehavior: {
    origin: new origins.S3Origin(bucket, {
      // Restrict viewer access, viewers must use CloudFront signed URLs or signed cookies to access your content.
      originAccessIdentity: cloudfrontOAI,
    }),
    // Serving compressed files
    compress: true,
    // Allowed GET HEAD and OPTIONS requests
    allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
    // redirects from HTTP to HTTPS, using a CloudFront distribution,
    viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
  },
})
```

> **The code for this article is available on [GitHub](https://github.com/buithaibinh/cdk-cloudfront-s3-compressed)**

## Testing

### Deploy stack
```bash
yarn deploy
```
Wait for the stack to be created. After the stack is created, upload some files to the bucket. Note [File types that CloudFront compresses](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html)

You can try to upload file `data/site.xml` then access it via CloudFront.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tyolin2kxw6ae732z2a.png)
 
![serving compressed]](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6vrodd6lfgru1346xtj2.png)

That all, you can download sample source code from my git.

> [cdk-cloudfront-s3-compressed](https://github.com/buithaibinh/cdk-cloudfront-s3-compressed)

### Clean up
Don't forget to delete the stack to avoid leaving resources in your account.

```bash
npx cdk destroy
```

Thanks for reading! I hope you find this article useful. If you have any questions, please feel free to leave a comment.