aws / copilot-cli

The AWS Copilot CLI is a tool for developers to build, release and operate production ready containerized applications on AWS App Runner or Amazon ECS on AWS Fargate.
https://aws.github.io/copilot-cli/
Apache License 2.0
3.52k stars 417 forks source link

Configuring Cloudfront distribution for Static Site Service #5158

Closed coding-velociraptor closed 1 year ago

coding-velociraptor commented 1 year ago

Hey Copilot-Team,

thank you for creating this simple CLI tool to reduce complexity of deploying containers to AWS.

We recently adopted the Static Site Service and noticed a few unfortunate defaults, which we would like to configure. In our case, I would like to change the Cloudfront Distribution to use:

Also, I have a folder of hashed file names, which could be cached indefinitely. A Cache-Control header could stop the browser from even making a request if previously accessed.

Is there a way to achieve without breaking out?

Thank you!

coding-velociraptor commented 1 year ago

Update 1: Using CDK overrides

For knowledge sharing, I used copilot svc override to generate the template and make the following modification:

   transformCloudFrontDistribution() {
        const cloudFrontDistribution = this.template.getResource("CloudFrontDistribution") as cf.CfnDistribution;
        cloudFrontDistribution.addPropertyOverride(
            "DistributionConfig.HttpVersion",
            "http2and3"
        );
        cloudFrontDistribution.addPropertyOverride(
            "DistributionConfig.ViewerCertificate.MinimumProtocolVersion",
            "TLSv1.2_2021"
        );
    }
KollaAdithya commented 1 year ago

Hello @coding-velociraptor !

Thanks for sharing the overrides!

In copilot version v1.29 we added cache invalidation that will invalidate any cached files every time upon deployment by default.

Here is a related PR(#5035) and issue (#5024)

Is your requirement to invalidate the cache only on certain folders or files?

coding-velociraptor commented 1 year ago

Hello @KollaAdithya,

Thank you for your fast response. My requirement is to set metadata when uploading static files to S3. I would need control over Cache-Control and Content-Encoding header.

The Content-Encoding is needed bc Cloudfront is inconsistent. It does not encode all files, which is while I would like to do it at rest.

Thank you!

coding-velociraptor commented 1 year ago

To achieve the desired outcome, we run the following command after CD:

aws s3 cp s3://my-bucket/Build/a1dd0e52c3027247e4ca27b3f19f04ca.data.br s3://my-bucket/Build/a1dd0e52c3027247e4ca27b3f19f04ca.data.br \
  --metadata-directive REPLACE --content-encoding br --cache-control 'public,max-age=31536000,immutable'

and it needs another cache invalidation.

Do you have any suggestion to make it part of copilot? Maybe extending the step function?

KollaAdithya commented 1 year ago

Hello @coding-velociraptor !

My teammate @dannyrandall had a wonderful idea using yaml patches ⬇️ that will help you set the ContentEncoding and CacheControl at S3 bucket level for all the files. In this way you do not need to do another cache invalidation.

- op: add
  path: /Resources/CopyAssetsStateMachine/Properties/Definition/States/CopyFiles/ItemProcessor/States/CopyFile/Parameters/CacheControl
  value: "public,max-age=31536000,immutable"
- op: add
  path: /Resources/CopyAssetsStateMachine/Properties/Definition/States/CopyFiles/ItemProcessor/States/CopyFile/Parameters/ContentEncoding
  value: "br"
- op: add
  path: /Resources/CopyAssetsStateMachine/Properties/Definition/States/CopyFiles/ItemProcessor/States/CopyFileWithContentType/Parameters/CacheControl
  value: "public,max-age=31536000,immutable"
- op: add
  path: /Resources/CopyAssetsStateMachine/Properties/Definition/States/CopyFiles/ItemProcessor/States/CopyFileWithContentType/Parameters/ContentEncoding
  value: "br"

Please let us know if this helps!

coding-velociraptor commented 1 year ago

Hey @KollaAdithya!

Thank you for the suggestion! And thank you @dannyrandall for the idea! I was wondering if you can think of an example for applying those headers only to a subset of files? Maybe by regex or folder? We don't want to cache the index.html file of the web application.

Thank you in advance!

huanjani commented 1 year ago

Thanks so much for your feedback, @coding-velociraptor. I've created a new issue (https://github.com/aws/copilot-cli/issues/5193) for the second part of this issue.