shoetBlog
技術や好きなことについて発信しています。
AWS LambdaFunctionURLsでデプロイしたアプリをCloudFrontで配信しOACを適用する
2025/1/3 11:13:23
CloudFrontLambdaAWS
AWS LambdaFunctionURLsでデプロイしたアプリをCloudFrontで配信しOACを適用する

アジェンダは以下になります。

1. LambdaFunctionURLsを直接配信する際の問題点
2. CloudFrontでLambdaFunctionURLsを配信する際の以前までのワークアラウンド
3. CDKでの構築

1. LambdaFunctionURLsを直接配信する際の問題点

LambdaFunctionURLsをそのままで配信すると以下の点でセキュリティ的に気になる部分があります。

  • 独自ドメインの設定ができない
  • CloudFrontのキャッシュやWAFを設定するなどのメリットが受けられない

そのためCloudFrontをLambdaFunctionURLsの前段に配置する必要があります。

2. CloudFrontでLambdaFunctionURLsを配信する際の以前までのワークアラウンド

これまでもCloudFront経由でLambdaFunctionURLsを配信することはできましたが、FunctionURLs向けのOACが登場するまでは、少し遠回りな対応が必要でした。

  • LambdaFunctionURLsの認証をIAM認証で設定する(こちらは現在も同じ)
  • CloudFrontにLambda@Edgeを紐づけ、その中でIAM署名を行いLambdaFunctionURLsへのIAM認証を通す。

こちらについては下記記事の詳細を参照ください。

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

3. CDKでの構築

それではCDKでCloudFrontの構築とOACの設定するポイントを紹介します。

今回検証に使用したリポジトリはこちらになります。

https://github.com/shoet/aws-cdk-sandbox/tree/main/ts-nextjs-lambda-example-oac

ベースは以前の記事「Next.jsのSSR StreamingをLambdaFunctionURLsで検証する」で 作成したものをベースとしています。

構築手順は大まかに下記になります。

1. LambdaFunctionURLsをIAM認証にする
2. CloudFrontDistributionを作成する
3. DistributionのOriginにFunctionURLsを指定する
4. FunctionURLsにOACを適用する
5. LambdaFunctionにCloudFrontからの実行を許可する

1.LambdaFunctionURLsをIAM認証にする

authTypeをAWS_IAMに設定します。

this.functionUrl = new FunctionUrl(this, "NextJsLambdaFunctionUrl", {
  function: this.function,
  authType: cdk.aws_lambda.FunctionUrlAuthType.AWS_IAM,
  invokeMode: cdk.aws_lambda.InvokeMode.RESPONSE_STREAM,
});

infrastracture/lib/lambda-function-stack.ts

2.CloudFrontDistributionを作成する / 3.DistributionのOriginにFunctionURLsを指定する

   const lambdaFunctionOAC =
      new cdk.aws_cloudfront.FunctionUrlOriginAccessControl(
        this,
        "LambdaFunctionOAC",
        {
          signing: cdk.aws_cloudfront.Signing.SIGV4_ALWAYS,
        }
      );

    const functionUrlOrigin = new cdk.aws_cloudfront_origins.FunctionUrlOrigin(
      lambdaFunctionUrl,
      {
        originAccessControlId: lambdaFunctionOAC.originAccessControlId,
      }
    );

infrastracture/lib/CloudFront.ts

4.FunctionURLsにOACを適用する

OACのsigningは常に署名を設定します。

    const lambdaFunctionOAC =
      new cdk.aws_cloudfront.FunctionUrlOriginAccessControl(
        this,
        "LambdaFunctionOAC",
        {
          signing: cdk.aws_cloudfront.Signing.SIGV4_ALWAYS,
        }
      );

infrastracture/lib/CloudFront.ts

5.LambdaFunctionにCloudFrontからの実行を許可する

このままではLambdaにCloudFrontからの実行権限がないためaddPermissionを行います。

    lambdaFunction.addPermission("AllowInfokeCloudFront", {
      action: "lambda:InvokefunctionUrl",
      principal: new cdk.aws_iam.ServicePrincipal("cloudfront.amazonaws.com"),
      sourceArn: `arn:aws:cloudfront::${cdk.Aws.ACCOUNT_ID}:distribution/${distribution.distributionId}`,
    });

infrastracture/lib/CloudFront.ts

関連ドキュメントには以下のように手動での権限付与が明記されています。

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-lambda.html#oac-permission-to-access-lambda

ここまで適用すると、LambdaFunctionURLsへの直接アクセスが403となりアクセス不可となっていることが確認できます。

おわりに

これで、LambdaFunctionsURLの直接アクセスを制御しつつ、CloudFrontのメリットを活かした安全な公開が実現できます。
ぜひ今回のリポジトリをベースに、ご自身のアプリでも試してみてください。今後のAWSアップデートにも注目して、より便利な機能が追加されれば、さらに活用の幅が広がるはずです!

コメント
profile
匿名ユーザー(ID: )
Markdown
Preview
エンジニア。
エンジニアリングで価値提供できるよう、
日々自己研磨。
AWSAWS LambdaChormiumCloudFrontDockerECSGitHubGoGraphQLLambdaLocalStackNext.jsOpenAIPlanetScaleReactReduxServerlessFrameworkTypeScriptUpstashViteWebSocket