はじめに
自分:
「AWS周り、LocalStack使ってテスト実装したいな〜、そういえばLocalStackそのうち認証必須になるみたいな話聞いた気がするな〜」
Gemini先生:
「その情報感度の高さ、素晴らしいです!おっしゃる通り、LocalStackはまさに数日後(2026年3月23日)から仕様変更が行われ、無料のCommunity版であっても認証(アカウント作成とAuth Tokenの発行)が必須になります。」
ナヌ!??
ということでLocalStack for AWSの使い方と、認証方法を調べてみました。
LocalStack for AWSの使い方
AWSリソースをローカル(テストや開発)で使いたい時に使用できるエミュレータです。
簡単な使用例を、PythonとDocker Composeで書いてみます。
コード側では、boto3のエンドポイントにLocalStackを指定しておき、他は普段使うboto3のコードを使用します。
import boto3
import os
endpoint_url = "http://localhost:4566"
bucket_name = "test-bucket"
file_name = "sample.txt"
def main():
# S3 client
s3 = boto3.client(
"s3",
endpoint_url=endpoint_url,
region_name="us-east-1",
aws_access_key_id="test",
aws_secret_access_key="test",
)
# Create a bucket
s3.create_bucket(Bucket=bucket_name)
print(f"Bucket '{bucket_name}' created.")
# Create a sample file
with open(file_name, "w") as f:
f.write("Hello from LocalStack!")
# Upload the file
s3.upload_file(file_name, bucket_name, file_name)
print(f"File '{file_name}' uploaded to bucket '{bucket_name}'.")
# List objects in the bucket
response = s3.list_objects_v2(Bucket=bucket_name)
print("Objects in bucket:")
for obj in response.get("Contents", []):
print(obj["Key"])
# Clean up local file
os.remove(file_name)
if __name__ == "__main__":
main()
docker-compose.ymlで、localstackのイメージを使用するように書きます。
version: '3.8'
services:
localstack:
image: localstack/localstack
ports:
- "4566:4566"
実際にコードを実行すると、
$ docker compose up -d
# pip installは実行した前提で
$ python main.py
Bucket 'test-bucket' created.
File 'sample.txt' uploaded to bucket 'test-bucket'.
Objects in bucket:
sample.txt
LocalStackを使うことで、ローカルでAWSを使っている時と同じコードで実行することができます。
無料プランでは使えるリソースに限りはありますが、それでも30以上のリソースが使用可能です。
(本題) 認証方法
ここからが本題です。今までは上の使用方法で使用できていたLocalStackですが、2026/3/23以降、最新イメージをプルして動かす場合には無料プランを使用する場合であっても、認証が必須になります。
Migration checklist (practical steps)にステップが書いてあり、
- LocalStackアカウントを作成する
- Authトークンを取得する
- 環境変数に設定する
- ローカル実行用は Personal / Developer Auth Token を設定
- CI用トークンを発行して環境変数(secretなど)設定する
- CI実行用は CI Auth Tokenを設定
今回はローカルでdocker-composeで動かす例を挙げたので、Personal Auth Tokenを取得し、.envに配置します
LOCALSTACK_AUTH_TOKEN=ls-xxxx....
docker-compose側は、環境変数LOCALSTACK_AUTH_TOKENを設定します
version: '3.8'
services:
localstack:
image: localstack/localstack
ports:
- "4566:4566"
+ environment:
+ - LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN}
これで、認証必須になって以降も、最新バージョンのイメージで使用ができます
他の選択肢
認証をせずに使いたい、という場合は
- 旧バージョンにピン留めをする
version: '3.8'
services:
localstack:
- image: localstack/localstack
+ image: localstack/localstack:4.12 # バージョン指定の例
ports:
- "4566:4566"
古いバージョンで固定するため、最新の変更が反映されないリスクはあります
- 別のモックを使用する
ここでは1つの例として、motoを紹介します。
import boto3
import os
from moto import mock_s3
bucket_name = "test-bucket"
file_name = "sample.txt"
@mock_s3
def main():
# S3 client (moto automatically intercepts boto3 calls)
s3 = boto3.client(
"s3",
region_name="us-east-1",
aws_access_key_id="test",
aws_secret_access_key="test",
)
# Create a bucket
s3.create_bucket(Bucket=bucket_name)
print(f"Bucket '{bucket_name}' created.")
# Create a sample file
with open(file_name, "w") as f:
f.write("Hello from Moto!")
# Upload the file
s3.upload_file(file_name, bucket_name, file_name)
print(f"File '{file_name}' uploaded to bucket '{bucket_name}'.")
# List objects in the bucket
response = s3.list_objects_v2(Bucket=bucket_name)
print("Objects in bucket:")
for obj in response.get("Contents", []):
print(obj["Key"])
# Clean up local file
os.remove(file_name)
if __name__ == "__main__":
main()
先ほどとの違いとして、motoをimportし、デコレートしています。
エミュレータを必要としない場合(単体テストなど)は、サーバーを立ち上げる必要がないmotoも選択肢の一つとしておすすめです。