Skip to content

Commit

Permalink
chore: add CloudFront cache invalidation for Static Site services (#5035
Browse files Browse the repository at this point in the history
)

One of the ways in which CloudFront reduces latency is by caching objects at edge locations, reducing the number of requests that users’ origin servers must respond to directly. For Copilot-managed Static Site services, this caching behavior has the unfortunate side effect of redeployments using cached— and out-of-date— versions of source files. By default, files expire after 24 hours.

We want users to benefit from edge caches, so we don’t want to [manage cache expiration](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html) by changing TTL values or the [cache policy](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html). Instead, we can allow the caching but [invalidate the cache](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html) each time the Static Site service is redeployed, after (updated) files are uploaded. This way, the updated files are served from the origin server rather than the outdated cached files.

We opted to invalidate all files (`/*`) for simplicity, efficiency, and [cost-savings](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#PayingForInvalidation). If, in the future, customers request the ability to exclude files from invalidation, we can consider adding that config to the workload manifest.

Resolves: #5024.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the Apache 2.0 License.
  • Loading branch information
huanjani committed Jul 7, 2023
1 parent e1e5e52 commit 11e2a04
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ Resources:
Next: CopyFiles
CopyFiles:
Type: Map
End: true
Next: InvalidateCache
ItemsPath: $.GetMappingFile.files
ItemProcessor:
ProcessorConfig:
Expand Down Expand Up @@ -251,6 +251,18 @@ Resources:
# Required otherwise ContentType won't be applied.
# See https://github.com/aws/aws-sdk-js/issues/1092 for more.
MetadataDirective: 'REPLACE'
InvalidateCache:
Type: Task
End: true
Resource: arn:aws:states:::aws-sdk:cloudfront:createInvalidation
Parameters:
DistributionId: !Ref CloudFrontDistribution
InvalidationBatch:
CallerReference.$: States.UUID()
Paths:
Quantity: 1
Items:
- "/*"

CopyAssetsStateMachineRole:
Metadata:
Expand Down Expand Up @@ -283,6 +295,37 @@ Resources:
Action:
- s3:PutObject
Resource: !Sub arn:aws:s3:::${Bucket}/*
- PolicyName: CacheInvalidation
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- acm:ListCertificates
- cloudfront:GetDistribution
- cloudfront:GetStreamingDistribution
- cloudfront:GetDistributionConfig
- cloudfront:ListDistributions
- cloudfront:ListCloudFrontOriginAccessIdentities
- cloudfront:CreateInvalidation
- cloudfront:GetInvalidation
- cloudfront:ListInvalidations
- elasticloadbalancing:DescribeLoadBalancers
- iam:ListServerCertificates
- sns:ListSubscriptionsByTopic
- sns:ListTopics
- waf:GetWebACL
- waf:ListWebACLs
Resource: "*"
Condition:
StringEquals:
'aws:ResourceTag/copilot-application': !Sub '${AppName}'
'aws:ResourceTag/copilot-environment': !Sub '${EnvName}'
'aws:ResourceTag/copilot-service': !Sub '${WorkloadName}'
- Effect: Allow
Action:
- s3:ListAllMyBuckets
Resource: arn:aws:s3:::*

EnvManagerS3Access:
Metadata:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ Resources:
Next: CopyFiles
CopyFiles:
Type: Map
End: true
Next: InvalidateCache
ItemsPath: $.GetMappingFile.files
ItemProcessor:
ProcessorConfig:
Expand Down Expand Up @@ -283,6 +283,18 @@ Resources:
# Required otherwise ContentType won't be applied.
# See https://github.com/aws/aws-sdk-js/issues/1092 for more.
MetadataDirective: "REPLACE"
InvalidateCache:
Type: Task
End: true
Resource: arn:aws:states:::aws-sdk:cloudfront:createInvalidation
Parameters:
DistributionId: !Ref CloudFrontDistribution
InvalidationBatch:
CallerReference.$: States.UUID()
Paths:
Quantity: 1
Items:
- "/*"

CopyAssetsStateMachineRole:
Metadata:
Expand Down Expand Up @@ -318,6 +330,38 @@ Resources:
Action:
- s3:PutObject
Resource: !Sub arn:aws:s3:::${Bucket}/*
- PolicyName: CacheInvalidation
# https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/security_iam_id-based-policy-examples.html
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- acm:ListCertificates
- cloudfront:GetDistribution
- cloudfront:GetStreamingDistribution
- cloudfront:GetDistributionConfig
- cloudfront:ListDistributions
- cloudfront:ListCloudFrontOriginAccessIdentities
- cloudfront:CreateInvalidation
- cloudfront:GetInvalidation
- cloudfront:ListInvalidations
- elasticloadbalancing:DescribeLoadBalancers
- iam:ListServerCertificates
- sns:ListSubscriptionsByTopic
- sns:ListTopics
- waf:GetWebACL
- waf:ListWebACLs
Resource: "*"
Condition:
StringEquals:
'aws:ResourceTag/copilot-application': !Sub '${AppName}'
'aws:ResourceTag/copilot-environment': !Sub '${EnvName}'
'aws:ResourceTag/copilot-service': !Sub '${WorkloadName}'
- Effect: Allow
Action:
- s3:ListAllMyBuckets
Resource: arn:aws:s3:::*

EnvManagerS3Access:
Metadata:
Expand Down

0 comments on commit 11e2a04

Please sign in to comment.