aws cdkaws lambdacloud front2025/4/11 • 読了時間:5分

aws cdk でlambdaにoacを適用しcloud frontからのみ参照出来るようにする

ブログ記事のメイン画像

前置き

Next.jsでaws lambda × cloud frontのサーバレス構成にしつつ、aws lambdaを直接参照できないようにしたときの備忘録になります。

実装についてはTypeScriptで記載しています。 環境構築などは出来ているものとして書いているので構築方法などは割愛しています。

ゴール

以下の状態とすることを最終的なゴールとします。

  • cloud front経由でaws lambdaの関数URLを実行できる
  • aws lambdaの関数URLを直接実行できない

実装

プロジェクトの作成

始めにcdkプロジェクトを作成します。 以降はこのプロジェクト内で作業を行います。

powershell
1npx cdk init app --language typescript

AWSへデプロイするための準備

プロジェクトを作成した直後の状態だとAWSへの適用ができません。 「/bin/〇〇.ts」で環境情報を設定する必要があるので調整を行います。 ※〇〇はプロジェクトの作成時に指定したフォルダ名とかになっているはず

typescript
1#!/usr/bin/env node
2import * as cdk from 'aws-cdk-lib';
3import { TestStack } from '../lib/test-stack';
4
5const app = new cdk.App();
6new TestStack(app, 'TestStack', {
7  env: {
8    account: 'aws account id', // AWS認証情報
9    region: 'ap-northeast-1',
10  },
11});
12

次にpackage.jsonに以下のscriptを追加します。

typescript
1{
2  ...,
3  "scripts": {
4    "build": "tsc",
5    "watch": "tsc -w",
6    "test": "jest",
7    "cdk": "cdk",
8+    "cdk:deploy": "cdk deploy", // これと
9+   "cdk:destroy": "cdk destroy" // これ
10  },
11  ...,
12}
13

上記の実装が終わったら次のコマンドを実行します。

powershell
1npm run cdk:deploy

コマンド実行後AWSコンソールへログインを行い「CloudFormation」にスタックが作成されていれば準備完了です。

画像

AWS Lambdaを構築するプログラムの実装

「/lib/〇〇-stack.ts」にてAWS環境を構築するためのプログラムを実装するファイルがあるため、Lambdaを構築するための実装を行います。

typescript
1import * as cdk from 'aws-cdk-lib';
2import { Construct } from 'constructs';
3import * as lambda from 'aws-cdk-lib/aws-lambda';
4
5export class TestStack extends cdk.Stack {
6  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
7    super(scope, id, props);
8
9		// Lambda関数の作成
10    const myLambda = new lambda.Function(this, "HelloWorldFunction", {
11      runtime: lambda.Runtime.NODEJS_20_X,
12      handler: "index.handler",
13      code: lambda.Code.fromInline(`
14        exports.handler = async function(event) {
15          return {
16            statusCode: 200,
17            body: JSON.stringify('Hello World!'),
18          };
19        };
20      `),
21    });
22    
23    // Lambda関数をURLで呼べるように設定
24    const lambdaUrl = myLambda.addFunctionUrl({
25      authType: lambda.FunctionUrlAuthType.NONE,
26    });
27
28    // Lambda関数URLの出力
29    new cdk.CfnOutput(this, 'LambdaUrl', {
30      value: lambdaUrl.url,
31      description: 'URL of the Lambda function',
32      exportName: 'LambdaUrl',
33    });
34  }
35}
36

一旦この状態で再度デプロイしてAWS Lambdaが動くか確認してみます。 ※コンソールにAWS LambdaのURLが出力されるのでそちらにアクセスします。

"Hello World!" が出力出来たらうまく動いています。

Cloud Front部分の実装とAWS Lambdaの直接実行を無効化

Cloud Frontの構築部分の処理とAWS Lambdaを直リンクで実行できないようにします。 Cloud Front ⇒ AWS Lambda間ではOACを設定し実行できるように調整を行います。

typescript
1import * as cdk from 'aws-cdk-lib';
2import { Construct } from 'constructs';
3import * as lambda from 'aws-cdk-lib/aws-lambda';
4import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
5import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
6
7export class TestStack extends cdk.Stack {
8  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
9    super(scope, id, props);
10
11		// Lambda関数の作成
12    const myLambda = new lambda.Function(this, "HelloWorldFunction", {
13      runtime: lambda.Runtime.NODEJS_20_X,
14      handler: "index.handler",
15      code: lambda.Code.fromInline(`
16        exports.handler = async function(event) {
17          return {
18            statusCode: 200,
19            body: JSON.stringify('Hello World!'),
20          };
21        };
22      `),
23    });
24    
25    // Lambda関数をURLで呼べるように設定
26    const lambdaUrl = myLambda.addFunctionUrl({
27      authType: lambda.FunctionUrlAuthType.AWS_IAM,  // NOTEからAWS_IAMに変更
28    });
29
30    // Cloud Frontの作成
31    const distribution = new cloudfront.Distribution(this, 'MyDistribution', {
32      defaultBehavior: {
33        origin: origins.FunctionUrlOrigin.withOriginAccessControl(lambdaUrl),
34      },
35    });
36
37    // Lambda関数URLの出力
38    new cdk.CfnOutput(this, 'LambdaUrl', {
39      value: lambdaUrl.url,
40      description: 'URL of the Lambda function',
41      exportName: 'LambdaUrl',
42    });
43
44    // CloudFrontのURLの出力
45    new cdk.CfnOutput(this, 'CloudFrontUrl', {
46      value: distribution.distributionDomainName,
47      description: 'URL of the CloudFront distribution',
48      exportName: 'CloudFrontUrl',
49    });
50  }
51}

再度デプロイを行うとCloud FrontのURLとAWS LambdaのURLがログで出力されます。 両方にアクセスしてみて以下の動きになったら成功です。

  • Cloud FrontのURLにアクセス⇒"Hello World!"
  • AWS LambdaのURLにアクセス⇒{"Message":"Forbidden"}

終わり

以上で「aws cdk でlambdaにoacを適用しcloud frontからのみ参照出来るようにする」実装が出来ました。

この構成はNuxt3やNextをAWS Lambda × Cloud Front(サーバーレス構成)の構成でも使えるので是非参考にしてもらえればと思います。

 

 

最新の記事

AIでの開発にいろいろと進展がある中、私もAIでフロントエンド実装をしてみた!となりいろいろとやって挫折した話になります。...

生成系AIの発展が目まぐるしい中、どんなことが出来るのか試してみたく実際に作ることにしました。 最後まで作り終える前にまたトレンドが変わっそうな気もしますが、気長にやっていきます。以下の工程全てAIを...