LambdaでS3バケットのファイルをzip圧縮してみる

LambdaでS3バケットのファイルをzip圧縮してみる

S3バケットにあるファイルをLambdaでzipファイルに圧縮してみました。
Clock Icon2025.02.21

S3バケットにあるファイルをLambdaでzipファイルに圧縮してみました。

おすすめの方

  • S3バケットにあるファイルをLambdaでzipファイルに圧縮したい方

S3バケットやLambdaを作成する

sam init

sam init \
    --runtime python3.11 \
    --name lambda-s3-zip-sample \
    --app-template hello-world \
    --no-tracing \
    --no-application-insights \
    --structured-logging \
    --package-type Zip

SAMテンプレート

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: lambda-s3-zip-sample

Globals:
  Function:
    Timeout: 10
    LoggingConfig:
      LogFormat: JSON

Resources:
  Bucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: blog-lambda-zip-sample-bucket

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: blog-lambda-zip-sample-function
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.11
      Policies:
        - arn:aws:iam::aws:policy/AmazonS3FullAccess
      Environment:
        Variables:
          BUCKET_NAME: !Ref Bucket
      Architectures:
      - x86_64

  HelloWorldFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${HelloWorldFunction}

Lambdaコード

S3バケットのファイルをLambdaの/tmpにダウンロードしています。なお、/tmpのストレージサイズには制限があるので、ご注意ください。

import os
import boto3
import zipfile

from zipfile import ZipFile

BUCKET_NAME = os.getenv("BUCKET_NAME")

s3 = boto3.client("s3")

TARGET_FILES = [
    "hello.txt",
    "world.txt",
]

ZIP_FILE_NAME = "hello_world.zip"

def lambda_handler(event, context):
    # S3からファイルをダウンロード
    for target_file in TARGET_FILES:
        s3.download_file(BUCKET_NAME, target_file, f"/tmp/{target_file}")

    # zipに圧縮
    with ZipFile(
        f"/tmp/{ZIP_FILE_NAME}", "w", compression=zipfile.ZIP_STORED
    ) as zip_file:
        for target_file in TARGET_FILES:
            zip_file.write(f"/tmp/{target_file}", f"zip-{target_file}")

    # S3にアップロード
    s3.upload_file(f"/tmp/{ZIP_FILE_NAME}", BUCKET_NAME, ZIP_FILE_NAME)

デプロイ

sam deploy

動作を確認する

S3バケットに圧縮したいファイルを格納する

簡単に実験するため、2つのテキストファイルを用意します。

echo hello > hello.txt
echo world > world.txt

aws s3 cp hello.txt s3://blog-lambda-zip-sample-bucket/hello.txt
aws s3 cp world.txt s3://blog-lambda-zip-sample-bucket/world.txt

S3バケットを確認する

先ほどアプロードした2ファイルだけが存在します。

$ aws s3 ls blog-lambda-zip-sample-bucket

2025-02-21 13:34:25          6 hello.txt
2025-02-21 13:34:26          6 world.txt

Lambdaを実行する

aws lambda invoke \
    --function-name blog-lambda-zip-sample-function \
    output.txt

S3バケットを確認する

zipファイルが増えていました。期待通りですね。

$ aws s3 ls blog-lambda-zip-sample-bucket

2025-02-21 13:34:25          6 hello.txt
2025-02-21 14:10:24        238 hello_world.zip
2025-02-21 13:34:26          6 world.txt

zipファイルを取得し、解凍し、中身を確認する

aws s3 cp s3://blog-lambda-zip-sample-bucket/hello_world.zip hello_world.zip

解凍できました

$ unzip hello_world.zip

Archive:  hello_world.zip
 extracting: zip-hello.txt           
 extracting: zip-world.txt

中身も期待通りです。

$ cat zip-hello.txt

hello
$ cat zip-world.txt

world

さいごに

S3バケットにあるファイルをLambdaでzipファイルに圧縮してみました。どなたかの参考になれば幸いです。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.