この記事はRust+SvelteKit+CDKでRSS要約アプリを作ってみる Advent Calendar 2025の15日目の記事になります。
また、筆者が属している株式会社野村総合研究所のアドベントカレンダーもあるので、ぜひ購読ください。
はじめに
AWSのサーバレス環境を構築する際、毎回ビルドして検証するのは大きな手間がかかります。デプロイ自体にも時間がかかりますし、期待通りに動かなかった場合のデバッグもスムーズには進められません。
そのため、AWSのサーバレス環境を前提としたソースコードでありながら、ローカルでも動作を検証する方法が必要になります。今回は、AWSの環境をDockerを使ってローカルに再現できるLoaclStackを使用しました。
LocalStackとは
Dockerコンテナ上でAWSと同等の環境を構築できるプロダクトです。S3、DynamoDB、SQSなどの主要サービスのエンドポイントを提供し、AWS CLIやSDKから本物と同じようにアクセスできます。
有料プランが用意されていますが、無料でも主要なサービスは利用可能です。
実際に使用できるサービスは公式サイトを確認してください。
また、今回はLambdaをRustで書いています。今までの記事で紹介したcargo lambdaコマンドを使うことで、ローカルでLambdaを起動できます。
まとめると、
- LocalStackでS3やDynamoDBをローカルに用意する
- アプリからそのローカル上のリソースに向けて接続する
という流れになります。
SumaRSSでの実装
今回のWebアプリでは、localディレクトリに開発環境用の設定をまとめています。
LocalStackの起動 (docker-compose.yml)
まずは、local/docker-compose.ymlでLocalStackを定義する必要があります。
version: "3.8"
services:
localstack:
container_name: sumarss-localstack
image: localstack/localstack:latest
ports:
- "4566:4566" # Gateway Port
environment:
- SERVICES=dynamodb,s3,sqs,ssm,cloudformation,lambda,iam
- AWS_DEFAULT_REGION=ap-northeast-1
SERVICESには利用したいサービスをカンマ区切りで指定します。上記のサービスはすべて無料で利用できます。
これで docker-compose up -d すれば、http://localhost:4566 にローカルのAWS環境が立ち上がります。
アプリケーション側の対応
Rustコード側で、ローカル環境の場合にエンドポイントをLocalStackに向ける仕組みが必要です。
SumaRSSでは、AWS_ENDPOINT_URL環境変数が設定されている場合に、SDKのConfigを上書きするように実装しています(cdk/lambda/src/lib.rs)。
let dynamodb_config = if let Ok(endpoint_url) = std::env::var("AWS_ENDPOINT_URL") {
aws_sdk_dynamodb::config::Builder::from(&config)
.endpoint_url(endpoint_url)
.build()
} else {
// 本番環境(AWS)
aws_sdk_dynamodb::config::Builder::from(&config).build()
};
また、S3に関しては特に注意が必要です。LocalStackなどのローカル環境では、DNS解決の都合上、バケット名をサブドメインではなくURIパスとして扱う「パススタイル」でのアクセスを強制する必要があります。AWS SDK for Rustでは force_path_style(true) を設定することでこれを実現しています。
let s3_config = if let Ok(endpoint_url) = std::env::var("AWS_ENDPOINT_URL") {
debug!(endpoint_url = %endpoint_url, "Using custom S3 endpoint");
aws_sdk_s3::config::Builder::from(&config)
.endpoint_url(endpoint_url)
.force_path_style(true) // LocalStack利用時に必須
.build()
} else {
aws_sdk_s3::config::Builder::from(&config).build()
};
開発ワークフロー
実際の開発手順は以下のようになります。
LocalStack起動とリソース作成
docker-compose -f local/docker-compose.yml up -d
# awslocal(LocalStack用ラッパー)でテーブル作成などを行う
awslocal dynamodb create-table ...
awslocalは、LocalStack用のawsコマンドの代替です。実際のAWS環境ではなくLocalStackで起動したAWSリソースに対してawsコマンドと同じ操作が可能です。
https://docs.localstack.cloud/aws/integrations/aws-native-tools/aws-cli/#localstack-aws-cli-awslocal
用意したローカルのAWS環境に対してデータのセットアップを行いたい場合はこのawslocalコマンドを使用します。
イベント送信によるテスト
別のターミナルから、テスト用イベント(JSON)を送信してLambdaを実行します。
cargo lambda invoke collector --data-file local/test-event.json
cargo lambda invoke {関数名(基本的にbin配下のファイル名)}で該当のLambdaを起動できます。