<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lambda | きいちログ</title>
	<atom:link href="https://wptech.kiichiro.work/tag/lambda/feed/" rel="self" type="application/rss+xml" />
	<link>https://wptech.kiichiro.work</link>
	<description>WordPressとかAWSとかPHPとか</description>
	<lastBuildDate>Wed, 16 Jul 2025 02:16:58 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>AWS CDK と Bref を用いた Laravel サーバーレス構成 ― Lambda + EFS + SQLite</title>
		<link>https://wptech.kiichiro.work/94slab74qm/</link>
		
		<dc:creator><![CDATA[むらおか]]></dc:creator>
		<pubDate>Wed, 30 Apr 2025 06:26:38 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">https://wptech.kiichiro.work/?p=3700</guid>

					<description><![CDATA[目次 はじめにプロジェクトの概要コンセプト成果物システム構成準備LaravelCDKCDKの実装ネットワークデータストレージアプリケーションWebアプリケーションConsoleアプリケーションデプロイ・動作確認まとめと感 [&#8230;]]]></description>
										<content:encoded><![CDATA[

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">はじめに</a></li><li><a href="#toc2" tabindex="0">プロジェクトの概要</a><ol><li><a href="#toc3" tabindex="0">コンセプト</a></li><li><a href="#toc4" tabindex="0">成果物</a></li><li><a href="#toc5" tabindex="0">システム構成</a></li></ol></li><li><a href="#toc6" tabindex="0">準備</a><ol><li><a href="#toc7" tabindex="0">Laravel</a></li><li><a href="#toc8" tabindex="0">CDK</a></li></ol></li><li><a href="#toc9" tabindex="0">CDKの実装</a><ol><li><a href="#toc10" tabindex="0">ネットワーク</a></li><li><a href="#toc11" tabindex="0">データストレージ</a></li><li><a href="#toc12" tabindex="0">アプリケーション</a><ol><li><a href="#toc13" tabindex="0">Webアプリケーション</a></li><li><a href="#toc14" tabindex="0">Consoleアプリケーション</a></li></ol></li></ol></li><li><a href="#toc15" tabindex="0">デプロイ・動作確認</a></li><li><a href="#toc16" tabindex="0">まとめと感想</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">はじめに</span></h2>



<p>PHPでAWS Lambdaを利用したアプリケーションを構築するには、カスタムランタイムが必要になります。BrefはLambdaでPHPを実行するためのランタイムとLaravel、SymfonyなどのPHPフレームワークとの統合を提供しています。</p>




<a rel="noopener" href="https://bref.sh" title="Bref – Simple and scalable PHP with serverless" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img decoding="async" src="https://bref.sh/social-card.png" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Bref – Simple and scalable PHP with serverless</div><div class="blogcard-snippet external-blogcard-snippet">Bref is a framework to write and deploy serverless PHP applications on AWS Lambda.</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img decoding="async" src="https://www.google.com/s2/favicons?domain=https://bref.sh" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">bref.sh</div></div></div></div></a>



<p>本記事では、このBrefを使ったLaravelアプリケーションの環境構築方法を解説していきます。</p>



<h2 class="wp-block-heading"><span id="toc2">プロジェクトの概要</span></h2>



<h3 class="wp-block-heading"><span id="toc3">コンセプト</span></h3>



<p>基本的にBrefはServerless Frameworkを介して利用しますが、今回はAWS CDKにBref用の専用Constructが用意されているので、CDKを利用することにしました。コードベースでのインフラ管理や拡張の容易性もCDKを選定した理由になります。</p>



<p>また、個人のテスト環境として比較的低コストで構築できるように最小構成で実装していきます。</p>



<h3 class="wp-block-heading"><span id="toc4">成果物</span></h3>



<p>完成品は以下に配置してあります。</p>




<a rel="noopener" href="https://github.com/ShotaroMuraoka/cdk-serverless-laravel" title="GitHub - ShotaroMuraoka/cdk-serverless-laravel: Laravel アプリケーションを Bref でサーバーレス化した CDK" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img decoding="async" src="https://opengraph.githubassets.com/9e5f1f036341ca90ff4e35999daa9468a3cfc0b7532da531ce456db400428a22/ShotaroMuraoka/cdk-serverless-laravel" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">GitHub - ShotaroMuraoka/cdk-serverless-laravel: Laravel アプリケーションを Bref でサーバーレス化した CDK</div><div class="blogcard-snippet external-blogcard-snippet">Laravel アプリケーションを Bref でサーバーレス化した CDK. Contribute to ShotaroMuraoka/cdk-serverless-laravel development by creating an ac...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://github.com/ShotaroMuraoka/cdk-serverless-laravel" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">github.com</div></div></div></div></a>



<h3 class="wp-block-heading"><span id="toc5">システム構成</span></h3>



<p>システム構成は以下の通りです。</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="901" height="461" src="https://wptech.kiichiro.work/wp-content/uploads/2025/04/bref-cdk.png" alt="AWSの構成図。クライアントからはHTTPとaws lambda invokeの線が出ており、それぞれAPI Gateway, Lambda ConsoleFunctionと接続している。API GatewayはApiFunctionと接続している。ApiFunctionとConsoleFunctionはEFSに接続している。API GatewayはAWS Cloudの中、Lambda ApiFunctionとConsoleFunction, EFSはAWS Cloudの中のVPCの中のPrivate subnetの中に配置されている。" class="wp-image-3719" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/04/bref-cdk.png 901w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/bref-cdk-300x153.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/bref-cdk-768x393.png 768w" sizes="(max-width: 901px) 100vw, 901px" /></figure>



<p>Lambda関数が2つデプロイされているのは、API Gatewayに統合されているWebアプリケーションと <code>php artisan migrate</code> などを実行するConsoleアプリケーションを分けているためです。EFSは後述しますが、データストレージの役割を担っています。</p>



<h2 class="wp-block-heading"><span id="toc6">準備</span></h2>



<h3 class="wp-block-heading"><span id="toc7">Laravel</span></h3>



<p>Laravel側の作業はBrefに必要なライブラリをインストールするだけです。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>% composer require bref/bref bref/laravel-bridge --update-with-dependencies</code></pre></div>



<h3 class="wp-block-heading"><span id="toc8">CDK</span></h3>



<p>CDK側では、BrefのConstructパッケージをインストールします。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>% npm install @bref.sh/constructs</code></pre></div>



<h2 class="wp-block-heading"><span id="toc9">CDKの実装</span></h2>



<p>CDK側の実装を見ていきます。</p>



<h3 class="wp-block-heading"><span id="toc10">ネットワーク</span></h3>



<p>EFSをマウントさせる都合上、VPC Lambdaである必要があります。コスト高になりがちなNAT Gatewayに関しては、今回はLambdaからインターネットに出ていく必要は無いので、作成をしない設定にしています。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="lib/construct/networking.ts" data-lang="TypeScript"><code>const vpc = new ec2.Vpc(this, &quot;BrefVpc&quot;, {
  maxAzs: 1,
  natGateways: 0,
  restrictDefaultSecurityGroup: true,
  subnetConfiguration: [
    {
      name: &quot;BrefPrivate&quot;,
      subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
    },
  ],
});</code></pre></div>



<h3 class="wp-block-heading"><span id="toc11">データストレージ</span></h3>



<p>RDBのマネージドサービスは高価ですので、Laravelの初期状態で使えるSQLiteを選定し、EFSに <code>database.sqlite</code> ファイルを配置するようにします。冗長化も不要なのでOneZoneを選択しています。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="lib/construct/datastore.ts" data-lang="TypeScript"><code>const fileSystem = new efs.FileSystem(this, &quot;BrefEfs&quot;, {
  vpc: vpc,
  removalPolicy: cdk.RemovalPolicy.DESTROY,
  performanceMode: efs.PerformanceMode.GENERAL_PURPOSE,
  throughputMode: efs.ThroughputMode.BURSTING,
  oneZone: true,
});

const accessPoint = this.fileSystem.addAccessPoint(&quot;BrefAccessPoint&quot;, {
  path: &quot;/bref&quot;
  createAcl: {
    ownerUid: &quot;1001&quot;,
    ownerGid: &quot;1001&quot;,
    permissions: &quot;750&quot;,
  },
  posixUser: {
    uid: &quot;1001&quot;,
    gid: &quot;1001&quot;,
  },
});</code></pre></div>



<h3 class="wp-block-heading"><span id="toc12">アプリケーション</span></h3>



<p>システム構成の項で紹介した通り、WebアプリケーションとConsoleアプリケーションの2つを用意しています。</p>



<h4 class="wp-block-heading"><span id="toc13">Webアプリケーション</span></h4>



<p>Webアプリケーションでは、Lambda関数とHTTPからのアクセス用にAPI Gatewayを統合します。Lambda関数は <code>@bref.sh/constructs</code> に <code>PhpFpmFunction</code> というBrefのレイヤーを追加したConstructがあるので、これを使用します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="lib/construct/backend.ts" data-lang="TypeScript"><code>const backendFn = new PhpFpmFunction(this, &quot;BrefApiFunction&quot;, {
  functionName: &quot;ApiFunction&quot;,
  handler: &quot;public/index.php&quot;,
  code: packagePhpCode(&quot;../laravel/&quot;, {
    exclude: [&quot;tests/**&quot;, &quot;var/**&quot;],
  }),
  timeout: cdk.Duration.seconds(28),
  memorySize: 1024,
  vpc: vpc,
  filesystem: lambda.FileSystem.fromEfsAccessPoint(
    accessPoint,
    &quot;/mnt/efs&quot;,
  ),
  environment: {
    APP_ENV: &quot;production&quot;,
    LOG_CHANNEL: &quot;stderr&quot;,
    DB_CONNECTION: &quot;sqlite&quot;,
    DB_DATABASE: &quot;/mnt/efs/database.sqlite&quot;,
  },
  phpVersion: &quot;8.4&quot;,
});

const api = new apigwv2.HttpApi(this, &quot;BrefHttpApi&quot;, {
  defaultIntegration: new integrations.HttpLambdaIntegration(
    &quot;Integration&quot;,
    backendFn,
  ),
});

new cdk.CfnOutput(this, &quot;ApiUrl&quot;, {
  value: api.url!,
});</code></pre></div>



<div class="wp-block-cocoon-blocks-tab-box-1 blank-box bb-tab bb-check block-box">
<p>URLを <code>CfnOutput</code> で出力するとデプロイ後のアクセスが楽になります。</p>
</div>



<h4 class="wp-block-heading"><span id="toc14">Consoleアプリケーション</span></h4>



<p>Brefには、<code>ConsoleFunction</code> というConstructがあります。これは、artisanコマンドを実行するエンドポイントになります。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="lib/construct/artisan.ts" data-lang="TypeScript"><code>new ConsoleFunction(this, &quot;BrefConsoleFunction&quot;, {
  functionName: &quot;ConsoleFunction&quot;,
  handler: &quot;artisan&quot;,
  code: packagePhpCode(&quot;../laravel/&quot;, {
    exclude: [&quot;tests/**&quot;, &quot;var/**&quot;],
  }),
  timeout: cdk.Duration.seconds(28),
  memorySize: 512,
  vpc: vpc,
  filesystem: lambda.FileSystem.fromEfsAccessPoint(
    accessPoint,
    &quot;/mnt/efs&quot;,
  ),
  environment: {
    APP_ENV: &quot;production&quot;,
    LOG_CHANNEL: &quot;stderr&quot;,
    DB_CONNECTION: &quot;sqlite&quot;,
    DB_DATABASE: &quot;/mnt/efs/database.sqlite&quot;,
  },
  phpVersion: &quot;8.4&quot;,
});</code></pre></div>



<div class="wp-block-cocoon-blocks-tab-box-1 blank-box bb-tab bb-check block-box">
<p>artisanコマンドはaws cli経由で実行しますので、<code>functionName</code> を定義しておくと後々便利です。</p>
</div>



<h2 class="wp-block-heading"><span id="toc15">デプロイ・動作確認</span></h2>



<p>デプロイして動作確認してみます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>% cdk deploy

(略)

Outputs:
BrefStack.ApiUrl = https://example.execute-api.ap-northeast-1.amazonaws.com/
</code></pre></div>



<p>出力されたURLにアクセスしてみます。</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="537" src="https://wptech.kiichiro.work/wp-content/uploads/2025/04/e6f5d404fcf83bb886fcbff5cd5339e9-1024x537.png" alt="Internal Server Error のタイトルで、Database file at path [/mnt/efs/database.sqlite] does not exist. のメッセージが出ている。" class="wp-image-3787" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/04/e6f5d404fcf83bb886fcbff5cd5339e9-1024x537.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/e6f5d404fcf83bb886fcbff5cd5339e9-300x157.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/e6f5d404fcf83bb886fcbff5cd5339e9-768x403.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/e6f5d404fcf83bb886fcbff5cd5339e9-1536x805.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/e6f5d404fcf83bb886fcbff5cd5339e9.png 1618w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>当然、migrationが終わっていないのでエラーが表示されます。ConsoleFunctionを直接実行してmigrationします。aws cliを利用して以下を実行します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>% aws lambda invoke \
     --function-name ConsoleFunction \
     --region ap-northeast-1 \
     --cli-binary-format raw-in-base64-out \
     --payload &#39;&quot;migrate --force&quot;&#39; \
     response.json</code></pre></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>{
    &quot;StatusCode&quot;: 200,
    &quot;ExecutedVersion&quot;: &quot;$LATEST&quot;
}
</code></pre></div>



<p>Lambdaの実行に問題がなければLaravelの画面が見られるようになるはずです。</p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="483" src="https://wptech.kiichiro.work/wp-content/uploads/2025/04/deca5a578e8813d0057e8e4cd7a16ea4-1024x483.png" alt="Laravel 12 の初期画面。" class="wp-image-3790" srcset="https://wptech.kiichiro.work/wp-content/uploads/2025/04/deca5a578e8813d0057e8e4cd7a16ea4-1024x483.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/deca5a578e8813d0057e8e4cd7a16ea4-300x141.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/deca5a578e8813d0057e8e4cd7a16ea4-768x362.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/deca5a578e8813d0057e8e4cd7a16ea4-1536x724.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2025/04/deca5a578e8813d0057e8e4cd7a16ea4.png 1934w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading"><span id="toc16">まとめと感想</span></h2>



<p>本記事では、BrefをCDKで利用してAWS Lambda上でLaravelを動かしてみました。また、低コストでの構築を目指し、最小構成の形を取りました。</p>



<p>BrefはLaravelアプリケーション側で意識することが少ないですので、かなり手軽にできるんじゃないかと思いました。デプロイパイプラインを整えれば、本番環境にも適用できると思います。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Lambda Web AdapterでRemixアプリケーションをサーバーレス化してCDKでデプロイする</title>
		<link>https://wptech.kiichiro.work/617bivwxur/</link>
		
		<dc:creator><![CDATA[むらおか]]></dc:creator>
		<pubDate>Thu, 11 Jul 2024 09:08:50 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[Remix]]></category>
		<guid isPermaLink="false">https://wptech.kiichiro.work/?p=3178</guid>

					<description><![CDATA[既存の Web フレームワークを Lambda に組み込む方法として Lambda Web Adapter というのがあります。 Lambda Web Adapter でウェブアプリを (ほぼ) そのままサーバーレス化す [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>既存の Web フレームワークを Lambda に組み込む方法として Lambda Web Adapter というのがあります。</p>




<a rel="noopener" href="https://aws.amazon.com/jp/builders-flash/202301/lambda-web-adapter" title="Lambda Web Adapter でウェブアプリを (ほぼ) そのままサーバーレス化する (2025 年改訂版)  - 変化を求めるデベロッパーを応援するウェブマガジン | AWS" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://d1.awsstatic.com/Developer%20Marketing/jp/magazine/2025/202504/thumb_lambda-web-adapter_2025.eaa3dee4029c2885d864b4da103ab18cd6b2b4f9.jpg" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Lambda Web Adapter でウェブアプリを (ほぼ) そのままサーバーレス化する (2025 年改訂版)  - 変化を求めるデベロッパーを応援するウェブマガジン | AWS</div><div class="blogcard-snippet external-blogcard-snippet">VM やコンテナ用に実装されたウェブアプリを、ほとんどそのまま Lambda でも動かせる AWS Lambda Web Adapter について、新しい実装パターンを含めた使い方、仕組みや対応する Web フレームワーク、性能をご紹介しま...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://aws.amazon.com/jp/builders-flash/202301/lambda-web-adapter/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">aws.amazon.com</div></div></div></div></a>




<a rel="noopener" href="https://github.com/awslabs/aws-lambda-web-adapter" title="GitHub - awslabs/aws-lambda-web-adapter: Run web applications on AWS Lambda" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://opengraph.githubassets.com/d477a0d6d3e245d785d915f1b8b645c121d6d8cd3e618243358d4ae6e1b114cb/awslabs/aws-lambda-web-adapter" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">GitHub - awslabs/aws-lambda-web-adapter: Run web applications on AWS Lambda</div><div class="blogcard-snippet external-blogcard-snippet">Run web applications on AWS Lambda. Contribute to awslabs/aws-lambda-web-adapter development by creating an account on G...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://github.com/awslabs/aws-lambda-web-adapter" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">github.com</div></div></div></div></a>



<p>その仕組みですが、API Gateway などの統合先から受信したイベントをフレームワークの手前にある Lambda Web Adapter のエントリポイントが HTTP リクエストに変換して、フレームワークに渡してくれる、というイメージで良さそうです。</p>



<p>公式の実装例では、Node.js であれば Next.js と Express.js が対応していますが、HTTP であればどのようなフレームワークも動作するはずです。</p>



<p>今回はこれを使って Remix アプリをサーバーレス化してみました。既に作ったものは GitHub にあげてあります。</p>




<a rel="noopener" href="https://github.com/ShotaroMuraoka/cdk-serverless-remix" title="GitHub - ShotaroMuraoka/cdk-serverless-remix: Remix アプリケーションを Lambda Web Adapter でサーバーレス化した CDK" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://opengraph.githubassets.com/7e2f8909af7deb175a15b54c16dbbb4c74009bec87bc2f528dea48788888602f/ShotaroMuraoka/cdk-serverless-remix" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">GitHub - ShotaroMuraoka/cdk-serverless-remix: Remix アプリケーションを Lambda Web Adapter でサーバーレス化した CDK</div><div class="blogcard-snippet external-blogcard-snippet">Remix アプリケーションを Lambda Web Adapter でサーバーレス化した CDK. Contribute to ShotaroMuraoka/cdk-serverless-remix development by crea...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://github.com/ShotaroMuraoka/cdk-serverless-remix" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">github.com</div></div></div></div></a>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-4" checked><label class="toc-title" for="toc-checkbox-4">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">CDKの準備</a></li><li><a href="#toc2" tabindex="0">Remixアプリケーションの作成</a></li><li><a href="#toc3" tabindex="0">デプロイ</a></li><li><a href="#toc4" tabindex="0">参考資料</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">CDKの準備</span></h2>



<p>デプロイの方法は CDK にしました。init で新しいプロジェクトを作成しておきます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>$ cdk --version
2.148.0 (build e5740c0)

$ cdk init app --language typescript</code></pre></div>



<p>今回は HTTP リクエストを受け付けるので、API Gateway と統合します。Stack は以下からお借りしました。</p>



<figure class="wp-block-embed is-type-rich is-provider-hatena-blog wp-block-embed-hatena-blog"><div class="wp-block-embed__wrapper">
<iframe title="AWS Lambda Web AdapterでServerless Next.jsを実現する  - Activ8 Tech Blog" src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fsynamon.hatenablog.com%2Fentry%2F2023%2F07%2F18%2F080000" class="embed-card embed-blogcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 190px; max-width: 500px; margin: 10px 0px;"></iframe>
</div></figure>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="my-lambda-stack.ts" data-lang="TypeScript"><code>import * as cdk from &#39;aws-cdk-lib&#39;;
import { Construct } from &#39;constructs&#39;;
import * as lambda from &#39;aws-cdk-lib/aws-lambda&#39;;
import { Platform } from &#39;aws-cdk-lib/aws-ecr-assets&#39;;
import * as apigw from &#39;aws-cdk-lib/aws-apigatewayv2&#39;;
import { HttpLambdaIntegration } from &#39;aws-cdk-lib/aws-apigatewayv2-integrations&#39;;

export class MyLambdaStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const handler = new lambda.DockerImageFunction(this, &#39;Handler&#39;, {
      code: lambda.DockerImageCode.fromImageAsset(&#39;./my-remix&#39;, { // Remix アプリケーションのディレクトリ名とする
        platform: Platform.LINUX_AMD64,
      }),
      memorySize: 256,
      timeout: cdk.Duration.seconds(30),
    });

    new apigw.HttpApi(this, &#39;Api&#39;, {
      apiName: &#39;MyLambdaRemix&#39;,
      defaultIntegration: new HttpLambdaIntegration(&#39;Integration&#39;, handler),
    });
  }
}
</code></pre></div>



<h2 class="wp-block-heading"><span id="toc2">Remixアプリケーションの作成</span></h2>



<p>CDK のプロジェクトルートで Remix アプリを作成します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>$ npx create-remix@latest</code></pre></div>



<p>Remix アプリのルートに Dockerfile を作成します。Remix に対応した Dockerfile を作成したことがなかったので、以下を参考にそれっぽく書いてみました。</p>




<a rel="noopener" href="https://github.com/clintonwoo/hackernews-remix-react/blob/main/Dockerfile" title="hackernews-remix-react/Dockerfile at main · clintonwoo/hackernews-remix-react" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://opengraph.githubassets.com/9f4b585a4145808d862d74acfde120c24aa19eb58f0d39f34c2549a48ecc5e13/clintonwoo/hackernews-remix-react" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">hackernews-remix-react/Dockerfile at main · clintonwoo/hackernews-remix-react</div><div class="blogcard-snippet external-blogcard-snippet">Hacker News clone written with universal TypeScript, using React and Remix. - clintonwoo/hackernews-remix-react</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://github.com/clintonwoo/hackernews-remix-react/blob/main/Dockerfile" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">github.com</div></div></div></div></a>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash" data-line="23, 40"><code>FROM node:22-bookworm-slim AS base

FROM base AS deps
RUN mkdir /app
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

FROM base AS builder

RUN mkdir /app
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NODE_ENV production
RUN npm run build

FROM base AS runner

# lambda-web-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.5.0 /lambda-adapter /opt/extensions/lambda-adapter

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 remix

RUN mkdir /app
WORKDIR /app

RUN chown remix:nodejs ./
USER remix

COPY --from=builder --chown=remix:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=remix:nodejs /app/build ./build
COPY --from=builder --chown=remix:nodejs /app/public ./public
COPY --from=builder --chown=remix:nodejs /app/package.json /app/package-lock.json ./

ENV NODE_ENV production
ENV PORT 3000
EXPOSE 3000

CMD [&quot;npm&quot;, &quot;run&quot;, &quot;start&quot;]</code></pre></div>



<p>ここでは Lambda Web Adapter のために難しい記述をする必要はありません。ローカルでも ECS でも動くコンテナイメージであれば、Lambda Web Adapter で動作するようです。</p>



<p>追記が必要なのは Lambda の extension を追加するというところのみです。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.5.0 /lambda-adapter /opt/extensions/lambda-adapter</code></pre></div>



<p>また、デフォルトでは 8080 でポートを Listen しているので、変更する場合は PORT を指定します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>ENV PORT 3000</code></pre></div>



<h2 class="wp-block-heading"><span id="toc3">デプロイ</span></h2>



<p>CDK のルートディレクトリでデプロイを実行します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>$ cdk deploy</code></pre></div>



<p>管理コンソールから API Gateway の画面を確認すると、作成した API Gateway のエンドポイントが作成されています。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="384" src="https://wptech.kiichiro.work/wp-content/uploads/2024/07/24ba3ff1ffab27bfd8a591fc1c9770c3-1024x384.png" alt="AWS の管理コンソールで API Gateway &gt; API &gt; MyLambdaRemixの画面を開いている。エンドポイントが有効になっており、リンクが表示されている" class="wp-image-3225" srcset="https://wptech.kiichiro.work/wp-content/uploads/2024/07/24ba3ff1ffab27bfd8a591fc1c9770c3-1024x384.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2024/07/24ba3ff1ffab27bfd8a591fc1c9770c3-300x112.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2024/07/24ba3ff1ffab27bfd8a591fc1c9770c3-768x288.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2024/07/24ba3ff1ffab27bfd8a591fc1c9770c3-1536x576.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2024/07/24ba3ff1ffab27bfd8a591fc1c9770c3-2048x768.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>デフォルトのエンドポイントの URL をクリックして Remix アプリの画面が表示されていれば OK です。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="952" height="502" src="https://wptech.kiichiro.work/wp-content/uploads/2024/07/5a7c608aaf71c8c8671576d79db1798d.png" alt="Remix の初期の画面で、Welcome to Remix と表示されている" class="wp-image-3228" srcset="https://wptech.kiichiro.work/wp-content/uploads/2024/07/5a7c608aaf71c8c8671576d79db1798d.png 952w, https://wptech.kiichiro.work/wp-content/uploads/2024/07/5a7c608aaf71c8c8671576d79db1798d-300x158.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2024/07/5a7c608aaf71c8c8671576d79db1798d-768x405.png 768w" sizes="(max-width: 952px) 100vw, 952px" /></figure>



<h2 class="wp-block-heading"><span id="toc4">参考資料</span></h2>




<a rel="noopener" href="https://serverless.co.jp/blog/g30vzpio0ww" title="Dockerを使わない、Remix / Next.js 14 など最新ウェブフレームワークのAWS完全サーバーレス構成と環境構築方法 | ブログ | Serverless Operations" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://images.microcms-assets.io/assets/7c0b324145eb4ee6bd26d44022795cf4/219c94fc1d5b45038289ecdb40b09463/overview.png?w=1200&#038;fm=webp&#038;q=80" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Dockerを使わない、Remix / Next.js 14 など最新ウェブフレームワークのAWS完全サーバーレス構成と環境構築方法 | ブログ | Serverless Operations</div><div class="blogcard-snippet external-blogcard-snippet">（※ 2025/01/31 追記）この記事の後続編として、React Router v7 と Next.js 15 を利用する構成の詳細な構築手順について、こちらの記事（</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://serverless.co.jp/blog/g30vzpio0ww" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">serverless.co.jp</div></div></div></div></a>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>CDKでやる Lambda Function URLs</title>
		<link>https://wptech.kiichiro.work/8at84s0zgd/</link>
		
		<dc:creator><![CDATA[むらおか]]></dc:creator>
		<pubDate>Tue, 13 Dec 2022 14:51:12 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">http://13.115.157.198/?p=944</guid>

					<description><![CDATA[最近、CDKいじってなかったのでリハビリを兼ねて前からやってみたかったネタを。 Lambda Function URLs AWS LambdaはAPIエンドポイントとして利用するケースも多いと思いますが、Lambda F [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>最近、CDKいじってなかったのでリハビリを兼ねて前からやってみたかったネタを。</p>



<h1 class="wp-block-heading">Lambda Function URLs</h1>



<p>AWS LambdaはAPIエンドポイントとして利用するケースも多いと思いますが、Lambda Function URLsを利用することでAPI Gatewayを追加することなくHTTPSエンドポイントを設定することができます。API Gatewayの機能を必要としないAPIエンドポイントであればこれ使っておけばOKというものらしいです。</p>




<a rel="noopener" href="https://aws.amazon.com/jp/blogs/aws/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/" title="Announcing AWS Lambda Function URLs: Built-in HTTPS Endpoints for Single-Function Microservices | Amazon Web Services" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Faws.amazon.com%2Fjp%2Fblogs%2Faws%2Fannouncing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices%2F?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Announcing AWS Lambda Function URLs: Built-in HTTPS Endpoints for Single-Function Microservices | Amazon Web Services</div><div class="blogcard-snippet external-blogcard-snippet">Organizations are adopting microservices architectures to build resilient and scalable applications using AWS Lambda. Th...</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://aws.amazon.com/jp/blogs/aws/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">aws.amazon.com</div></div></div></div></a>



<h1 class="wp-block-heading">CDKでやる</h1>



<p>CDKのバージョンは以下。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cdk --version
2.54.0 (build 9f41881)</code></pre></div>



<p>CDKでは、FunctionUrlが用意されているのでそれを使用します。</p>




<a rel="noopener" href="https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.FunctionUrl.html" title="class FunctionUrl (construct) · AWS CDK" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Fdocs.aws.amazon.com%2Fcdk%2Fapi%2Fv2%2Fdocs%2Faws-cdk-lib.aws_lambda.FunctionUrl.html?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">class FunctionUrl (construct) · AWS CDK</div><div class="blogcard-snippet external-blogcard-snippet"># class FunctionUrl (construct)</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.FunctionUrl.html" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">docs.aws.amazon.com</div></div></div></div></a>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="lambda-function-urls-stack.ts" data-lang="TypeScript"><code>import * as cdk from &#39;aws-cdk-lib&#39;;
import { Construct } from &#39;constructs&#39;;
import * as lambda from &#39;aws-cdk-lib/aws-lambda&#39;;

export class LambdaFunctionUrlsStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const fn =  new lambda.Function(this, &#39;LambdaFunction&#39;, {
      runtime: lambda.Runtime.PYTHON_3_9,
      handler: &#39;app.lambda_handler&#39;,
      code: lambda.Code.fromAsset(&#39;./lambda&#39;),
    });

    const fnUrl = fn.addFunctionUrl({
      authType: lambda.FunctionUrlAuthType.NONE,
    });
    new cdk.CfnOutput(this, &#39;TheUrl&#39;, {
      value: fnUrl.url,
    });
  }
}</code></pre></div>



<p>Pythonは適当に。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-python" data-file="lambda/app.py" data-lang="Python"><code>def lambda_handler(event, context):
    return &quot;Hello  world!!&quot;</code></pre></div>



<p>build後、<code>cdk deploy</code> を行うとURLが出力されます。curl実行でFunctionが実行されていることが確認できます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>Outputs:
LambdaFunctionUrlsStack.TheUrl = https://xxxxxxxxxx.lambda-url.ap-northeast-1.on.aws/

curl https://xxxxxxxxxx.lambda-url.ap-northeast-1.on.aws/
Hello  world!!%</code></pre></div>



<h1 class="wp-block-heading">IAM認証する場合</h1>



<p>APIエンドポイントを公開する必要がない場合はIAM認証として設定することができます。以下の通り <code>authType</code> をAWS_IAMに変更するだけでOKです。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-lang="TypeScript"><code>const fnUrl = fn.addFunctionUrl({
  authType: lambda.FunctionUrlAuthType.AWS_IAM,
});</code></pre></div>



<p>ポリシーは <code>lambda:InvokeFunctionUrl</code> への許可があればOKだそうです。</p>




<a rel="noopener" href="https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/urls-invocation.html" title="Lambda &#38306;&#25968; URL &#12398;&#21628;&#12403;&#20986;&#12375; - AWS Lambda" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Fdocs.aws.amazon.com%2Fja_jp%2Flambda%2Flatest%2Fdg%2Furls-invocation.html?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Lambda &#38306;&#25968; URL &#12398;&#21628;&#12403;&#20986;&#12375; - AWS Lambda</div><div class="blogcard-snippet external-blogcard-snippet">ウェブブラウザ、curl、Postman、または任意の HTTP クライアントを使用して、専用の HTTP エンドポイントを介して Lambda 関数を呼び出します。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/urls-invocation.html" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">docs.aws.amazon.com</div></div></div></div></a>




<a rel="noopener" href="https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/urls-auth.html" title="Lambda &#38306;&#25968; URL &#12408;&#12398;&#12450;&#12463;&#12475;&#12473;&#12398;&#21046;&#24481; - AWS Lambda" class="blogcard-wrap external-blogcard-wrap a-wrap cf" target="_blank"><div class="blogcard external-blogcard eb-left cf"><div class="blogcard-label external-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail external-blogcard-thumbnail"><img loading="lazy" decoding="async" src="https://s.wordpress.com/mshots/v1/https%3A%2F%2Fdocs.aws.amazon.com%2Fja_jp%2Flambda%2Flatest%2Fdg%2Furls-auth.html?w=160&#038;h=90" alt="" class="blogcard-thumb-image external-blogcard-thumb-image" width="160" height="90" /></figure><div class="blogcard-content external-blogcard-content"><div class="blogcard-title external-blogcard-title">Lambda &#38306;&#25968; URL &#12408;&#12398;&#12450;&#12463;&#12475;&#12473;&#12398;&#21046;&#24481; - AWS Lambda</div><div class="blogcard-snippet external-blogcard-snippet">リソースベースのポリシーに加え AuthType パラメータを使用して、Lambda 関数 URL へのアクセスを保護および制限します。</div></div><div class="blogcard-footer external-blogcard-footer cf"><div class="blogcard-site external-blogcard-site"><div class="blogcard-favicon external-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/urls-auth.html" alt="" class="blogcard-favicon-image external-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain external-blogcard-domain">docs.aws.amazon.com</div></div></div></div></a>



<div class="hcb_wrap"><pre class="prism line-numbers lang-json" data-lang="JSON"><code>{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: &quot;lambda:InvokeFunctionUrl&quot;,
            &quot;Resource&quot;: &quot;*&quot;
        }
    ]
}</code></pre></div>



<p>署名付きAPIへのアクセスが必要になるのですが、今回はPostmanでやってみました。<br>適当なIAMユーザーを作ってAccessKey, SecretAccessKeyを作成し、入力していきます。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="732" src="https://wptech.kiichiro.work/wp-content/uploads/2022/12/e922b113fca42efba5b0865752f799fd-1024x732.png" alt="Postmanでの実行結果" class="wp-image-1005" srcset="https://wptech.kiichiro.work/wp-content/uploads/2022/12/e922b113fca42efba5b0865752f799fd-1024x732.png 1024w, https://wptech.kiichiro.work/wp-content/uploads/2022/12/e922b113fca42efba5b0865752f799fd-300x214.png 300w, https://wptech.kiichiro.work/wp-content/uploads/2022/12/e922b113fca42efba5b0865752f799fd-768x549.png 768w, https://wptech.kiichiro.work/wp-content/uploads/2022/12/e922b113fca42efba5b0865752f799fd-1536x1098.png 1536w, https://wptech.kiichiro.work/wp-content/uploads/2022/12/e922b113fca42efba5b0865752f799fd.png 1726w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>リクエストを投げると無事レスポンスが返ってきました。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>AWS CDKを使ってTypeScriptで書いたLambdaをデプロイする + SAM Localで動かす</title>
		<link>https://wptech.kiichiro.work/26ru99uao0/</link>
		
		<dc:creator><![CDATA[むらおか]]></dc:creator>
		<pubDate>Sat, 12 Mar 2022 15:20:42 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Lambda]]></category>
		<category><![CDATA[TypeScript]]></category>
		<guid isPermaLink="false">http://13.115.157.198/?p=313</guid>

					<description><![CDATA[LambdaのコードをTypeScriptで書いてCDKでデプロイしようとすると、CDKによるデプロイの外でトランスパイルしなければいかんよなぁ。。と思っていたんですが、今はそんなことしなくても良くなってるんですね。 前 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>LambdaのコードをTypeScriptで書いてCDKでデプロイしようとすると、CDKによるデプロイの外でトランスパイルしなければいかんよなぁ。。と思っていたんですが、今はそんなことしなくても良くなってるんですね。</p>



<span id="more-313"></span>



<h1 class="wp-block-heading">前提</h1>



<p>CDKとSAMがインストールされていること。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cdk --version
2.2.0 (build 4f5c27c)

sam --version
SAM CLI, version 1.40.1</code></pre></div>



<h1 class="wp-block-heading">やりたいこと</h1>



<p><a rel="noopener" href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-cdk-getting-started.html" target="_blank">Getting started with AWS SAM and the AWS CDK</a> でやってる内容を、デプロイするLambdaのコードをTypeScriptに変更して書く。</p>



<h1 class="wp-block-heading">やったこと</h1>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-8" checked><label class="toc-title" for="toc-checkbox-8">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"></li><li><a href="#toc1" tabindex="0">プロジェクトの作成</a></li><li><a href="#toc2" tabindex="0">リソースの作成</a></li><li><a href="#toc3" tabindex="0">CloudFormation templateの出力 &amp; SAMでローカル実行</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">プロジェクトの作成</span></h2>



<p>まずプロジェクトを作っておきます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>mkdir lambda-local-sam
cd lambda-local-sam
cdk init app --language typescript</code></pre></div>



<h2 class="wp-block-heading"><span id="toc2">リソースの作成</span></h2>



<p>あとはStackを書いて行きます。</p>



<p>Lambda Functionは、 <code>aws-lambda</code> モジュールを使用し、実行環境とコードのエントリーポイント、ハンドラを設定して作成します。Pythonの場合は以下。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="lambda-local-sam-stack.ts" data-lang="TypeScript"><code>import { Stack, StackProps } from &#39;aws-cdk-lib&#39;
import { Construct } from &#39;constructs&#39;
import * as path from &quot;path&quot;
import * as lambda from &#39;aws-cdk-lib/aws-lambda&#39;

export class LambdaLocalSamStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    new lambda.Function(this, &#39;MyFunction&#39;, {
      runtime: lambda.Runtime.PYTHON_3_7,
      handler: &#39;app.lambda_handler&#39;,
      code: lambda.Code.fromAsset(&#39;./lambda&#39;),
    })
  }
}</code></pre></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-python" data-file="lambda/app.py" data-lang="Python"><code>def lambda_handler(event, context):
    return &quot;Hello from SAM and the CDK!&quot;</code></pre></div>



<p>これに対してTypeScriptの場合は、実行環境をNode.jsにすることに加え、冒頭にも書きましたが、TypeScript -&gt; JavaScript にトランスパイルする必要があります。<br>愚直にスクリプトを組むという方法もありますが、<strong>言語固有モジュール</strong>を利用するとそれらの処理を暗黙的に行ってくれます。Node.jsの言語固有モジュールは <code>aws-lambda-nodejs</code> です。</p>



<p>実際のコードは以下の通りです。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="lambda-local-sam-stack.ts" data-lang="TypeScript"><code>import { Stack, StackProps } from &#39;aws-cdk-lib&#39;
import { Construct } from &#39;constructs&#39;
import * as path from &quot;path&quot;;
import * as nodeLambda from &#39;aws-cdk-lib/aws-lambda-nodejs&#39;

export class LambdaLocalSamStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    new nodeLambda.NodejsFunction(this, &#39;MyFunction&#39;, {
      entry: path.join(__dirname, &#39;../lambda/index.ts&#39;),
      handler: &#39;handler&#39;,
    })
  }
}</code></pre></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-file="lambda/index.ts" data-lang="TypeScript"><code>import { Handler } from &#39;aws-cdk-lib/aws-lambda&#39;

export const handler: Handler = async function () {
    return &quot;Hello from SAM and the CDK!&quot;;
}</code></pre></div>



<h2 class="wp-block-heading"><span id="toc3">CloudFormation templateの出力 &amp; SAMでローカル実行</span></h2>



<p>cdk synthコマンドでCloudFormationのtemplateを出力します (出力先は <code>cdk.out</code>)。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>cdk synth --no-staging</code></pre></div>



<p>出力されたtemplateを参照するようにsam localコマンドを実行します。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-js" data-lang="JavaScript"><code>sam local invoke MyFunction --no-event -t ./cdk.out/LambdaLocalSamStack.template.json
(略)
&quot;Hello from SAM and the CDK!&quot;</code></pre></div>



<p>Lambdaが実行されたことが確認出来ました。</p>



<h1 class="wp-block-heading">参考</h1>



<p>AWS CDK による AWS Lambda コードの管理<br><a href="https://aws.amazon.com/jp/blogs/news/lambda-managed-by-cdk/">https://aws.amazon.com/jp/blogs/news/lambda-managed-by-cdk/</a></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
