Lambdaの新機能、コード保存先に自前S3バケットを使うREFERENCEモードの挙動を確認してみた

Lambdaの新機能、コード保存先に自前S3バケットを使うREFERENCEモードの挙動を確認してみた

Lambdaのcreate-functionに追加されたS3ObjectStorageMode=REFERENCEを使い、ユーザー管理のS3オブジェクトをコード保存先として参照する関数を作成しました。COPYモードとのコードストレージ容量カウントの違いや、S3オブジェクト削除時の挙動、CloudTrailでのアクセスログを検証します。
2026.07.01

はじめに

2026年6月29日、AWS Lambda にコードストレージの新オプションが追加されました。AWS CLI v2のChangelogには以下の記載があります。

api-change:lambda: Lambda now supports self-managed S3 buckets for Lambda code storage giving you the option for Lambda to reference a copy of your source code from your own S3 buckets. This allows you to maintain a single copy of your source code and manage your own code storage limits.

AWS CLI v2 CHANGELOG

create-function--codeパラメータにS3ObjectStorageModeが新設されています。従来のCOPY(Lambdaが内部ストレージにコードをコピー)に加えてREFERENCE(ユーザー管理のS3オブジェクトをコード保存先として参照)が選択可能です。

従来(COPYモード)と新方式(REFERENCEモード)の違いを表にまとめます。

項目 COPY(従来) REFERENCE(新)
コード保存先 Lambda内部ストレージにコピー ユーザー管理のS3オブジェクト
コードストレージ容量(75GB上限) カウントされる カウントされない

※ S3オブジェクト削除時の挙動は両モード共通です。今回の検証では、削除後も既存関数のinvokeは成功しました。一方、削除済みのS3オブジェクトを指定したupdate-function-codeは失敗します(NoSuchKey)。

Lambda Developer Guide — Creating functions using self-managed S3 buckets

本記事では、REFERENCEモードでLambda関数を作成・実行し、COPYモードとの挙動差を検証します。あわせてCloudTrailでS3オブジェクトレベルのアクセスログを取得し、Lambdaサービスがコードを取得する様子を確認します。

検証環境

  • リージョン: ap-northeast-1(東京)
  • ランタイム: Node.js 22.x
  • AWS CLI: 2.35.12

S3 バケットと IAM ロールの準備

テスト用のS3バケットとLambda実行ロールを作成します。

# テスト用 S3 バケット作成
aws s3api create-bucket \
  --bucket lambda-ref-mode-test-20260630-<ACCOUNT_ID> \
  --create-bucket-configuration '{"LocationConstraint": "ap-northeast-1"}' \
  --region ap-northeast-1
# Lambda 実行ロール作成
aws iam create-role \
  --role-name lambda-ref-mode-test-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "lambda.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

aws iam attach-role-policy \
  --role-name lambda-ref-mode-test-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

Lambda コードの準備と S3 へのアップロード

シンプルなハンドラを作成し、S3にアップロードします。

// index.mjs
export const handler = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: "Hello from Lambda with REFERENCE mode!",
      timestamp: new Date().toISOString(),
    }),
  };
};
zip function.zip index.mjs
aws s3 cp function.zip s3://lambda-ref-mode-test-20260630-<ACCOUNT_ID>/function.zip

REFERENCE モードで Lambda 関数を作成

--code パラメータの S3ObjectStorageMode=REFERENCE を指定して関数を作成します。

aws lambda create-function \
  --function-name lambda-ref-mode-test \
  --runtime nodejs22.x \
  --role arn:aws:iam::<ACCOUNT_ID>:role/lambda-ref-mode-test-role \
  --handler index.handler \
  --code S3Bucket=lambda-ref-mode-test-20260630-<ACCOUNT_ID>,S3Key=function.zip,S3ObjectStorageMode=REFERENCE \
  --region ap-northeast-1

invokeを実行します。

aws lambda invoke \
  --function-name lambda-ref-mode-test \
  --region ap-northeast-1 \
  response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

レスポンスボディ:

{"statusCode":200,"body":"{\"message\":\"Hello from Lambda with REFERENCE mode!\",\"timestamp\":\"2026-06-30T14:39:21.885Z\"}"}

COPY モードとの比較

同じコードを S3ObjectStorageMode=COPY(従来のデフォルト動作)で作成します。

aws lambda create-function \
  --function-name lambda-copy-mode-test \
  --runtime nodejs22.x \
  --role arn:aws:iam::<ACCOUNT_ID>:role/lambda-ref-mode-test-role \
  --handler index.handler \
  --code S3Bucket=lambda-ref-mode-test-20260630-<ACCOUNT_ID>,S3Key=function.zip,S3ObjectStorageMode=COPY \
  --region ap-northeast-1

invokeの結果はREFERENCEモードと同様です。違いはコードストレージ容量のカウントに現れます。

コードストレージ容量の比較

両モードの関数が存在する状態で get-account-settings を確認し、関数を個別に削除してTotalCodeSizeの変化を観測しました。

※ 検証アカウントには他の関数も存在するため、FunctionCountは11からスタートしています。

状態 TotalCodeSize FunctionCount 差分
両関数存在 6,440,304 11
REFERENCE 関数削除後 6,440,304 10 変化なし
COPY 関数削除後 6,439,969 9 -335 bytes

REFERENCEモードの関数を削除してもTotalCodeSizeは変わりませんでした。一方、COPYモードの関数を削除するとfunction.zipのサイズ(335 bytes)分だけ減少しています。

つまり、REFERENCE モードの関数はリージョン単位のコードストレージ容量(デフォルト 75GB)にカウントされません。大量のLambda関数をデプロイしてストレージ上限に達しがちな環境では、REFERENCEモードで関数を作成することでコードストレージ容量の消費を抑えられます。

S3 オブジェクト削除時の挙動

S3から function.zip を削除した後の挙動を確認しました。

aws s3 rm s3://lambda-ref-mode-test-20260630-<ACCOUNT_ID>/function.zip

invoke の結果

両モードとも、S3オブジェクト削除後に実行したinvokeは成功しました。ソースのS3オブジェクトが消えても、既にデプロイ済みの関数の実行には影響しませんでした。

update-function-code の結果

S3オブジェクトが削除された状態で update-function-code を実行すると、両モードとも NoSuchKey エラーで失敗しました。

InvalidParameterValueException: Error occurred while GetObject.
S3 Error Code: NoSuchKey. S3 Error Message: The specified key does not exist.

REFERENCEモードではコードの正本をS3で管理する運用となるため、ライフサイクルポリシーによる自動削除や誤削除に注意が必要です。

CloudTrail によるアクセスログの確認

REFERENCEモードでcreate-functionを実行したところ、LambdaサービスがsourceIPAddress: lambda.amazonaws.comでS3からGetObjectを行う様子がCloudTrailのデータイベントに記録されました。これにより、ユーザー操作とLambdaサービスの操作を区別して追跡できます。

以下のCloudTrail設定は、S3アップロード・create-function・削除操作を実行する前に有効化しています。

# Trail 作成
aws cloudtrail create-trail \
  --name lambda-ref-mode-s3-trail \
  --s3-bucket-name cloudtrail-lambda-ref-test-20260630-<ACCOUNT_ID> \
  --no-is-multi-region-trail \
  --no-include-global-service-events \
  --region ap-northeast-1

# 対象バケット限定でデータイベントを有効化
aws cloudtrail put-event-selectors \
  --trail-name lambda-ref-mode-s3-trail \
  --event-selectors '[{
    "ReadWriteType": "All",
    "IncludeManagementEvents": false,
    "DataResources": [{
      "Type": "AWS::S3::Object",
      "Values": ["arn:aws:s3:::lambda-ref-mode-test-20260630-<ACCOUNT_ID>/"]
    }]
  }]' \
  --region ap-northeast-1

# ロギング開始
aws cloudtrail start-logging --name lambda-ref-mode-s3-trail --region ap-northeast-1

配信されたログから以下のイベントを確認しました。

aws s3 cp s3://cloudtrail-lambda-ref-test-20260630-<ACCOUNT_ID>/AWSLogs/<ACCOUNT_ID>/CloudTrail/ap-northeast-1/2026/06/30/<ログファイ>.json.gz /tmp/ct-log.json.gz
gunzip /tmp/ct-log.json.gz
cat /tmp/ct-log.json | jq '.Records[] | {eventTime, eventName, sourceIPAddress, key: .requestParameters.key}'

実際に取得されたイベント(抜粋、IPアドレスはマスク済み):

{
  "eventTime": "2026-06-30T14:39:14Z",
  "eventName": "PutObject",
  "sourceIPAddress": "203.0.113.10",
  "key": "function.zip"
}
{
  "eventTime": "2026-06-30T14:39:14Z",
  "eventName": "GetObject",
  "sourceIPAddress": "lambda.amazonaws.com",
  "key": "function.zip"
}
{
  "eventTime": "2026-06-30T14:39:29Z",
  "eventName": "DeleteObject",
  "sourceIPAddress": "203.0.113.10",
  "key": "function.zip"
}

sourceIPAddresslambda.amazonaws.comになっているGetObjectイベントが、Lambdaサービスによるコード取得です。なお、S3からコードを指定する場合、このGetObjectはCOPY/REFERENCEのどちらでも発生します。今回の検証では、sourceIPAddressの値でユーザー操作とLambdaサービスの操作を区別できました。

まとめ

S3ObjectStorageMode=REFERENCEは、Lambdaのコード保存先としてユーザー管理のS3オブジェクトを利用できる新しい選択肢です。COPYモードと比べてLambda側のコードストレージ容量を消費しないため、同一コードを複数関数で参照する構成や、関数数が多い環境ではメリットが出る可能性があります。

ただし、コードの正本はS3側で管理することになるため、作成・更新時には参照先のオブジェクトが存在している必要があります。Lambdaのコード管理をS3側に寄せたい場合に検討できる機能ですが、参照先オブジェクトの削除や変更には注意が必要です。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事