🕶️

CloudFormation で CloudFront の Cache policy がInvalid request

2021/05/16に公開

CDKを使って、前段に CloudFront 背後に API Gateway を配置しようとしています
API Gateway へのアクセス時には、キャッシュを行いたくないため、TTLをゼロとするキャッシュポリシーを作ってみましたが、デプロイに失敗しました

	const cachePolicyForApiGateway = new cloudFront.CachePolicy(this, 'cachePolicyForApiGateway', {
            defaultTtl: cdk.Duration.seconds(0),
            minTtl: cdk.Duration.seconds(0),
            maxTtl: cdk.Duration.seconds(0),
            enableAcceptEncodingGzip: true,
            enableAcceptEncodingBrotli: true,
            headerBehavior: cloudFront.CacheHeaderBehavior.allowList(
                'Authorization',
            ),
        });

ぱっとみ問題は無さそうに見えますが cdk deploy するとポリシー作成のところで

Resource handler returned message: "Invalid request provided: AWS::CloudFront::CachePolicy" (RequestToken: 382afa79-3fd8-9336-4015-xxxxxxxxx, HandlerErrorCode: InvalidRequest)

と返されます

こういうときは、コンソールで同じ設定を作ろうとしてみます
AWSコンソール上でCloudFrontのキャッシュポリシー作成画面でTTLを全てゼロにすると、Cache key contents 以下が非表示となり編集できなくなる

Minimum TTL, Maximum TTL, Default TTL を全てゼロにすると、Cache key contents 以下が非表示になります
ということは、すべてのTTLがゼロの場合は、ほかのオプションを設定してはいけないと判断できそうです
上記のコードから enableAcceptEncodingGzip, enableAcceptEncodingBrotli, headerBehavior の各プロパティを削除します

	const cachePolicyForApiGateway = new cloudFront.CachePolicy(this, 'cachePolicyForApiGateway', {
            defaultTtl: cdk.Duration.seconds(0),
            minTtl: cdk.Duration.seconds(0),
            maxTtl: cdk.Duration.seconds(0),
        });

これで成功しました

よくよく考えてみれば、全てのTTL値をゼロとする場合 CloudFront は「キャッシュしない」という意味になるわけで、「キーに基づいてキャッシュする」という設定は矛盾しています

GZip 及び Brotli をサポートするための enableAcceptEncodingGzip, enableAcceptEncodingBrotli についても Accept-Encoding ヘッダーを追加する設定のため headerBehavior と同じほぼ同じ意味ですね

また、最初に掲出したコードでは Authorization ヘッダーをキーに追加していますが、これは

https://aws.amazon.com/jp/premiumsupport/knowledge-center/api-gateway-cloudfront-distribution/

このページを参考にしていて

API で IAM 認証を有効にした場合、または後で有効にする場合は、許可リストに Authorization リクエストヘッダーを追加する必要があります。[Cache Based on Selected Request Headers] (選択したリクエストヘッダーに基づくキャッシュ) では、[Whitelist] (ホワイトリスト) を選択します。Whitelist Headers (ホワイトリストのヘッダー) で、許可されるヘッダーのリストに Authorization を追加します。

とあったため追加していましたが、このページでは TTL についての言及が無いため (おそらくはデフォルト値を使用しての) キャッシュが有効であるとした上で、認証を行う API の場合に必要な対応のようです
(現時点では認証をまだ用意していない かつ 認証のAPIは別のビヘイビアにしようとしているので、誤解しているかもしれません…ご存じの方は知見をコメントいただけたら)

Discussion