0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Lambda Runtime のソースコードを抽出する方法:Node.js を例に

0
Posted at

AWS Lambda は非常に多くの言語の Runtime をサポートしていますが、実際には AWS Lambda の仕組みは言語に依存しない Lambda Runtime API に基づいています。
公式の各言語の Runtime はすべて Lambda Runtime API を基に実装されており、handler のロード機構も同様です。

では、各言語の Runtime がどのように実装されているか、また handler がどのようにロードされるかを確認したい場合はどうすればよいのでしょうか?

この記事では、Node.js Runtime の抽出を例にこの問題を議論します。

Lambda から直接 Runtime ファイルを抽出する

Lambda の起動時に /var/runtime/bootstrap がロードされることは分かっています。そうなると、/var/runtime ディレクトリには一体どのようなファイルがあるのか気になるところです。

そこで、Node.js の Lambda 関数を作成し、関数内で /var/runtime ディレクトリのファイル一覧をログに出力する方法でこの問題を調べてみましょう。

Lambda 関数を作成したら、以下の handler コードを記述します:

import fs from "node:fs/promises";

export const handler = async () => {
  console.log("== /var/runtime ==");
  try {
    console.log(await fs.readdir("/var/runtime"));
  } catch (e) {
    console.log("fail /var/runtime:", e.message);
  }

  return "ok";
};

この Lambda 関数を実行してログを確認すると、結果は以下のとおりです。

Function Logs:
2026-02-17T15:08:34.735Z	441910a6-5f21-4d67-b972-ef2a90133c0b	INFO	== /var/runtime ==
2026-02-17T15:08:34.754Z	441910a6-5f21-4d67-b972-ef2a90133c0b	INFO	[
  'THIRD-PARTY-LICENSES.txt',
  'bootstrap',
  'ca-cert.pem',
  'index.mjs',
  'node_modules',
  'rapid-client.node',
  'runtime-release'
]

/var/runtime ディレクトリには bootstrap ファイルのほかに、index.mjsnode_modules などのファイルがあることが分かります。これらのファイルが Node.js Runtime の実装であると考えてよいでしょう。

/var/runtime ディレクトリを zip に圧縮し、バイナリファイルとして呼び出し元に返すことで、対応するファイルを抽出してみましょう。

/var/runtime ディレクトリを zip で圧縮する

上記の作業を行うために、以下の準備が必要です。

  1. 圧縮処理に時間がかかる可能性があるため、Lambda 関数のデフォルトタイムアウトは 3 秒しかないので、タイムアウトをより長い時間(例えば 1 分)に変更する必要があります。
  2. メモリ不足を防止するために、メモリを 512MB に変更します。
  3. Lambda 関数の設定で Function URL を有効にし、AuthNONE に設定することで、curl を使って直接 Lambda 関数を呼び出し、圧縮済みの zip ファイルをダウンロードできるようにします。

次に、ローカルでディレクトリを作成し、Lambda 用の関数を記述します。

mkdir dump-nodejs-runtime
cd dump-nodejs-runtime
npm init -y
npm i archiver
touch index.mjs

Lambda の実行環境(instance)には zip コマンドが存在しないため、npm i archiverarchiver パッケージをインストールして zip 圧縮機能を実現する必要があります。

handler コードは以下のとおりです。

import archiver from "archiver";
import fs from "node:fs";
import fsp from "node:fs/promises";

export const handler = async () => {
  const outPath = "/tmp/var-runtime.zip";

  const out = fs.createWriteStream(outPath);
  const zip = archiver("zip", { zlib: { level: 9 } });

  zip.on("error", (e) => { throw e; });
  out.on("error", (e) => { throw e; });

  zip.pipe(out);
  zip.glob("**/*", { cwd: "/var/runtime", dot: true, ignore: ["node_modules/**"] });
  await zip.finalize();
  await new Promise((r) => out.on("close", r));

  const st = await fsp.stat(outPath);
  console.log("zip size bytes:", st.size);


  const b64 = (await fsp.readFile(outPath)).toString("base64");
  return {
    statusCode: 200,
    isBase64Encoded: true,
    headers: {
      "content-type": "application/zip",
      "content-disposition": 'attachment; filename="var-runtime.zip"',
      "cache-control": "no-store",
    },
    body: b64,
  };
};

上記の handler は /var/runtime ディレクトリ配下のすべてのファイルを zip に圧縮し(node_modules ディレクトリを除く)、圧縮した zip ファイルを呼び出し元に返します。これにより、Function URL を通じて圧縮された Runtime パッケージをダウンロードできます。

次に、作成した Lambda 関数を zip に圧縮して Lambda にアップロードし、ブラウザで対応する Function URL にアクセスすれば、圧縮された Runtime パッケージをダウンロードできます。

zip -r ../dump-nodejs-runtime.zip .
# この zip パッケージを Lambda にアップロードする
# 対応する Function URL にアクセスすれば、圧縮された Runtime パッケージをダウンロードできる

zip ファイル var-runtime.zip をダウンロードして解凍すると、以下のファイルが得られます。

bootstrap
index.mjs
rapid-client.node
THIRD-PARTY-LICENSES.txt
ca-cert.pem
node_modules
runtime-release

他の言語の Lambda Runtime を抽出したい場合も、同様の方法で行えます。

Docker イメージから直接 Runtime を抽出する

上記の方法は公式の Lambda から Runtime ファイルを抽出できますが、手順がやや煩雑です。

実は、もっと簡単に Runtime ファイルを抽出する方法があります。

AWS は公式 Lambda Runtime を含む Docker イメージを公式に提供しており、これらのイメージから直接抽出できます。

https://gallery.ecr.aws/lambda

これらのイメージには公式の Lambda Runtime が格納されており、直接抽出できます。

Node.js の場合、public.ecr.aws/lambda/nodejs:24 イメージから対応するファイルを抽出できます。以下のコマンドを実行してコンテナに入ります。

docker run -it --rm --entrypoint /bin/sh public.ecr.aws/lambda/nodejs:24

コンテナ内で /var/runtime ディレクトリのファイルを確認すると、上記の公式 Lambda と同じ内容であることが分かります。


sh-5.2# ls -al /var/runtime
total 696
drwxr-xr-x 1 root root   4096 Feb 17 14:26 .
drwxr-xr-x 1 root root   4096 Feb 17 15:29 ..
-rwxr-xr-x 1 root root   4033 Feb  3 16:44 bootstrap
-rw-r--r-- 1 root root 181066 Feb  3 16:49 ca-cert.pem
-rw-r--r-- 1 root root  54889 Feb  3 16:49 index.mjs
drwxr-xr-x 3 root root   4096 Feb 17 14:26 node_modules
-rwxr-xr-x 1 root root 343376 Feb  3 16:49 rapid-client.node
-rw-r--r-- 1 root root     63 Feb  3 16:49 runtime-release
-rw-r--r-- 1 root root 104462 Feb  3 16:44 THIRD-PARTY-LICENSES.txt

したがって、コンテナから /var/runtime ディレクトリを直接コピーすればよいだけです。

docker create --platform=linux/amd64 --name lambda24 public.ecr.aws/lambda/nodejs:24
docker cp lambda24:/var/runtime ./var-runtime
docker rm lambda24

実行完了後、ローカルの ./var-runtime ディレクトリに Node.js 24 の Runtime ファイルが格納されます。

最後に、抽出したファイルを こちら にアップロードしました

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?