AWS
S3
lambda

S3にファイルをアップロードしたときに自動的にCache-Controlを設定する

はじめに

ふとPage Speed Insightを眺めていたら、ブラウザキャッシュが効いてないファイルが・・・ :thinking:
そういえば、S3に置いてるファイルってCache-Control設定されてないやん!:open_mouth:
ということで、AWS Lambdaを使って、S3にアップロードされたときに自動的にCache-Controlを設定する仕組みを作っていきます :muscle:

Lambdaを作成する

まずは要のLambda functionを作っていきます。

一から作るよりもテンプレートを使ったほうが手っ取り早いので、

関数の作成 > 設計図 > s3-get-object を選択して「設定」をポチります。

適当な関数名をつけて、ロールもテンプレートから新しく作成しちゃいましょう。
(このロールのままだと権限が不足してるのであとで編集していきます :point_up:

スクリーンショット 2018-10-11 15.54.32.png

S3のイベントタイプは「PUT」を選択し、「関数の作成」をポチります。

スクリーンショット_2018-10-11_15_47_19.png

するとこんな感じで関数ができあがります。
スクリーンショット 2018-10-11 16.35.42.png

テンプレートの関数を編集して、Cache-Controlを付与するように書き換えます。
(今回はmax-age=86400にしました)

console.log('Loading function');

const aws = require('aws-sdk');

const s3 = new aws.S3({ apiVersion: '2006-03-01' });


exports.handler = async (event, context) => {

    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    console.log('Bucket: ', bucket);
    console.log('Key: ', key);

    try {
        const data = await s3.getObject({Bucket: bucket, Key: key}).promise();

        const contentType = data.ContentType ? data.ContentType : 'application/octet-stream';
        const params = {
            Bucket: bucket,
            CopySource: `${bucket}/${key}`,
            Key: key,
            ContentType: contentType,
            CacheControl: "max-age=86400",
            MetadataDirective: "REPLACE"
        };

        const newData = await s3.copyObject(params).promise();        

        console.log('success!');
    } catch (err) {
        console.log(err);
        throw new Error(err.message);
    }
};

いったんここで「保存」をポチっておきます。 :sleeping:

ロールを編集する

テンプレートから作成したロールのままだとS3の読み込み権限しかないので、書き込み権限を追加します。

IAM > ロール に移動し、作成したロール(今回だとlambdaS3Role)のS3ポリシーに書き込み権限を追加します。

VisualEditorでポチポチ設定できます。お手軽〜 :smile:
スクリーンショット 2018-10-11 16.09.08.png

結果、S3に関するポリシーにs3:PutObjectが追加されました :point_down:

スクリーンショット_2018-10-11_16_10_16.png

動作確認する

では、Lambdaもロールも完成したので、動作確認しましょう。

実際に画像をUPLOADしてみると、Cache-Controlが設定されました :tada:
スクリーンショット_2018-10-11_16_12_17.png

めでたしめでたし :hugging:

参考