LocalStack触ってみた
LocalStack とは
LocalStack は、AWS のクラウドサービスをローカル環境でエミュレートできるツールです。
何ができるか
主な特徴は以下の通りです:
- AWS の主要なサービス(S3、Lambda、DynamoDB など)をローカルで再現できる
- クラウドアプリケーションの開発やテストを、実際の AWS 環境を使わずにローカルで行える
- Docker を使って簡単に環境構築ができる
- AWS CLI や SDK を使って、実際の AWS と同じようにリソースを操作できる
- 無料版と有料版があり、無料版でも基本的なサービスは利用可能
ブラウザで確認ができる
画像のように aws のサービスを操作できます。
設定
- endpoint の設定(default は localhost:4566)
Edit
のボタンから設定できます - Region を設定
画面の上のところがrunning
になれば OK です。
下記からアカウント作成できます
LocalStack の導入方法
$ brew install localstack/tap/localstack-cli
$ localstack --version
どう使うか
いくつか使用したケースをご紹介したいと思います。
pytest で dynamodb
import boto3
import os
from conftest import set_env_vars
def create_dynamodb(dynamodb):
dynamodb.create_table(
TableName=TABLE_NAME,
KeySchema=[
{"AttributeName": "pk", "KeyType": "HASH"},
{"AttributeName": "sequence", "KeyType": "RANGE"},
],
AttributeDefinitions=[
{"AttributeName": "pk", "AttributeType": "S"},
{"AttributeName": "sequence", "AttributeType": "N"},
],
ProvisionedThroughput={"ReadCapacityUnits": 3, "WriteCapacityUnits": 3},
)
# ローカル環境セットアップに使う
if __name__ == "__main__":
TABLE_NAME = "test_table"
dynamodb = boto3.resource(
"dynamodb",
endpoint_url="http://localhost:4566",
region_name="ap-northeast-1",
aws_access_key_id="DUMMY",
aws_secret_access_key="DUMMY",
)
create_dynamodb(dynamodb)
上記のファイルを起動して dynamodb にtest_table
の名前を作成します。
python localstack.py
dynamodb を確認するとtest_table
の名前が確認できました。
test を実行
import boto3
def test_zenn():
dynamodb = boto3.resource(
"dynamodb",
endpoint_url="http://localhost:4566",
region_name="ap-northeast-1",
aws_access_key_id="DUMMY",
aws_secret_access_key="DUMMY",
)
table = dynamodb.Table("test_table")
table.put_item(
Item={
"pk": "test",
"sequence": 1,
"service": "test",
},
)
res = table.get_item(
Key={
"pk": "test",
"sequence": 1,
}
)
item = res.get("Item")
assert item.get("service") == "test"
上記のファイルを pytest で起動します。
pytest -k test_zenn
テストが成功して画面上にもデータが入ってることが確認できました。
gitHub Actions で pytest
こちらでは gitHubActions で pytest を動かす際に LocalStack を使ってみたいと思います。
事前準備
まずは、テストで使用する依存関係を requirements.txt にまとめます。今回は、pytest、boto3(AWS SDK)、および localstack-utils を使用します。
pytest==8.3.2
boto3==1.35.12
localstack-utils==1.0.1
GitHub Actions でのワークフロー設定
name: zenTest
on:
pull_request:
branches:
- develop
paths:
- .github/workflows/zenTest.yaml
workflow_dispatch:
jobs:
pytest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12.5"
- name: Run pytest
run: |
pip install -r requirements.txt
ENV=test python -m pytest
このワークフローでは、pytest が実行される前に、必要なパッケージをインストールし、ENV=test という環境変数を設定しています。
LocalStack を使った pytest テスト
次に、LocalStack を使用して DynamoDB テーブルを作成し、それを pytest でテストします。startup_localstack を使用して LocalStack を起動し、テスト終了後に stop_localstack で環境を停止します。
import boto3
import pytest
import os
from localstack_utils.localstack import startup_localstack, stop_localstack
@pytest.fixture
def table():
if os.environ["ENV"] == "test":
startup_localstack(gateway_listen="0.0.0.0:14566")
end_point = "http://localhost:14566"
else:
end_point = "http://localhost:4566"
dynamodb = boto3.resource(
"dynamodb",
endpoint_url=end_point,
region_name="ap-northeast-1",
aws_access_key_id="DUMMY",
aws_secret_access_key="DUMMY",
)
table = dynamodb.create_table(
TableName="test_table",
KeySchema=[
{"AttributeName": "pk", "KeyType": "HASH"},
{"AttributeName": "sequence", "KeyType": "RANGE"},
],
AttributeDefinitions=[
{"AttributeName": "pk", "AttributeType": "S"},
{"AttributeName": "sequence", "AttributeType": "N"},
],
ProvisionedThroughput={"ReadCapacityUnits": 3, "WriteCapacityUnits": 3},
)
yield table
stop_localstack()
# local実行
def test_zenn(table):
table.put_item(
Item={
"pk": "test",
"sequence": 1,
"service": "test",
},
)
# 値を取得
res = table.get_item(
Key={
"pk": "test",
"sequence": 1,
}
)
item = res.get("Item")
assert item.get("service") == "test"
LocalStack の起動と停止
このテストコードでは、startup_localstack を使用してテスト中に LocalStack の DynamoDB 環境を起動し、テスト終了後に stop_localstack を使用して環境をクリーンアップしています。
起動時
startup_localstack(gateway_listen="0.0.0.0:14566")
このコマンドで LocalStack が 0.0.0.0:14566 でリッスンし、ローカル環境で AWS DynamoDB をエミュレートします。
停止時
stop_localstack()
テストが終了した後に、stop_localstack を使って LocalStack をシャットダウンします。これにより、不要なリソースが解放されます。
まとめ
LocalStack を使用することで、GitHub Actions 上で AWS の環境をエミュレートし、効率的にテストを実行できます。今回は dynamodb のみを触りましたが、他にも s3 や lambda や SQS なども触れそうなので触ってみたいと思います。
Discussion