user40991
user40991

Reputation: 173

Amazon CloudFront invalidation API

The images used in our application are rendered from Amazon CloudFront.

When an existing image is modified, it does not reflect the image change immediately since CloudFront take around 24 hours to update.

As a workaround, I'm planning to call CreateInvalidation to reflect the file change immediately.

Is it possible to use this invalidation call without SDK?

Using ColdFusion programming language and does not seem to have SDK for this.

Upvotes: 3

Views: 6212

Answers (3)

Ashan
Ashan

Reputation: 19705

For frequent modifications, I think the best approach is to append a query string to the image url (time stamp or hash value of the object) and configure Cloudfront to forward query strings, which will always return the latest image when query string differs.

For infrequent modifications, apart from SDK, you can use AWS CLI which will also allows to invalidate the cache upon builds, integrating with your CI/CD tools.

E.g

  aws cloudfront create-invalidation --distribution-id S11A16G5KZMEQD \
  --paths /index.html /error.html

Upvotes: 0

John Rotenstein
John Rotenstein

Reputation: 270114

Some alternatives to invalidating an object are:

Upvotes: 1

Victor Leontyev
Victor Leontyev

Reputation: 8736

You can simply make POST request. Example on PHP from Steve Jenkins

<?php
/**
 * Super-simple AWS CloudFront Invalidation Script
 * Modified by Steve Jenkins <steve stevejenkins com> to invalidate a single file via URL.
 * 
 * Steps:
 * 1. Set your AWS Access Key
 * 2. Set your AWS Secret Key
 * 3. Set your CloudFront Distribution ID (or pass one via the URL with &dist)
 * 4. Put cf-invalidate.php in a web accessible and password protected directory
 * 5. Run it via: http://example.com/protected_dir/cf-invalidate.php?filename=FILENAME
 *    or http://example.com/cf-invalidate.php?filename=FILENAME&dist=DISTRIBUTION_ID
 * 
 * The author disclaims copyright to this source code.
 *
 * Details on what's happening here are in the CloudFront docs:
 * http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html
 * 
 */
$onefile = $_GET['filename']; // You must include ?filename=FILENAME in your URL or this won't work
if (!isset($_GET['dist'])) {
        $distribution = 'DISTRIBUTION_ID'; // Your CloudFront Distribution ID, or pass one via &dist=
} else {
        $distribution = $_GET['dist'];
}
$access_key = 'AWS_ACCESS_KEY'; // Your AWS Access Key goes here
$secret_key = 'AWS_SECRET_KEY'; // Your AWS Secret Key goes here
$epoch = date('U');
$xml = <<<EOD
<InvalidationBatch>
    <Path>{$onefile}</Path>
    <CallerReference>{$distribution}{$epoch}</CallerReference>
</InvalidationBatch>
EOD;
/**
 * You probably don't need to change anything below here.
 */
$len = strlen($xml);
$date = gmdate('D, d M Y G:i:s T');
$sig = base64_encode(
    hash_hmac('sha1', $date, $secret_key, true)
);
$msg = "POST /2010-11-01/distribution/{$distribution}/invalidation HTTP/1.0\r\n";
$msg .= "Host: cloudfront.amazonaws.com\r\n";
$msg .= "Date: {$date}\r\n";
$msg .= "Content-Type: text/xml; charset=UTF-8\r\n";
$msg .= "Authorization: AWS {$access_key}:{$sig}\r\n";
$msg .= "Content-Length: {$len}\r\n\r\n";
$msg .= $xml;
$fp = fsockopen('ssl://cloudfront.amazonaws.com', 443, 
    $errno, $errstr, 30
);
if (!$fp) {
    die("Connection failed: {$errno} {$errstr}\n");
}
fwrite($fp, $msg);
$resp = '';
while(! feof($fp)) {
    $resp .= fgets($fp, 1024);
}
fclose($fp);
print '<pre>'.$resp.'</pre>'; // Make the output more readable in your browser

Upvotes: 2

Related Questions