ここで、テストのためCloudFront のエンドポイントにcurlを打ち込みましたが、“403 ERROR”となりました。原因は、デフォルトのキャッシュ動作の設定でCache Based on Selected Request Headersに”All” を設定したことに起因しておりました。(前述の説明で、黄色ハッチングの箇所です)
API Gateway はHTTPS プロトコルでアクセスする必要があり、かつカスタムドメインを設定しております。Cache Based on Selected Request Headersを”All” にした場合、CloudFront はオリジンに”Host”ヘッダを転送するため、API Gatewayのカスタムドメインに設定した証明書とヘッダが一致せず、エラーを招きます。
niikawa@niikawa1:~$ curl https://niikawa-front.example.com
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Bad request.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: vCM1si1-KjhQRnfFbLEMBGR2BRP-wvE3fmpFOYIxKaWYM6UVFqVQeQ==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>
CloudFront + APIGateway 構成の勘所はココ
それでは、Cache Based on Selected Request Headersには何を設定すれば良かったのでしょうか? 今回、オリジンはAPI であり静的コンテンツではないため、ヘッダのキャッシュは不要、Cache Based on Selected Request Headersは”All” と判断しました。しかし、オリジンに”Host”ヘッダが転送されたことが逆効果となりました。
下記の通り、Cache Based on Selected Request HeadersにはAllではなく、Whitelistを選択します。かつ、Whitelist Headers にオリジンに転送が必要なヘッダを個別に指定します。(今回は、Accept, Accept-Encoding, Accept-Languageを指定)