AWSのCloudFront Functionsを使おうとしてハマったこと2つ

わかってしまえばなんということも無いことなので、忘れた時に見返すための覚書として。

ハマったこと1: viewer-XXXはLambda@edgeと併用不可

※現在はAWSのドキュメントに可能な組み合わせ表があります。

Lambda@edgeのviewer-requestまたはviewer-responseをすでに使用しているDistributionの場合、CloudFront Functionsを設定することができません。

無理に設定しようとすると、InvalidLambdaFunctionAssociationエラーが飛んできます。

com.amazonaws.services.cloudfront.model.InvalidLambdaFunctionAssociationException: The CloudFront function arn:aws:cloudfront::0000000:function/ViewerResponseFunction-development:LIVE with a viewer-response event type cannot be used with the Lambda function arn:aws:lambda:us-east-1:00000000:function:lambda-edge-development-vr1:4 with a viewer-request event type. (Service: AmazonCloudFront; Status Code: 400; Error Code: InvalidLambdaFunctionAssociation; Request ID: 123456-ecfe-4343-843a-3532388cce43; Proxy: null)

解決策: viewer-XXXはCloudFront Functions OR Lambda@edgeに統一する

解決策というか、これしかできないというほうが正しいかもしれません。

「外部APIの利用やES記法、npm modulesを使えるが、更新する度にCloudFrontをupdateする必要があるLambda@edge」か「記法に制限があり、外部APIなどを使えない代わりに、Functionを更新(publish)したら全CloudFrontに反映されるCloudFront Functions」かを判断基準にしつつ、コストとの相談になると思います。

ハマったこと2: AWS Lambdaバンドルのaws-sdkが古い

AWS Lambdaには、デフォルトでaws-sdkがバンドルされています。そのためnpm install -S aws-sdkをすることなくAWS APIを利用できます。が、このSDKは常に最新版ではないため、現状CloudFront FunctionsをCloudFront Distributionに設定することができません。

Unexpected key 'FunctionAssociations' found in params.DistributionConfigWithTags.DistributionConfig.DefaultCacheBehavior Full log {"message":"Unexpected key 'FunctionAssociations' found in params.DistributionConfigWithTags.DistributionConfig.DefaultCacheBehavior","code":"UnexpectedParameter","time":"2021-06-30T05:37:23.214Z"}

解決策: aws-sdkは自前でバンドルする

要は対応するバージョンのAWS SDKがあればOKなので、自前でバンドルしましょう。devDependenciesに入れていると、Serverless Frameworkなどが気を利かせてデプロイ対象から外しちゃうことがあります。かならずnpm install -S aws-sdk or yarn add aws-sdkdependenciesにいれましょう。

ちなみに、Lambdaのベストプラクティスにも、「依存関係を完全に制御したい場合は自前で管理してね(意訳)」と書かれています。

最新の機能やセキュリティ更新プログラムを有効にするために、Lambda ではこれらのライブラリを定期的に更新します。この更新に伴って、Lambda 関数の動作が微妙に変わる場合があります。関数で使用する依存関係を完全に制御するには、すべての依存関係をデプロイパッケージでパッケージングします。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/best-practices.html?

Comment