#1. はじめに
「Cloud Cloud うるせータイトルだな」と思った方もいらっしゃると思いますが、僕もそう思います。以前CloudFrontFunctionsについて紹介した記事を書きましたが、CloudFormationを用いてもCloudFrontFunctionsをデプロイできるという情報を入手したため、今回記事にしてみました。ちなみにCloudFormationって何? AWS-SAM-CLIって何?って人はこちらの記事が参考になるかもしれません。
とりあえず手頃な例として、CloudFrontFunctionを用いたIP制限の例をご紹介したいと思います。
#2. テンプレートの書き方
CloudFormationのテンプレートに慣れている方はなんとなくイメージがつくと思いますが、以下のような流れでcloudfrontのテンプレートに追記していきます。
1、ResourcesにCloudFrontFunctionsの記述を追加
2、CloudFrontDistributionのプロパティの中に、CloudFrontFunctionsの設定を追加
###ResourcesにCloudFrontFunctionsの記述を追加
CloudFrontFunctionsを追加する場合はResourcesの欄に以下のように記述します。
TestFunctions:
Type: AWS::CloudFront::Function
Properties:
Name: <関数名>
AutoPublish: true
FunctionConfig:
Comment: <コメント>
Runtime: cloudfront-js-1.0
FunctionCode: |
<任意のコード>
####Name
CloudFrontFcuntionの名前。注意として、CloudFormationではストック名、リソース名、関数名の三つでCloudFrontFunctionが管理されます。そのため、すでにCloudFormationでデプロイ済の関数名を変更しようとした時、Nameの値をいきなり変更すると「TestFunctionsと紐づく関数名が違います。」みたいなエラーが吐き出されます。ほんとなんでこんな仕様なんでしょうかね。。。?
そういうエラーに悩まされたら、一旦ストックごとリソースと関数を消してしまいましょう。
####AutoPublish
デプロイ時に関数を自動で発行するかどうかのパラメーターになります。こちらをtrueにしておかないと、CloudFrontを同じテンプレート上で作成し紐づけた際に「TestFunctionsがデプロイされていないため、関数を設定できません。」みたいなエラーが吐き出されます。CloudFrontを同じテンプレートで管理する方はtrueで問題ないと思います。
####FunctionConfig
コメントとランタイムを指定できます。ちなみに、こちらの情報は公式HPでは必須となっていませんが、記述しておかないとエラーになります。何か書いておきましょう。現状ランタイムには「cloudfront-js-1.0」しか値が入りません。
####FunctionCode
ここに関数の中身を書きます。これに関しては「3.IP制限のやり方」にて記述します。
###CloudFrontDistributionのプロパティの中に、CloudFrontFunctionsの設定を追加
こちらは大した手間ではありません。リソースで記述したディストリビューションの中で、
Properties → DistributionConfig → DefaultCacheBehavior(もしくは CacheBehaviors) → FunctionAssociations
の中で、イベントタイプとCloudFrontFcuntionのARNを記述します。
TestDistribution:
Type: "AWS::CloudFront::Distribution"
Properties:
DistributionConfig:
DefaultCacheBehavior:
- FunctionAssociations:
- EventType: viewer-request
FunctionARN: !GetAtt TestFunctions.FunctionMetadata.FunctionARN
どこのパスに関数を設定するかでDefaultCacheBehaviorとするかCacheBehaviors決定しましょう。今回は簡単なIP制限になりますのでDefaultCacheBehaviorに設定します。
イベントタイプは任意の値を入力してください。viewer-request か viewer-response の値を入力可能です。
#3.IP制限のやり方
FunctionCodeの中身を利用してIP制限を行っていきます。
CloudFrontFcuntionでは、関数を実行する際にeventとして様々な情報を受け取ります。IPアドレスだけでなくヘッダー、クエリ、クッキーの情報も含まれます。受け取ったeventの中で、event.viewer.ipという箇所にIPアドレスが含まれているため、今回はそれを用いて制限をします。
以下コードです。
FunctionCode: |
function handler(event) {
var request = event.request;
var viewerIP = event.viewer.ip;
if(viewerIP != '1.1.1.1'){
var indexPath = `/error/index.html`;
request.uri = indexPath;
}
return request
}
これにて任意のIPアドレス以外が入ってきたときにerror/index.htmlに飛ばすことができるようになりました。'1.1.1.1'には任意のIPアドレスを入力してください。
#4.終わりに
IP制限等の簡単な処理の場合、WAFやLambdaEdge等が選択肢に入ってくると思いますが、CloudFrontFcuntionがリリースされたことで、気軽にIP制限を行えるようになりました。ただ、署名付きクッキーによるカスタムエラーレスポンスを同時に利用すると(なぜかはわかっていませんが)エラーが発生してしまうので注意が必要です。なぜ、エラーが発生するのかわかったらまた加筆したいと思います。
ご精読ありがとうございました。