「CloudFrontがLambda Functions URLへのOACに対応！」の何がすごいか

# はじめに

CloudFrontのOrigin　Access Control（OAC）がLambda Functions URLに対応しました。
つまり、Functions URLとCloudFrontのインテグレーションが実現できるようになりました！うおおおお！

https://aws.amazon.com/jp/about-aws/whats-new/2024/04/amazon-cloudfront-oac-lambda-function-url-origins/

と、このアプデの何がすごいの？　という点がいまいち伝わってない人向けに、この記事ではもろもろの経緯とユースケースを紹介します。

## 経緯

### Functions URLs、その課題

2022/4にLambdaの組み込みエンドポイントとしてLambda Functions URLが利用できるようになりました。

https://aws.amazon.com/jp/blogs/news/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/

これは従来ALBやAPI Gateway経由のリクエストしか扱えなかったAWS Lambdaにとって、同期リクエストを受ける便利な選択肢です。API Gatewayでネックだった29秒制限もないので、Lambdaの起動時間（最大900秒）を活かしてStreaming Responseを柔軟に利用できました。

Functions URLの難点として、セキュリティ機能がありました。標準だとCORSとIAM認証しかなく、要はWAF無しのHTTPエンドポイントと同等なので、IAM認証があるとは言えプロダクション採用には二の足を踏むものでした。

### ワークアラウンド、その課題

この点をどう解決するかというとCloudFrontとFunctions URLを紐付けて、間接的にWAF制御をFuncions URLで実現するものでした。

CloudFrontのHTTP OriginとしてFunctions URLを指定する書き方は、CDKだとこのように書けます！

```ts
const originFn = new NodejsFunction(this, 'origin', {
  entry: 'lambda/index.ts',
  handler: 'handler',
  runtime: lambda.Runtime.NODEJS_20_X,
});

const urlOriginFn = originFn.addFunctionUrl({
  // authType: lambda.FunctionUrlAuthType.AWS_IAM
  authType: lambda.FunctionUrlAuthType.NONE
})

new cloudfront.Distribution(this, 'Cdn', {
  defaultBehavior: {
    origin: new origins.FunctionUrlOrigin(urlOriginFn),
    edgeLambdas: [
      {
        functionVersion: edgeFn.currentVersion,
        eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
      },
    ],
  },
});

```

この場合CloudFrontからのアクセスはWAFが通りますが、問題としてOrigin自体のアクセス制御がありました。アクセスを制御する目的でFunctionsURLへIAM認証をかけると、CloudFrontから見たときに通常のHTTP Originとして扱えません。


結果としてCloudFrontからのリクエストをOrigin ViewerのLambda@EdgeでIAM署名し、OriginのFunctions URLに設定されたIAM認証を通す。というワークアラウンドで対応するしかありませんでした。

- ワークアラウンドの参考記事

https://aws.amazon.com/jp/blogs/compute/protecting-an-aws-lambda-function-url-with-amazon-cloudfront-and-lambdaedge/

https://iret.media/88185

これは当然、以下の問題がありました。

- Lambda@Edge(Origin Viewer)のコード管理
- 本来用途としてLambda@Edgeを使う際の、コードの複雑化
- Lambda@Edgeの実行費用


### 今回のアップデート

今回のOACサポートがされることで、Functions URLのIAM認証設定を保ったまま、Lambda@Edge部分を外すことができます。つまり、よりシンプルに扱えるようになりました。これは嬉しいことです。


## CloudFront + Functions URLの何が嬉しいのか

「背景はわかったけど、Functions URLをそこまでして使うのはなぜ？」という点が気になる方もいるでしょう。

### for API

API Gateway - Lambdaモデルの場合、Lambda側のコードはマイクロサービス志向になることが多かったのではないでしょうか？ 

LambdaのイベントをそのままHTTP リクエストとして流すことのできるLambda Web AdaptorというExtentionとLambda Functions URLを組み合わせた、モジュラーモノリスとしてのLambdaも注目されています。バックエンドはFastAPIやHonoのフレームワークを採用することで可搬性があり、記述しやすい構成にしたいが、API基盤としてのセキュリティが気になる方もいたかと思います。

https://aws.amazon.com/jp/builders-flash/202301/lambda-web-adapter/?awsf.filter-name=*all

これを解決するのが前述の”ワークアラウンド”だったのですが、

![oac-lambda-api.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528454/fcda077e-d25d-5c7c-de92-91f917d7530d.png)

OACが対応したので、スッキリと扱えます！

![oac-lambda-api-after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528454/839a8883-8c9f-2353-b0a1-4a377520c190.png)

手前でのルーティングを実施したい、オーソライザーを利用したいなどのユースケースがあればAPI Gatewayは引き続き有効です。Lambda側でルーティング定義がされている、すなわちWebフレームワーク主体の書き方をしたい場合にはCloudFront ＋ Lambda Functions URL ＋(Lambda Web Adaptor)は強力な選択肢になると思います！

### for FrontEnd

Amplifyを使えない要件の場合、CloudFront＋S3にてフロントの基盤を用意するのが一般的ですが、CloudFrontからSSRする基盤としてLambdaを選ぶときに、Originのセキュリティを考えてAPI Gateway＋WAFを使っていた方もいると思います。

![functionurl-oac.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528454/07c0ce8a-f4df-db24-c6f1-a9a39a69e68b.png)


今回のアップデートでOriginはIAM認証を保つことができるため、これを外すことができます。リソース管理がシンプルになりましたね！

![functionurl-oac-after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528454/365aca0c-4b2a-1cde-021e-24fe18de175f.png)




## まとめ

ということで「CloudFrontがLambda Functions URLへのOACに対応！　の何がすごいか」について語っていきました。この記事を書いていたら早速動かした記事が出ているので、私も手元の環境で試してみます。

https://qiita.com/Kanahiro/items/85573c9ae724df435a6a