AWS LambdaでS3 Filesを使い、S3バケットをマウントして読み込む方法

AWS LambdaからAmazon S3のデータを処理する際、従来はboto3(get_object)を用いてメモリ上にダウンロードして処理するのが一般的でした。

しかし、2026年4月にリリースされた新機能「Amazon S3 Files」により、新たな方法が利用できるようになりました。S3バケットをNFS経由でファイルシステムとして直接マウントできるようになり、Lambdaからの利用もサポートされました。

本記事では、この新機能「S3 Files」をLambdaに紐付け、10万件以上のレコードを含むアクセスログ(CSV)をローカルファイル(/mnt/data/…)として直接読み込む手順と、ネットワークや権限設定で注意すべきポイントを解説します。

全体アーキテクチャの概要

  1. Amazon S3:大量のログデータ(CSV)を保存するストレージ。
  2. Amazon S3 Files【2026年4月新機能】:S3をファイルシステム(NFSプロトコルベース)として公開する新機能。
  3. AWS Lambda:VPC内で動作し、S3 Filesのマウント機能を介して、ローカルパス/mnt/data経由でS3上のファイルに直接アクセスする実行環境。

VPCネットワークとルーティング設定のポイント

LambdaからS3 Files(マウントターゲット)へ安全に接続するためには、VPC内のネットワーク設計およびルーティングが正しく構成されている必要があります。実装の際は以下の点を確認してください。

  1. サブネットの配置とルーティング
    1. Lambda関数がデプロイされているサブネット(プライベートサブネットなど)のルートテーブルにおいて、マウントターゲットが存在するサブネットやネットワークインターフェイス(ENI)への通信経路が適切に確保されていること。
  2. セキュリティグループの相互通信
    1. マウントターゲット側(NFSポート2049)が、Lambda側のセキュリティグループからのインバウンド通信を許可していること。
  3. AWSサービスへのアクセス(VPCエンドポイントやNAT)
    1. Lambdaから各AWSサービス(S3やS3 FilesのコントロールプレーンAPIなど)へアクセスできるよう、NAT Gatewayや適切なVPCエンドポイント(Interface Endpoint)を経由する通信経路が確保されていること。

構築・検証の手順

①S3 Filesアクセスポイントの作成

S3 Filesアクセスポイントの作成

まず、S3バケット上の特定のプレフィックスをルートディレクトリとするアクセスポイントを作成します。

Bash

aws s3files create-access-point \
  --file-system-id <YOUR_FILE_SYSTEM_ID> \
  --root-directory '{"path": "/lambda", "creationPermissions": {"ownerUid": 1000, "ownerGid": 1000, "permissions": "755"}}' \
  --region ap-northeast-1

②ネットワークとセキュリティグループの調整(トラブルシューティング)

Lambdaからマウントターゲット(NFS:ポート2049)への通信を許可するため、マウントターゲットのセキュリティグループに対して、Lambdaのセキュリティグループからのインバウンドルール(TCP 2049)を追加します。

Bash

# マウントターゲットのSGに対してLambdaのSGからのNFS(2049)通信を許可

aws ec2 authorize-security-group-ingress \
  --group-id <MOUNT_TARGET_SECURITY_GROUP_ID> \
  --protocol tcp \
  --port 2049 \
  --source-group <LAMBDA_SECURITY_GROUP_ID> \
  --region ap-northeast-1

③IAMロールの権限設定

Lambdaの実行ロールに対し、S3 Filesの接続権限および対象S3バケットへのアクセス権限(s3:GetObjectなど)を付与します。

ポリシー例(policy.json):

JSON

{
              "Version": "2012-10-17",
              "Statement": [
                            {
                                          "Sid": "AllowEFSMountPermissions",
                                          "Effect": "Allow",
                                          "Action": [
                                                        "elasticfilesystem:ClientMount",
                                                        "elasticfilesystem:ClientWrite",
                                                        "elasticfilesystem:ClientRootAccess",
                                                        "elasticfilesystem:DescribeMountTargets",
                                                        "elasticfilesystem:DescribeFileSystems"
                                          ],
                                          "Resource": "*"
                            },
                            {
                                          "Sid": "AllowS3Access",
                                          "Effect": "Allow",
                                          "Action": [
                                                        "s3:GetObject",
                                                        "s3:PutObject",
                                                        "s3:ListBucket"
                                          ],
                                          "Resource": [
                                                        "arn:aws:s3:::infrastructurecomposer",
                                                        "arn:aws:s3:::infrastructurecomposer/*"
                                          ]
                            },
                            {
                                          "Sid": "AllowS3ExpressMountPermissions",
                                          "Effect": "Allow",
                                          "Action": [
                                                        "s3express:CreateSession"
                                          ],
                                          "Resource": "*"
                            },
                            {
                                          "Sid": "AllowVPCAccessForS3Files",
                                          "Effect": "Allow",
                                          "Action": [
                                                        "ec2:CreateNetworkInterface",
                                                        "ec2:DescribeNetworkInterfaces",
                                                        "ec2:DeleteNetworkInterface"
                                          ],
                                          "Resource": "*"
                            },
                            {
                                          "Sid": "AllowCloudWatchLogs",
                                          "Effect": "Allow",
                                          "Action": [
                                                        "logs:CreateLogGroup",
                                                        "logs:CreateLogStream",
                                                        "logs:PutLogEvents"
                                          ],
                                          "Resource": "arn:aws:logs:*:*:*"
                            }
              ]
}

④Lambdaのファイルシステム設定

Lambdaのファイルシステム設定

Lambda関数にファイルシステム(S3 Files)を紐付けます。AWSコンソールまたはAWS CLIを用いて設定を行います。

  • ファイルシステム/アクセスポイント:先ほど作成したS3 Filesのファイルシステムおよびアクセスポイントを指定します。
  • ローカルマウントパス:Lambdaコンテナ内でのマウント先として/mnt/dataを指定します(※Lambdaのファイルシステムマウントパスは必ず/mnt/で始める必要があります)。

AWS CLIで設定する場合のコマンド例:

Bash

aws lambda update-function-configuration \
  --function-name prd-log-processor-s3stream \
  --file-system-configs '[{
      "Arn": "arn:aws:elasticfilesystem:ap-northeast-1:440022655707:access-point/fsap-0c98f3fa1d57181e4",
      "LocalMountPath": "/mnt/data"
  }]' \
  --region ap-northeast-1

S3 FilesのアクセスポイントとLambdaのパスの関係

ここまでで設定した「S3 Filesのアクセスポイント」と「Lambda内のマウントパス(/mnt/data)」がどのように対応しているのかを整理します。

項目概要今回の設定例
S3 FilesアクセスポイントS3バケット内のどのフォルダ(プレフィックス)をルートとして公開するかを定義するエンドポイント/lambdaフォルダを起点とするアクセスポイント
LambdaのローカルマウントパスLambda関数のコンテナ内で、どのディレクトリ(パス)としてマウントするかを定義する設定/mnt/data

【実際のパスの対応関係】 S3バケットの対象プレフィックス(例:/lambda/)の中にあるファイル(例: large_dataset2.csv)は、Lambdaコンテナ内では/mnt/data/large_dataset2.csvとして参照できます。これにより、ローカルディスク上のファイルと同様に読み込み・処理が可能になります。

Lambda関数の実装

S3 FilesによってLambdaのコンテナ内(/mnt/data)にマウントされたディレクトリから、通常のファイル読み込みと同様にCSVをパースします。API経由でファイルをダウンロードするコードを記述する必要がなく、コードがシンプルになります。

lambda_function.py:

Python

import json
import csv
from collections import Counter

# S3 Filesでマウントされたローカルパス
FILE_PATH = "/mnt/data/large_dataset.csv"

def lambda_handler(event, context):
    try:
        total_records = 0
        status_code_counts = Counter()
        total_response_time = 0

        # 通常のファイルIOとして安全に読み込み
        with open(FILE_PATH, mode='r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            for row in reader:
                total_records += 1
                status = row.get('status_code', 'UNKNOWN')
                status_code_counts[status] += 1
                try:
                    total_response_time += float(row.get('response_time_ms', 0))
                except ValueError:
                    pass

        avg_response_time = (
            round(total_response_time / total_records, 2) if total_records > 0 else 0
        )

        return {
            'statusCode': 200,
            'body': json.dumps({
                'message': 'Successfully processed access log via S3 Files mount',
                'summary': {
                    'total_records_processed': total_records,
                    'average_response_time_ms': avg_response_time,
                    'status_code_breakdown': dict(status_code_counts)
                }
            }, ensure_ascii=False)
        }

    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }

実行結果とパフォーマンス

Lambda関数の実行結果

設定完了後、Lambdaを呼び出すと以下の通り正常に処理が完了します。

JSON

{
  "statusCode": 200,
  "body": "{\"message\": \"Successfully processed access log via EFS/S3 Files mount\", \"summary\": {\"total_records_processed\": 100000, \"average_response_time_ms\": 254.62, \"status_code_breakdown\": {\"200\": 100000}}}"
}
  • 処理レコード数:100,000件のCSVレコード
  • 実行時間(Duration):約1.3秒〜2.0秒台(ウォーム時)
  • メリット:従来のboto3による全件ダウンロード処理に比べ、メモリ消費量を抑えながら、Python標準のファイル操作API(open()やcsvモジュール)をそのまま利用したシンプルな実装が可能です。

まとめ

2026年4月にリリースされたAmazon S3 FilesをLambdaと組み合わせることで、S3上のファイルをローカルディスク上のファイルと同様に扱うというアプローチが可能になりました。

既存コードの変更を抑えながら、一般的なファイル操作でデータを高速処理できるため、サーバーレスアーキテクチャにおいて有効な選択肢になります。S3 Filesを活用したデータ処理を検討する際の参考にしてください。