AWS LambdaでS3更新時にCloudFrontのInvalidationを実施する

 Lambda IAM S3 CloudFront AWS-SDK JavaScript CloudFormation
2014.12.05

AWS Lambda、夢が広がりますね!
今日は社内の(そしておそらく世間一般にも)ニーズの高い
CloudFrontのInvalidation自動化を実装してみます。

 
私はクラウドデザインパターンに疎いのですが、s3Invalidationパターンとか命名できそう。
 

0. このLambdaが役に立つのはどんなとき?

S3をオリジンとしたCloudFrontディストリビューションが少なくとも一つあり、
S3のファイルを更新した同時刻にそのディストリビューション上のキャッシュが
Invalidateされるのが望ましいケース。
 

1. IAMロールの作成

Lambdaを動かすには2つのAssumeRoleが必要です。
今回はS3のイベント通知がトリガになるケースなので
公式ドキュメントでいうexecutionroleと、invocationroleが必要になります。
 
加えてInvalidationを行うために、CloudFrontディストリビューションのリストアップ
Invalidation生成の権限もexecutionroleのポリシーに付与する必要があります。
・・という最小構成をCloudFormationテンプレートに用意しました。
 
CloudFormationでRoleを作成する

 
(特定のバケットのみの挙動をLambdaに許可したい場合は、CloudFormationの実行時引数に
 バケット名を、どのバケットでも使えるようにする場合は * のままご利用ください)

 

2. Lambdaのzipパッケージを作る

実際にLambdaとして動作させるコードは、これだけです。
 

ローカルの作業フォルダに、index.jsとして保存してください。
非同期処理の結果をまとめて表示したいがためにdeferredを使っており
そのためにちょっと複雑っぽく見えなくもですが・・まあ簡単ですね!
 
さてこれをLambdaへアップロードするためには
AWS-SDK以外に必要なパッケージをzipにまとめる必要があるので、
以下のようにリソースをzipしちゃいます。

$ cd 作業フォルダへ
$ npm install q
$ zip -r s3-invalidation.zip index.js node_modules

 

3. コンソールからLambdaをセットアップ

コンソールを開きます。 新規作成画面へ進みましょう、Get Started Now!


2.で作ったzipファイルをアップロードします。
またこの画面にあるRole nameは、executionroleのことです。
右のSelect Roleから、1.で作成したexecutionroleと、Policyを選択します。

また、この処理は環境によっては3秒だとちょっと足りないかもしれません。
2つ上の画像のほうになりますが、Timeout値も必要に応じて変更してください。
設定できたら、Create Lambda function!
 

設定はあと少しです。
上図の、Configure event sourceから、イベント通知を行うS3バケットと、
functionをinvokeするためのロール、invocationroleを割当てます。

バケットを選び、先ほどと同じような形式ですが、invocationroleも指定してあげます。
 
ただちなみにここまできて、ひとつ残念なお知らせです。
東京リージョンで作ったS3では動きません・・
はやく対応してLambda…

完成しました!
 
指定したS3バケットに何かしらのファイルをアップロードしてみて、
それをオリジンにしたCloudFrontディストリビューションで
Invalidationが発生したら成功です!!