はじめに
先日、AWS Lambda Web Functionが発表されました。
以前もLambda Function URLsという、Webから実行できるLambda関数が作れましたが、それはLambda関数として記述する必要があります。
Lambda Web Functionは、nodeコマンドで実行するコードで動かすことができます。
今回は、CloudShell上で作成してみます。その際、まずローカルで実行してからデプロイします。またAWSのリソースを操作する権限を付与してみます。
概要
CloudShellから、AWS Lambda Web Functionを作成します。
- まず、単純な内容を作成
- ローカルで実行してテスト
- デプロイして確認
- S3からファイルを読み取り、その内容を出力するよう変更
- S3を作成して、ローカルでテスト
- 権限を作成して、デプロイ時にアタッチ
参考
やってみた
以下の内容を、CloudShellで行っていきます。
ファイル作成
専用のフォルダを作って、その中にファイルを2つ作ります。
mkdir my-web-func
cd my-web-func
edit package.json
edit index.js
ファイルの内容はそれぞれ以下です。
{
"name": "my-lambda-web-app",
"version": "1.0.0",
"type": "module",
"main": "index.js",
"dependencies": {
"express": "^4.19.2"
}
}
import express from 'express';
const app = express();
// 1. AWS Lambda Web Functionsの環境変数からポートとホストを取得する
const endpoint = process.env.AWS_LAMBDA_HTTP_ENDPOINT;
const [host, port] = endpoint.split(':');
// 2. ルートエンドポイントの定義
app.get('/', (req, res) => {
res.json({
message: 'Hello from custom Node.js Lambda Web Function!',
timestamp: new Date().toISOString()
});
});
// 3. サーバーの起動
app.listen(port, host, () => {
console.log(`Server running at http://${host}:${port}`);
});
テスト起動
まずはCloudShellでNode.jsを動かすようにします。
npm install
その後、先ほど作成したコードをローカルで実行します。そのためAWS_LAMBDA_HTTP_ENDPOINTを指定して起動し、CURLで確認します。
AWS_LAMBDA_HTTP_ENDPOINT=127.0.0.1:3000 node index.js &
curl http://127.0.0.1:3000/
{"message":"Hello from custom Node.js Lambda Web Function!","timestamp":"2026-11-08T07:49:51.246Z"}
うまく動いたら、プロセスを切ります。
pkill -f node
AWS Lambda Web Functionとしてデプロイ
うまくいったら、aws lambda-web deployでデプロイです。
aws lambda-web deploy --name my-web-func --code . --create --region ap-northeast-1
コマンドの結果で、URLが発行されます。それに対してCURLを実行します。
curl https://xxxxxxxxxxxxxxxx.xxx.lambda-web.ap-northeast-1.on.aws/
うまく動いていることを確認したら、一度Lambda関数を削除します。
aws lambda-web delete-web-function --function-name my-web-func
S3を読み込むよう、変更
先に作った内容を修正して、S3から読み込んだファイルを返すようにします。
import express from 'express';
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
const app = express();
// 各種設定・クライアントの初期化
const s3 = new S3Client({ region: 'ap-northeast-1' });
const BUCKET_NAME = 'your-bucket-name';
// 1. AWS Lambda Web Functionsの環境変数からポートとホストを取得する
const endpoint = process.env.AWS_LAMBDA_HTTP_ENDPOINT;
const [host, port] = endpoint.split(':');
// 2. ルートエンドポイントの定義
app.get('/', (req, res) => {
res.json({
message: 'Hello from custom Node.js Lambda Web Function!',
timestamp: new Date().toISOString()
});
});
// S3からファイルを取ってくるルート
app.get('/load-file', async (req, res) => {
try {
const command = new GetObjectCommand({
Bucket: BUCKET_NAME,
Key: 'sample.txt',
});
const s3Response = await s3.send(command);
res.setHeader('Content-Type', s3Response.ContentType || 'text/plain');
s3Response.Body.pipe(res);
} catch (error) {
console.error(error);
res.status(500).json({ error: 'S3からの読み込みに失敗しました' });
}
});
// 3. サーバーの起動
app.listen(port, host, () => {
console.log(`Server running at http://${host}:${port}`);
});
S3が使えるように関連するパッケージをインストールします。
npm install @aws-sdk/client-s3
S3にはsample.txtというファイルを作っておきます。
その後、先ほどと同じように、ローカル実行します。URLの後ろにload-fileを付与して実行します。CloudShellを実行している権限がS3へのアクセス可であれば、うまく応答が返ってくるはずです。
AWS_LAMBDA_HTTP_ENDPOINT=127.0.0.1:3000 node index.js &
curl http://127.0.0.1:3000/load-file
S3の中身が出力されたら成功です。
hogehoge
mogemoge
変更後の内容でAWS Lambda Web Functionをデプロイ
このままデプロイしてもS3の権限を持っていないので、以下のようにエラーが返ってきます。
{"error":"S3からの読み込みに失敗しました"}
デプロイするときに関数にアタッチされているロールは、awscli-lambdaweb-[関数名]という名前で自動作成されています。
このロールにS3の権限を付与してもよいですが、今回はAmazonS3ReadOnlyAccessとAWSLambdaBasicExecutionRoleの権限を持つロールを作成しました。
作成したロールのARNを--execution-role-arnで指定してデプロイします。
aws lambda-web deploy --name my-web-func --code . --create --region ap-northeast-1 --execution-role-arn xxx
同じように発行されるURLをCURLで実行して、うまくいくことが確認できます。
curl https://xxxxxxxxxxxxxxxx.xxx.lambda-web.ap-northeast-1.on.aws/
curl https://xxxxxxxxxxxxxxxx.xxx.lambda-web.ap-northeast-1.on.aws/load-file
削除
- Lambdaは
aws lambda-web delete-web-function --function-name my-web-funcで削除 - IAM Roleは以下のが作成されていると思いますので、コンソールから削除します
- 自作したロール
awscli-lambdaweb-[関数名]
- ファイルを置いたS3
おわりに
今回は、新サービスAWS Lambda Web Functionを、CloudShellから作成してみました。
コードがLambdaに依存しない形式なので、ローカルでテストする例も行ってみました。
この記事がどなたかのお役に立てれば幸いです。
