LoginSignup
9

More than 1 year has passed since last update.

AWSサービスのローカル環境を構築 (LocalStack)

Last updated at Posted at 2022-01-18

AWSサービスに接続するソフトウェア開発の際の、
ローカル環境構築に便利な LocalStack の紹介

前提知識

  • Docker と docker-compose の知識
  • AWS CLI コマンド の知識

Dockerで実行する

LocalStackのDockerイメージは単一のDockerコンテナで各種AWSのローカルモック環境を実行できます

docker-compose.yml設定例
version: '3.8'

services:
  localstack:
    container_name: localstack
    image: localstack/localstack:0.13.3
    environment:
      SERVICES: s3,dynamodb
      EDGE_PORT: 4566
    ports:
      - '4566:4566'

環境変数

  • 起動するサービスをSERVICES 環境変数でカンマ区切りで指定します
    上記の例では S3 と DynamoDB を起動しています
  • EDGE_PORT エンドポイントのポート番号を設定。デフォルトは 4566
  • その他の環境変数の詳細はこちら

起動

docker compose up -d

ホスト側から AWS CLI で接続

Access Key ID と Secret Access Key を test にする

$ aws configure --profile default
AWS Access Key ID [None]: test
AWS Secret Access Key [None]: test
Default region name [None]: ap-northeast-1
Default output format [None]: json

awsコマンドに endpoint パラメータを指定して実行

S3バケット一覧を取得する例
aws s3 ls --endpoint=http://localhost:4566

プログラムからの接続

Go (AWS-SDK-Go v2)

S3バケット一覧を取得する例
package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

var EndpointURL = "http://localhost:4566"

func main() {
    cfg, err := config.LoadDefaultConfig(
        context.TODO(),
        // EndpointResolverでエンドポイントURLを設定
        config.WithEndpointResolverWithOptions(
            aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
                if EndpointURL != "" {
                    return aws.Endpoint{
                        URL: EndpointURL,
                    }, nil
                }
                return aws.Endpoint{}, &aws.EndpointNotFoundError{}
            }),
        ),
    )
    if err != nil {
        log.Fatalf("LoadDefaultConfig failed:%v", err)
    }
    client := s3.NewFromConfig(cfg, func(o *s3.Options) {
        // UsePathStyle を設定する
        o.UsePathStyle = true
    })

    // 3S バケット一覧を表示
    output, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
    if err != nil {
        log.Fatalf("s3.ListBuckets failed:%v", err)
    }
    for _, v := range output.Buckets {
        log.Println(*v.Name)
    }
}

NodeJS (aws-sdk-v3)

S3バケット一覧を取得する例
import { S3 } from "@aws-sdk/client-s3";

const s3 = new S3({
    endpoint: "http://localhost:4566",
});

(async () => {
    // バケット一覧を取得
    const output = await s3.listBuckets({});
    const bucketList = output?.Buckets?.map((bucket) => {
        return bucket.Name;
    });
    console.log(bucketList);
})().catch((err) => {
    console.error(err);
});

初期化スクリプト

コンテナ起動時に自動実行するスクリプトを実行できる

docker-compose.yml
version: '3.8'

services:
  localstack:
    container_name: localstack
    image: localstack/localstack:0.13.3
    platform: linux/amd64
    environment:
      SERVICES: s3,dynamodb
      INIT_SCRIPTS_PATH: /init/scripts
      DEFAULT_REGION: 'ap-northeast-1'
    ports:
      - '4566:4566'
    volumes:
      - ./init/scripts:/init/scripts:ro
      - ./init/data:/init/data:rw
  • 環境変数INIT_SCRIPTS_PATH でコンテナ起動時に自動的に実行されるスクリプトの配置ディレクトリを指定する
  • この例ではコンテナ内の /init/scripts ディレクトリ指定し、ここにホスト側のディレクトリ ./init/scripts をマウント
  • コマンドで使用するJSONやアップロードするデータを格納する ./init/data ディレクトリを /init/data にマウント

起動時にS3バケットを作成しファイルを配置する例

./init/scripts/xxx.sh
# S3バケット作成
awslocal s3 mb s3://backat-name

# S3バケットにファイルをPUT
awslocal s3 cp /data/hoge.txt s3://backet-name/hoge.txt

LocalStackコンテナ内のシェルで実行する場合
awslocal という aws コマンドのラッパを利用することで
エンドポイント指定などを省略できます

参考資料

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9