LocalStack を使用してローカルに S3 環境を構築する

AWS

はじめに

LocalStack とは AWS のサービスを擬似的に使用できるモックフレームワークです。
Docker イメージも公開されており、手軽にローカルに AWS 環境を構築することが可能です。
本記事では LocalStack を使用してローカルに S3 環境を構築します。

環境

以下の環境で動作を確認しています。

$ docker compose version
Docker Compose version v2.2.3

手順

以下のファイルを準備します。LocalStack の立ち上げ自体は docker-compose.yml だけで可能です。

$ tree
.
├── create_bucket.py
├── deploy_file.py
├── docker-compose.yml
├── setup.sh
└── test_data
    ├── test1.txt
    └── test2.txt

docker-compose.yml は公式のリポジトリのものをほとんどそのまま流用します。

version: "3.8"

services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
    image: localstack/localstack
    ports:
      - "127.0.0.1:4566:4566"            # LocalStack Gateway
      - "127.0.0.1:4510-4559:4510-4559"  # external services port range
    environment:
      - DEBUG=${DEBUG-}
      - PERSISTENCE=${PERSISTENCE-}
      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}
      - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
バケットを作成する Python プログラム(create_bucket.py)です。
boto3 を使用し、endpoint_url に localhost の 4566 ポートを指定することで、立ち上げた LocalStack に対してリクエストをすることが可能です。
※ LocalStack v0.11.0 以降は使用するサービスごとにポートをして指定する必要はなくなりました。(参考)
Release LocalStack release 0.11.0 · localstack/localstack
Change Log: LocalStack release 0.11.0 1. New Features add Edge service as central API entry point (may become a breaking change in the future) implement taggin...
import sys

import boto3

BUCKET_NAME = sys.argv[1]
REGION_NAME = 'ap-northeast-1'

s3 = boto3.resource(
        service_name = 's3',
        endpoint_url='http://localhost:4566',
        region_name=REGION_NAME,
        )

def main():
    bucket = s3.create_bucket(
        Bucket=BUCKET_NAME,
        CreateBucketConfiguration={'LocationConstraint': REGION_NAME}
        )

if __name__ == '__main__':
   main()

ストレージ上にファイルを配置する Python プログラム(deploy_file.py)です。

import os
import sys

import boto3

BUCKET_NAME = sys.argv[1]
REGION_NAME = 'ap-northeast-1'

SOURCE_PATH = './test_data/'
TARGET_PATH = 'test'


s3 = boto3.resource(
        service_name = 's3',
        endpoint_url='http://localhost:4566',
        region_name=REGION_NAME,
        )
bucket = s3.Bucket(BUCKET_NAME)

def main():
    list_file_name =  os.listdir(SOURCE_PATH)
    for file in list_file_name:
        bucket.upload_file(f'{SOURCE_PATH}/{file}', f'{TARGET_PATH}/{file}')

if __name__ == '__main__':
   main()

上記のプログラムを実行すると、バケットの作成、ファイルのアップロードを行います。

$ python3 create_bucket.py s3-local

$ python3 deploy_file.py s3-local
$ aws s3 ls s3-local --endpoint-url http://localhost:4566 --recursive
2022-09-24 05:53:25          4 test/test1.txt
2022-09-24 05:53:25          4 test/test2.txt

上記の手順をまとめたものが以下になります。

#!/bin/sh

BUCKET_NAME=s3-local

# LocalStack
docker compose down
docker compose up -d
echo "waiting for the start of LocalStack"
sleep 3

# バケットの作成
python3 create_bucket.py $BUCKET_NAME

# ファイルの配置
python3 deploy_file.py $BUCKET_NAME

おわりに

本記事では LocalStack を使用してローカルに S3 環境を構築する方法をまとめました。S3 以外にも構築可能なサービスは多くありますので複数のサービスが関連するプログラムのテストにも利用できそうです。
この記事がどなたかの参考になれば幸いです。

参考

コメント