1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows 上で AWS をローカル開発できる環境を構築する(3)

1
Last updated at Posted at 2026-04-14

Windows 上で AWS をローカル開発できる環境を構築する(3)

今回はS3、SSM(パラメータストア)、シークレットマネージャを使ってみます。

1. docker-compose.yaml を拡張する(サービス追加)

ファイル修正
docker-compose.yaml

  • container_name: localstack を追加
  • SERVICES に s3, ssm, secretsmanager を追加
  • localstack-init を /etc/localstack/init/ready.d にマウント (LocalStack 起動後に自動実行される)
services:
  localstack:
    image: localstack/localstack:3.0.2
    container_name: localstack
    ports:
      - "4566:4566"
    environment:
      - SERVICES=lambda,s3,ssm,secretsmanager
      - DEBUG=1
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./localstack-init:/etc/localstack/init/ready.d"

2. 起動時に初期データを登録するスクリプトを作成

LocalStack では、/etc/localstack/init/ready.d/*.sh に置いたスクリプトが
起動完了後に自動実行されます。

以下の 2 つを作成します。

localstack-init/
├── 01-init-ssm.sh
└── 02-init-s3.sh

2-1. SSM と Secrets Manager の初期値登録

localstack-init/01-init-ssm.sh

#!/bin/bash
set -e

echo "[init] Register SSM parameters and Secrets Manager values"

# SSM: バケット名
awslocal ssm put-parameter \
  --name "/demo/bucket" \
  --value "demo-bucket" \
  --type "String"

# Secrets Manager: 任意のテスト用シークレット
awslocal secretsmanager create-secret \
  --name "demo-secret" \
  --secret-string '{"token":"demo-token-123"}'

2-2. S3 にテスト用バケットを作成

localstack-init/02-init-s3.sh

#!/bin/bash
set -e

echo "[init] Create S3 bucket"

awslocal s3 mb s3://demo-bucket

2-3. 実行権限を付与

$ chmod +x localstack-init/*.sh

3. LocalStack を起動して確認

$ docker compose up -d

初期化が成功しているか確認:

$ awslocal ssm describe-parameters
$ awslocal secretsmanager list-secrets
$ awslocal s3 ls

4. demo Lambda を作成する

前回の hello Lambda に加えて、今回は demo Lambda を追加します。

.
├── docker-compose.yaml
├── hello
│   ├── handler.mjs
│   └── test
│       └── handler.test.mjs
├── demo
│   ├── handler.mjs
│   └── test
│       └── handler.test.mjs
├── package-lock.json
└── package.json

4-1. AWS SDK v3 のインストール

demo Lambda では S3 / SSM / Secrets Manager を利用するため、
必要なクライアントパッケージをインストールします。

$ npm install @aws-sdk/client-s3 @aws-sdk/client-ssm @aws-sdk/client-secrets-manager

4-2. Lambda のコードを作成

処理の流れは次のとおりです。
AWS SDK の基本的な操作(GetParameter / GetSecretValue / PutObject / GetObject)を
1つの Lambda で確認します。

  • SSM パラメータストアから S3 バケット名を取得
  • Secrets Manager からテスト用シークレットを取得
  • 取得した情報を文字列として組み立てる
  • S3 に demo.txt としてアップロード
  • アップロードしたファイルを S3 からダウンロード
  • ダウンロードした内容をレスポンスとして返す

補足

  • LambdaからLocalStack には localhost ではなく、
    docker-compose の container_name(localstack)を使って http://localstack:4566 で接続します。環境変数 LOCALSTACK_ENDPOINT はLambdaデプロイ時に設定します。
  • LocalStack の S3 はバーチャルホスト形式を完全にサポートしていないため、
    forcePathStyle: true を付ける必要があります。

demo/handler.mjs

// demo/handler.mjs
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";
import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";

export const handler = async () => {
  
  // LocalStack 用の共通設定(credentials を明示)
  const endpoint 
    = process.env.LOCALSTACK_ENDPOINT || "http://localhost:4566";
  const common = {
    region: "us-east-1",
    endpoint: endpoint,
    credentials: {
      accessKeyId: "test",
      secretAccessKey: "test",
    },
  };

  const ssm = new SSMClient(common);
  const secrets = new SecretsManagerClient(common);
  const s3 = new S3Client({
    ...common,
    forcePathStyle: true, // LocalStack では必須
  });

  // SSM からバケット名取得
  const param = await ssm.send(
    new GetParameterCommand({ Name: "/demo/bucket", WithDecryption: false })
  );
  const bucket = param.Parameter.Value;

  // Secrets Manager から値取得
  const secret = await secrets.send(
    new GetSecretValueCommand({ SecretId: "demo-secret" })
  );

  const content = `bucket=${bucket}\nsecret=${secret.SecretString}`;

  // S3 にアップロード
  await s3.send(
    new PutObjectCommand({
      Bucket: bucket,
      Key: "demo.txt",
      Body: content,
    })
  );

  // S3 からダウンロード
  const result = await s3.send(
    new GetObjectCommand({
      Bucket: bucket,
      Key: "demo.txt",
    })
  );

  const body = await result.Body.transformToString();

  return {
    statusCode: 200,
    body: JSON.stringify({
      message: "demo lambda executed",
      content: body
    })
  };
};

4-3. テストコード作成

このテストでは、demo Lambda が SSM・Secrets Manager・S3 の値を正しく取得し、処理結果を返せていることをまとめて確認しています。

demo/test/handler.test.mjs

import { describe, it, expect } from "vitest";
import { handler } from "../handler.mjs";

describe("demo lambda", () => {
  it("runs demo lambda", async () => {
    const result = await handler();
    expect(result.statusCode).toBe(200);
    const body = JSON.parse(result.body);
    expect(body.message).toBe("demo lambda executed");
    expect(body.content).toContain("bucket=");
  });
});

5. Vitest で実行

$ npx vitest

今回追加した demo のみテストする場合

$ npx vitest demo/test/handler.test.mjs

6. LocalStack にデプロイして実行

6-1. Lambda 用コードを ZIP 化する

ファイルを ZIP の直下に置きます。

$ zip -j demo.zip demo/handler.mjs

6-2. Lambda 関数を LocalStack にデプロイする

作成した ZIP を LocalStack に登録します。
環境変数 LOCALSTACK_ENDPOINT を設定します。

$ awslocal lambda create-function \
  --function-name demo \
  --runtime nodejs20.x \
  --handler handler.handler \
  --zip-file fileb://demo.zip \
  --role arn:aws:iam::000000000000:role/lambda-role \
  --environment "Variables={LOCALSTACK_ENDPOINT=http://localstack:4566}"

6-3. 状態の確認

$ awslocal lambda get-function --function-name demo

出力内容に

"State": "Active"

が含まれていれば正常です。

6-4. 実行

$ awslocal lambda invoke --function-name demo out.json
$ cat out.json

出力例

{"statusCode":200,"body":"{\"message\":\"demo lambda executed\",\"content\":\"bucket=demo-bucket\\nsecret={\\\"token\\\":\\\"demo-token-123\\\"}\"}"}

以上です。

1
0
0

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?