Skip to content

Instantly share code, notes, and snippets.

@hungryblank
Last active August 29, 2015 14:25
Show Gist options
  • Save hungryblank/2b0cc3755e00eef3089d to your computer and use it in GitHub Desktop.
Save hungryblank/2b0cc3755e00eef3089d to your computer and use it in GitHub Desktop.
Invalidate CloudFront cache for static websites hosted on S3
{
"Records":[
{
"eventVersion":"2.0",
"eventSource":"aws:s3",
"awsRegion":"us-west-2",
"eventTime":"1970-01-01T00:00:00.000Z",
"eventName":"ObjectCreated:Put",
"userIdentity":{
"principalId":"AIDAJDPLRKLG7UEXAMPLE"
},
"requestParameters":{
"sourceIPAddress":"127.0.0.1"
},
"responseElements":{
"x-amz-request-id":"C3D13FE58DE4C810",
"x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
},
"s3":{
"s3SchemaVersion":"1.0",
"configurationId":"testConfigRule",
"bucket":{
"name":"sourcebucket",
"ownerIdentity":{
"principalId":"A3NL1KOZZKExample"
},
"arn":"arn:aws:s3:::sourcebucket"
},
"object":{
"key":"HappyFace.jpg",
"size":1024,
"eTag":"d41d8cd98f00b204e9800998ecf8427e",
"versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko"
}
}
}
]
}
'use strict';
var Promise = require('bluebird');
var _ = require('lodash');
var Invalidation = require('./lib/Invalidation');
var AWS = require('aws-sdk');
var handle = function (event, context) {
var cloudfront = new AWS.CloudFront();
var s3 = new AWS.S3();
var s3Config = {
Bucket: event.Records[0].s3.bucket.name,
Key: '_my_cloudfront_config.json'
};
s3.getObject(s3Config, function (err, configObject) {
if (err) {
throw err;
} else {
var config = JSON.parse(configObject.Body.toString('utf8'));
console.log(config);
var invalidationPromises = _.map(event.Records, function (record) {
var invalidation = new Invalidation(config, record);
return invalidation.create(cloudfront);
});
Promise.all(invalidationPromises).then(function () {
context.done();
});
}
});
};
module.exports.handle = handle;
'use strict';
var crypto = require('crypto');
var path = require('path');
var Promise = require('bluebird');
var Invalidation = function (config, s3EventRecord) {
this.record = s3EventRecord;
this.config = config;
this.resolver = Promise.pending();
};
Invalidation.prototype.params = function () {
var refHash = crypto.createHash('md5');
var s3Object = this.record.s3.object;
var reference = s3Object.key + s3Object.eTag;
var paths = this.paths();
refHash.update(reference);
var invalidationParams = {
DistributionId: this.config.distributionId,
InvalidationBatch: {
CallerReference: refHash.digest('hex'),
Paths: {
Quantity: paths.length,
Items: paths
}
}
};
console.log(invalidationParams.InvalidationBatch.Paths);
return invalidationParams;
};
Invalidation.prototype.paths = function () {
var s3ObjectKey = this.record.s3.object.key;
var dirname = path.dirname(s3ObjectKey);
if (path.basename(s3ObjectKey) === 'index.html') {
if (dirname === '.') {
dirname = '';
}
return [
'/' + s3ObjectKey,
path.normalize('/' + dirname + '/'),
'/' + dirname
];
} else {
return ['/' + s3ObjectKey];
}
};
Invalidation.prototype.create = function (cloudFrontDriver) {
var resolver = this.resolver;
cloudFrontDriver.createInvalidation(this.params(), function (err, data) {
if (err) {
resolver.reject(err);
} else {
resolver.fulfill(data);
}
});
return resolver.promise;
};
module.exports = Invalidation;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment