Amazon CloudFront在&#s; aws s3 sync'之后缓存失效。 CLI更新s3存储桶内容

时间:2015-04-06 21:18:06

标签: ruby-on-rails-3 amazon-web-services amazon-s3 amazon-cloudfront aws-cli

我有一个rails应用程序,使用aws cli来同步内容和配置我的s3存储桶,如下所示:

aws s3 sync --acl 'public-read' #{some_path} s3://#{bucket_path}

现在我正在寻找一种简单的方法来标记刚刚同步更新的所有内容,以便为CloudFront标记为无效或过期。

我想知道是否有某种方法可以使用aws cli提供的-cache-control标志来实现此目的。因此,不要使CouldFont无效,只需将文件标记为已过期,因此CloudFront将被强制从存储桶中获取新数据。

我知道CloudFront POST API将文件标记为无效,但这意味着我将检测上次同步中的更改,然后进行API调用。我可能有从1000s到1文件同步的任何地方。不是一个很好的前景。但是,如果我必须走这条路线,我将如何在不解析s3 sync的控制台输出的情况下检测更改。

还是其他任何想法?

谢谢!

3 个答案:

答案 0 :(得分:4)

使用全新AWS Lambda怎么样?基本上,只要在AWS中触发事件,它就会执行自定义代码(在您的情况下,文件在S3中同步)。

每当您同步文件时,您都会收到类似于以下内容的事件:

{
    "Records": [
        {
            "eventVersion": "2.0",
            // ...
            "s3": 
            {
                "s3SchemaVersion": "1.0",
                // ...
                "object": 
                {
                    "key": "hello.txt",
                    "size": 4,
                    "eTag": "1234"
                }
            }
        }
    ]
}

因此,您可以检查已更改的文件的名称,并在CloudFront中使其无效。每个已更改的文件都会收到一个事件。

我创建了一个脚本,只要在S3中发生更新,就会使CloudFront中的路径无效,如果您决定使用此方法,这可能是一个很好的起点。它是用JavaScript(Node.js)编写的,因为它是Lambda使用的语言。

var aws = require('aws-sdk'),
    s3 = new aws.S3({apiVersion: '2006-03-01'}),
    cloudfront = new aws.CloudFront();

exports.handler = function(event, context) {
    var filePath = '/' + event.Records[0].s3.object.key,
        invalidateParams = {
            DistributionId: '1234',
            InvalidationBatch: {
                CallerReference: '1',
                Paths: {
                    Quantity: 1,
                    Items: [filePath]
                }
            }
        };

    console.log('Invalidating file ' + filePath);

    cloudfront.createInvalidation(invalidateParams, function(err, data) {
        if (err) {
            console.log(err, err.stack);  // an error occurred
        } else {
            console.log(data);  // successful response
        }
    });

    context.done(null,'');
};

有关详情,请查看Lambda'sCloudFront's API文档。

但请注意,该服务仍处于预览状态,可能会发生变化。

答案 1 :(得分:3)

您无法使用awi提供的--cache-control选项使CloudFront中的文件无效。 --cache-control选项直接映射到Cache-Control header,CloudFront会将标题与文件一起缓存,因此如果您更改标题,则还必须使其无效,以告知CloudFront提取已更改的标题。

如果要使用aws cli,则必须解析sync命令的输出,然后使用aws cloudfront cli。

或者,您可以使用s3tools.org中的s3cmd。此程序提供--cf-invalidate选项以使CloudFront中上传的字段无效,并且sync命令将目录树同步到S3。

s3cmd sync --cf-invalidate <local path> s3://<bucket name>

阅读s3cmd usage page了解更多详情。

答案 2 :(得分:1)

AWS CLI工具可以output JSON。收集JSON结果,然后根据帖子中包含的链接提交失效请求。为了使它变得非常简单,您可以使用像CloudFront Invalidator这样的宝石,它将获取无效路径列表。