AWS Cloudfront cache invalidation with Paws

综合编程 2017-04-03 阅读原文

In Deploy a static website with Paws , I developed a simple script to upload files to AWS S3, using Paws . In this article I’ll describe a script to invalidate CloudFront caches: this can be used to force CloudFront to re-cache files which have changed on S3.

AWS CloudFront

CloudFront is Amazon’s Content Delivery Network service. It’s used to cache local versions of files so that they can be delivered to requests faster; for example if you used S3 to host your website in Amazon’s US East region, files on the website might load faster for East Coast customers than those on the West Coast. With a CDN like CloudFront however, copies of the website files can be saved all over the World, so that visitor’s browsers fetch the website files from closer geographic locations, improving the website speed.

When cached website files are updated on S3, they need to be invalidated from the CloudFront cache. This forces CloudFront to fetch fresh copies of invalidated files.

The code

Using CloudFront with Paws is pretty easy. For cache invalidation all you really need is a CloudFront distribution id, and a list of files to be invalidated. This is the script:

#!/usr/bin/env perl
use strict;
use warnings;
use Paws;
use Getopt::Long 'GetOptions';
use Time::HiRes 'gettimeofday';

GetOptions(
  'distribution-id=s' => my $DISTRIBUTION_ID,
  'keys=s'            => my @KEYS,
  'region=s'          => my $REGION,
) or die 'unrecognized arguments';

die '--distribution-id and --region are required'
  unless $DISTRIBUTION_ID && $REGION;

# don't block on empty STDIN
STDIN->blocking(0);
@KEYS = map { chomp;"/$_" } @KEYS, ;
die 'no objects to invalidate!' unless @KEYS;
printf "Invalidating cached keys: %sn", join ', ', @KEYS;

my $cfront = Paws->service('CloudFront', region => $REGION);
my $uid    = join '-', gettimeofday();

$cfront->CreateInvalidation(
  DistributionId    => $DISTRIBUTION_ID,
  InvalidationBatch => {
      CallerReference => $uid,
      Paths           => {
        Quantity => scalar @KEYS,
        Items    => @KEYS,
      }
  }
);

As before, I use Getopt::Long to process the command line options. The script requires a CloudFront distribution id and an AWS region string. The --keys switch is optional as the script also reads keys from STDIN . This snippet is curious:

# don't block on empty STDIN
STDIN->blocking(0);
@KEYS = map { chomp;"/$_" } @KEYS, ;

It sets the STDIN filehandle to non-blocking mode. That way, if STDIN is empty when the script tries to read from it, it won’t block. On the next line, map is used to prepend a slash to every key. This is required by CloudFront.

The script then creates a Paws CloudFront object, and the Time::HiRes gettimeofday function is used to calculate a cheap unique id (it returns the current epoch seconds and microseconds).

my $cfront = Paws->service('CloudFront', region => $REGION);
my $uid    = join '-', gettimeofday();

Finally, the script calls the CreateInvalidation method to send the data to AWS CloudFront:

$cfront->CreateInvalidation(
  DistributionId    => $DISTRIBUTION_ID,
  InvalidationBatch => {
      CallerReference => $uid,
      Paths           => {
        Quantity => scalar @KEYS,
        Items    => @KEYS,
      }
  }
);

Combining tools

The s3-upload script prints the keys it updated on STDOUT, and cf-invalid can read keys from STDIN. This makes for convenient chaining:

./s3-upload --files static --bucket example.com --region us-east-1 
| ./cf-invalid --distribution-id e9d4922bd9120 --region us-east-1

And because the scripts use Getopt::Long, the option names can be shortened:

./s3-upload -f static -b example.com -r us-east-1 | ./cf-invalid -d e9d4922bd9120 -r us-east-1

Alternatively, keys (filenames) can be specified as arguments:

./cf-invalid -d e9d4922bd9120 -r us-east-1 -k index.html -k about.html -k contact.html

Both scripts are available on Github .

perltricks

责编内容by:perltricks阅读原文】。感谢您的支持!

您可能感兴趣的

Introducing Custom Domains (Preview) with Auth0 Authenticating with a provider through a central authorization server provides ...
RouterOS 升级服务器IP RouterOS的升级服务器用的是Amazon CloudFront的CDN。在国外用效果很好,然而到了中国,效果就只能呵呵了。无法检测升级,下载更新包缓慢是常...
My first portfolio with React and AWS Hi dev.to! So, I built my first portfolio and thought about documenting the proc...
Cloudfront劫持技术分析与介绍 近期,我一直在研究CloudFront域名劫持相关的问题。虽然这并不是一种新出现的安全问题,但其重要性显而易见: 1. CloudFro...
aws_public_ips, a tool to fetch all public IPs tie... aws_public_ips https://rubygems.org/gems/aws_public_ips https://travi...