はじめに
ふとPage Speed Insightを眺めていたら、ブラウザキャッシュが効いてないファイルが・・・
そういえば、S3に置いてるファイルってCache-Control
設定されてないやん!
ということで、AWS Lambdaを使って、S3にアップロードされたときに自動的にCache-Control
を設定する仕組みを作っていきます
Lambdaを作成する
まずは要のLambda functionを作っていきます。
一から作るよりもテンプレートを使ったほうが手っ取り早いので、
関数の作成 > 設計図 > s3-get-object
を選択して「設定」をポチります。
適当な関数名をつけて、ロールもテンプレートから新しく作成しちゃいましょう。
(このロールのままだと権限が不足してるのであとで編集していきます )
S3のイベントタイプは「PUT」を選択し、「関数の作成」をポチります。
テンプレートの関数を編集して、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);
}
};
いったんここで「保存」をポチっておきます。
ロールを編集する
テンプレートから作成したロールのままだとS3の読み込み権限しかないので、書き込み権限を追加します。
IAM > ロール に移動し、作成したロール(今回だとlambdaS3Role
)のS3ポリシーに書き込み権限を追加します。
結果、S3に関するポリシーにs3:PutObject
が追加されました
動作確認する
では、Lambdaもロールも完成したので、動作確認しましょう。
実際に画像をUPLOADしてみると、Cache-Control
が設定されました
めでたしめでたし