2026年7月、AWS Lambda に 自己管理型 S3 コードストレージ(Self-managed S3 code storage) という機能が追加されました。地味なアップデートに見えますが、Lambda の運用で長年ネックだった「コードストレージ上限」の問題を根本的に解決できる、実はかなり嬉しい機能です。
これまでの Lambda
従来、.zip でコードをデプロイすると、Lambda は Lambda 管理ストレージにコードのコピーを保存 していました。そしてこのストレージには リージョン・アカウントごとに上限 があります(以前は 75GB、現在は 300GB に引き上げられています)。
関数やレイヤーが増えていくと、この上限に当たってサポートケースで緩和申請する……という運用をしていたチームも少なくありませんでした。
自己管理型 S3 コードストレージのメリット
この機能を使うと、Lambda は 自分の S3 バケットにあるコードを直接参照 します。Lambda 側にコピーを持たないため、Lambda 管理ストレージのクォータを一切消費しません。バケットが許す限り、いくらでもコードを置けるようになります。
動作を制御するのが S3ObjectStorageMode というパラメータです。
COPY(デフォルト) … 従来どおり Lambda 管理ストレージにコピーREFERENCE… コピーを作らず、S3 のオブジェクトを直接参照
単に「上限回避」だけではなく、コードの実体が自分の S3 バケットに置かれることで、次のようなことが可能になります。
- 300GB のクォータの壁を超えられる — コードがクォータを消費しない
- コード成果物に S3 の機能をそのまま使える — バージョニング(必須)、クロスリージョンレプリケーション、ライフサイクルポリシー、Object Lock(改ざん防止)、KMS 暗号化、CloudTrail による取得監査など
- コードの単一の真実の場所(Single Source of Truth)を持てる — 中央の「アーティファクト用アカウント」に置き、複数アカウント・リージョンから参照する構成が作りやすい
- データレジデンシー要件を満たしやすい — コードの所在地を自分で統制・説明できる
注意点
この機能を使ったLambda関数は、コードレポジトリであるS3バケットの影響を常に受けます。
オブジェクトを削除したり、バケットポリシーを外したり、暗号化キーが使えなくなると、Lambda はコードにアクセスできなくなり、関数は Inactive 状態 に遷移します。従来の「Lambda に預けて放置」から、「自分で管理する自由と責任」を引き受ける形になります。
さっそくやってみる
Step1:S3 バケットを作成してバージョニングを有効化
この機能は「どのバージョンのオブジェクトを使うか」を Lambda が追跡するために S3 バージョニングが必須 です。新しい .zip をアップするたびに S3 が新バージョンを作り、Lambda はそれを識別します。バージョニングが無いと機能自体が使えません。
aws s3 mb s3://my-lambda-code-bucket-kameoncloud --region ap-northeast-1
aws s3api put-bucket-versioning \
--bucket my-lambda-code-bucket-kameoncloud \
--versioning-configuration Status=Enabledこの例では`kameoncloud`という名称をバケット名に入れていますが適宜皆さんように書き換えてください。
Step 2. テスト用のコードを作って .zip 化
まずは動作確認用の最小コードを用意します。lambda_handler が Lambda から呼ばれるエントリーポイントです。
cat > lambda_function.py << 'EOF'
def lambda_handler(event, context):
return {"statusCode": 200, "body": "Hello from self-managed S3 storage in Tokyo"}
EOF
zip my-function.zip lambda_function.pyStep 3. .zip を S3 にアップロードしてバージョン ID を取得
REFERENCE モードでは、参照する オブジェクトのバージョン ID を明示的に指定 します。アップロード時に返る VersionId を必ず控えておきます。
aws s3api put-object \
--bucket my-lambda-code-bucket-kameoncloud \
--key my-function.zip \
--body my-function.zip \
--region ap-northeast-1{
"ETag": "\"e01beaf15c33ebf9a78a1f56142867a8\"",
"ChecksumCRC64NVME": "hlnEY3yrw/8=",
"ChecksumType": "FULL_OBJECT",
"ServerSideEncryption": "AES256",
"VersionId": "3xAEIaDTNdLyuM4jOtFCd5MEzbuRRgyR"
}戻ってきた VersionIdを手元にメモしておきます。
Step 4. バケットポリシーで Lambda に読み取り権限を付与
Lambda サービス(lambda.amazonaws.com)が S3 のオブジェクトを読めるようにします。s3:GetObject と s3:GetObjectVersion の両方が必要です。さらに aws:SourceArn 条件で「この関数からのアクセスだけ許可」と絞り込むことで、意図しない関数からの読み取りを防ぎます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LambdaSelfManagedCodeAccess",
"Effect": "Allow",
"Principal": { "Service": "lambda.amazonaws.com" },
"Action": ["s3:GetObject", "s3:GetObjectVersion"],
"Resource": "arn:aws:s3:::my-lambda-code-bucket-kameoncloud/my-function.zip",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:lambda:ap-northeast-1:917561075114:function:my-function"
}
}
}
]
}aws s3api put-bucket-policy \
--bucket my-lambda-code-bucket-kameoncloud \
--policy file://bucket-policy.json \
--region ap-northeast-1Step 5. 実行ロールを用意する
Lambda 関数には、それが AWS の各サービスを操作するための 実行ロール が必要です。ここでポイントなのが、ロールの 信頼ポリシー(trust policy)で lambda.amazonaws.com を信頼している こと。これが無いと後の関数作成時に「The role defined for the function cannot be assumed by Lambda」というエラーになります。
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "lambda.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}
EOFaws iam create-role \
--role-name lambda-execution-role \
--assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy \
--role-name lambda-execution-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRoleこの手順では lambda-execution-role という名前のIAMロールを作成しています。すでに同じ名前のロールがある場合は、作成するロール名を変更してください。
Step 6. REFERENCE モードで関数を作成
:いよいよ本命です。--code の中で S3ObjectStorageMode=REFERENCE を指定するのがこの機能の肝です。これにより Lambda はコピーを作らず S3 を直接参照します。
まずAWS CLIをバージョンアップします。
# Linux (x86_64) の例
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip -o awscliv2.zip
sudo ./aws/install --update
aws --version次に関数を作成します。
sleep 15
aws lambda create-function \
--function-name my-function \
--runtime python3.12 \
--role arn:aws:iam::917561075114:role/lambda-execution-role \
--handler lambda_function.lambda_handler \
--code S3Bucket=my-lambda-code-bucket-kameoncloud,S3Key=my-function.zip,S3ObjectVersion=iN.JQIo36OnJZ5MWmr0WFuaGa_n3N4T5,S3ObjectStorageMode=REFERENCE \
--region ap-northeast-1バケット名、IAMロール名、VersionIdは皆さんの環境ごとにことなりますので書き換えてください。
{
"FunctionName": "my-function",
"FunctionArn": "arn:aws:lambda:ap-northeast-1:917561075114:function:my-function",
"Runtime": "python3.12",
"Role": "arn:aws:iam::917561075114:role/lambda-execution-role",
"Handler": "lambda_function.lambda_handler",
"CodeSize": 297,
"Description": "",
"Timeout": 3,
"MemorySize": 128,
"LastModified": "2026-08-02T01:53:57.825+0000",
"CodeSha256": "",
"Version": "$LATEST",
"TracingConfig": {
"Mode": "PassThrough"
},
"RevisionId": "dcea5673-8f57-40d1-8874-1345587d0977",
"State": "Pending",
"StateReason": "The function is being created.",
"StateReasonCode": "Creating",
"PackageType": "Zip",
"Architectures": [
"x86_64"
],
"EphemeralStorage": {
"Size": 512
},
"SnapStart": {
"ApplyOn": "None",
"OptimizationStatus": "Off"
},
"RuntimeVersionConfig": {
"RuntimeVersionArn": "arn:aws:lambda:ap-northeast-1::runtime:fb4a5cbb4aeb1909cf946882192e0e708d8756b3a866c3ab89a3cfcfffeca7bc"
},
"LoggingConfig": {
"LogFormat": "Text",
"LogGroup": "/aws/lambda/my-function"
}
}Step 7. 動作確認(invoke)
ではいよいよ動作確認です。
aws lambda invoke \
--function-name my-function \
--region ap-northeast-1 \
response.json
cat response.json{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
{"statusCode": 200, "body": "Hello from self-managed S3 storage in Tokyo"}Lambda側のマネージメントコンソールでは以下の通り Reference モードになっていることがわかります。


