[アップデート]CloudFront Functions で VPC オリジンを動的に切り替えられるようになりました
お疲れさまです。とーちです。
CloudFront Functions で VPC オリジンを動的に切り替えられるようになったというアップデートがありました。こちらのアップデートを実際に試してみたので、今回はその内容をお届けします。
CloudFront Functions のオリジン変更機能について
私は知らなかったのですが、上記の What's New によると、もともと 2024/11 に CloudFront Functions にオリジン変更機能が追加されていたようです。
これはどういう機能かというと、CloudFront Functions 内でオリジンを動的に変更できるというもので、サンプルコードの例でいくと、リクエストの CloudFront-Viewer-Country
ヘッダからユーザーの国を判別して、その国に近い位置にある S3 バケットにオリジンを変更したうえでアクセスさせるといったようなことが出来たりします。
今回のアップデートは、この CloudFront Functions のオリジン変更機能が強化され、通常のオリジンだけではなく VPC オリジンやオリジングループも CloudFront Functions 内で変更できるようになったというものになります。
なお VPC オリジンやオリジングループについては以下の記事をご参照ください。
やってみた
それではさっそくやってみましょう。
今回は VPC オリジンの切り替えを CloudFront Functions でやってみたいと思います。
VPC オリジンの準備
まずは上記のブログを参考に VPC オリジンから作っていきます。
VPC 内の構成としては上記ブログと同様にシンプルに internal ALB のみを配置し、ALB から固定レスポンスを返す構成にしました。
もう一つの ALB のほうは固定レスポンスとして service2 OK
と返すようにしています。
ALB を作成した後に同一 VPC 内から正常に応答ができるかを一旦確認しました。
[root@ip-172-18-128-194 ~]# curl internal-cff-dev-test1-alb-ecs-***.ap-northeast-1.elb.amazonaws.com
service1 OK[root@ip-172-18-1
[root@ip-172-18-128-194 ~]# curl internal-cff-dev-test2-alb-ecs-***.ap-northeast-1.elb.amazonaws.com
service2 OK[root@ip-172-18-128-194 ~]#
CloudFrontの VPC オリジンの作成
VPC 内に internal ALB が作成出来たので、VPC オリジンを作成します。
今回は HTTP で ALB のリスナーを作成したので、VPC オリジンも HTTP のみで作成しています。上記と同じ VPC オリジンをもう一つの internal ALB の分、作成しました。
CloudFront ディストリビューションの設定
CloudFront のディストリビューションを作成します。以下の設定で作成しました。オリジンに上記で作成した test1
の VPC オリジンを指定している以外はほぼデフォルト設定のまま作成しています。
上記の状態では VPC オリジンはディストリビューションに一つしか設定されていません。そのためもう一つの VPC オリジンを追加します。
なお、ドキュメントを見る限りでは CloudFront Functions で VPC オリジンを切り替えるには予め CloudFront ディストリビューションに VPC オリジンを追加しておく必要がありそうです。
- Helper methods for origin modification - Amazon CloudFront
- updateRequestOrigin() では VPC オリジンは切り替えられないという記述
You can't use the updateRequestOrigin() method to update VPC origins. The request will fail.
- selectRequestOriginById() メソッドで切り替えられるとのことですが、この場合は以下の通り
同じディストリビューションで既に定義されているオリジンのみを受け入れる
とのことThis method only accepts origins that are already defined in the same distribution used when running the function. Origins are referenced by the origin ID, which is the origin name that you defined when setting up the origin.
この状態で CloudFront から internal ALB まで疎通できるかを確認してみます。
> curl https://d1an4ora2o1h1g.cloudfront.net/
service1 OK⏎
うまくいきました。
セキュリティグループに関する注意点
本筋とは少しずれるのですが、実は最初 internal ALB のセキュリティグループは以下のように設定していました。172.18.0.0/16 は VPC の CIDR ブロックです。
この状態で CloudFront 経由で通信したところうまくいきませんでした。
> curl https://d1an4ora2o1h1g.cloudfront.net/
<!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>504 Gateway Timeout ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
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) HTTP3 Server
Request ID: XUN0OVKLnwGNadyRXQkhMSCbrgUDniWeIz31WcEzK2MbE-qhaJ4saQ==
</PRE>
<ADDRESS>
</ADDRESS>
</BODY></HTML>⏎
CloudFront が VPC オリジン用に作成した ENI はおそらくこの2つのはずで、プライベート IP は 172.18.0.0/16 の範囲内のはずなのですが、なぜか通信できませんでした。ALB のセキュリティグループを 0.0.0.0/0 にしたところ、通信できるようになったので、送信元 IP が私の想定とは違うようです。このあたり時間があれば調べてみようと思います。
CloudFront Functions による VPC オリジンの切り替え
さてでは今回の本筋である CloudFront Functions による VPC オリジンの切り替えを試したいと思います。
CloudFront Functions の作成
まずは CloudFront Functions を作成します。オリジン変更のモジュールを使用するには cloudfront-js-2.0
を選択する必要がありますのでご注意を。
以下のようなコードを設定します。とりあえず検証のためのシンプルなコードで、単純に VPC オリジンをビヘイビアで設定されている test1
から test2
に変更しているだけです。なお、selectRequestOriginById
にはディストリビューションに設定したオリジン名を指定する必要があります。ID と書いてあるので VPC オリジンの ID を設定したくなりますが、オリジン名なので注意しましょう。
import cf from 'cloudfront';
function handler(event) {
const request = event.request;
const headers = request.headers;
const vpcOriginName =
"test2";
cf.selectRequestOriginById(vpcOriginName);
return request;
}
CloudFront Functions の関数を発行するのを忘れないようにしましょう。
ビヘイビアの変更
続いて CloudFront ディストリビューションのビヘイビアを変更し、ビューワーリクエストに作成した CloudFront Functions を紐づけます。
切り替え結果の確認
この状態で CloudFront にもう一度アクセスしてみましょう。
> curl https://d1an4ora2o1h1g.cloudfront.net/
service2 OK⏎
おお、ちゃんともう一つの VPC オリジンが表示されましたね!
まとめ
というわけで、CloudFront Functions で VPC オリジンを動的に切り替えられるようになったというアップデートでした。
このアップデートによりリクエスト元の国を判別して、対象の地域に近いリージョンの VPC オリジンにルーティングしたり、各 VPC オリジンに重みづけをしてリクエストを分散するといったようなこともできるようになります。なかなか面白いアップデートではないでしょうか?
以上、とーちでした。