/ #cdk #CloudFront 

【Python/CDK】CloudFront Functionsを使ってリダイレクトを実装する

もくじ

こんにちは、最近育児が忙しくて記事かけてない sisii です!(言い訳からスタート 🎃)

最近記事かけてないので、ちょっと文字数減らして1記事のコストを下げて行こうかなとか思ってます。

さて、今回ですが仕事で AWS を使ってリダイレクトを実装する要件があったので備忘録的に書き残しておこうと思います。

AWS を使ったリダイレクト方法は、たぶんいくらでも方法がありますが、今回は CloudFront Functions(以下 cfFunctions)を使って実装してみます。

何がしたいの?

  • cfFunctions を使ってリダイレクトを CDK を使って実装するよ

CloudFront Functions について

詳細は公式を御覧くださいですが、

cloudfront のエッジで動かすことができる関数です。

似てるもので Lambda@Edge があります。それと比べると cfFunctions の方がスループットが大きいのと基本的に速度と料金が安いです。ただしあらゆる面で使いにくいというものになってきます。

メリットも大きいですが、デメリットも大きく、個人的にとくに嫌だなってのが環境変数が使えないところです。この痛みは結構大きくて dev,stg,prod 環境とかで利用しようとすると各々実行ファイルをつくることになり、メンテやらテストやらが面倒になってきます。

あと地味に言語がJavaScriptだけっていうのも、CDK for Python とか typescript とかでデプロイしたときに、リポジトリに複数言語が含まれちゃって気持ち悪いし認知不可が高いなーって気持ちです。

では 作っていきましょう 👻

さて色々言いましたが作って行きましょう!

import aws_cdk as cdk
from aws_cdk import aws_cloudfront as cloudfront
from aws_cdk import aws_cloudfront_origins as origins
from aws_cdk import aws_s3 as s3

app = cdk.App()
stack = cdk.Stack(app, "cdk-url-redirect-stack")

# バケットを作成する
bucket = s3.Bucket(
    stack,
    "DummyBucket",
    block_public_access=s3.BlockPublicAccess.BLOCK_ALL,
    removal_policy=cdk.RemovalPolicy.DESTROY,
)

cf_function = cloudfront.Function(stack, "Function", code=cloudfront.FunctionCode.from_file(file_path="function.js"))

# CloudFrontのディストリビューションを作成する
distribution = cloudfront.Distribution(
    stack,
    "Distribution",
    default_behavior=cloudfront.BehaviorOptions(
        origin=origins.S3Origin(bucket),
        function_associations=[
            cloudfront.FunctionAssociation(
                function=cf_function, event_type=cloudfront.FunctionEventType.VIEWER_REQUEST
            ),
        ],
    ),
    default_root_object="index.html",
)


app.synth()

cfFunctions ですが、オリジンに被せる形に設定する必要があるのでなにかしらオリジンを作成する必要があります。

オリジンにはアクセスしないのでなんでも良いのですが、今回は一番簡単に用意できそうな S3 を使いました。 また S3 の削除ポリシーを更新してスタックと一緒に削除されるようにしています。これはデフォルト設定でデプロイするとスタック削除時にバケットが残って邪魔なのでこの設定にしてます。

続いて cfFunctions 側のコードはこんな感じです。

function handler(event) {
  return {
    statusCode: 302,
    headers: {
      location: { value: "https://blog.i-tale.jp/" },
    },
  };
}

ここで入ってくる event の情報ですがこんなものが含まれています。 リクエストの body は見ることができませんが、header とか URL クエリーパラメーターは取得できるので、結構色々できそうだなーという気がしますね。

動作確認してみる。

こんな感じ ↓ でデプロイします。

$ cdk -a "python app.py" deploy

AWS の CloudFront のコンソールで作成された URL にアクセスしてみます。

今回はhttps://drlav1duxuz3e.cloudfront.netこんな感じになりました。(記事公開するときには、この URL は削除されているはずです 🙇‍♂)

curl コマンドをつかって ↓ な感じで確認してみます。

$ curl -i https://drlav1duxuz3e.cloudfront.net
HTTP/2 302
server: CloudFront
date: Sat, 18 Nov 2023 06:32:15 GMT
content-length: 0
location: https://blog.i-tale.jp/
x-cache: FunctionGeneratedResponse from cloudfront
via: 1.1 1b3fd5e3e9b3fd38054dc45b58346688.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-C3
x-amz-cf-id: y3crb2t27Z46sb2vYL_G86__EhIRTCL0gSIAo7YWbKfCcnjZ_SF1Yw==

無事リダイレクトされていることが確認できました!

まとめ

CloudFront Functions を利用したリダイレクトを CDK を使って実装して動作確認までやってみました。

謎のバケットが1つ作られるのは気持ち悪いですが、少ないコードをでリダイレクト処理を作れるのは嬉しいですね。

今回のリポジトリはこちら

https://github.com/sisi100/cdk-url-redirect-with-cloudfront-functions

感謝!

表紙の写真は UnsplashChris Chowが撮影した写真です。 ありがとうございます!

Author

Sisii

インフラが好きなエンジニアぶってるなにか