docker-composeとlocalstackを使ってローカルでAWS SDK for JavaScript V3を動かしてみる

2021.12.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS SDK for JavaScriptのV3の存在を最近知りました。この「AWS SDK for JavaScript V3」を localstackを使いローカルで試せる環境を作ってみました(※AWS SDKから呼び出せる機能はlocalstackがカバーしているものに限られます)。

以下、docker-composelocalstackを使い、ローカルでAWS SDK for JavaScript V3を動かすサンプルプログラムとなります。AWS SDKを呼びだすプログラムはTypeScriptとし ts-node で実行してみました。

動作環境の作成

予めdocker-composeはローカルPCにインストールしておく必要があります。今回はMacにて動作を確認しました。

まず「docker-compose.yml」ファイルについてです。以下のようになり、Typescriptのプログラムを動かすためのコンテナ(コンテナ名「aws-sdk-ts-container」)と、localstackを動かすコンテナの2つを起動しています。

docker-compose.yml

version: "3.7"

services:
  aws-sdk-ts-container:
    build: .
    container_name: aws-sdk-ts-container
    privileged: true
    restart: always
    volumes:
      - type: bind
        source: ./share
        target: /share
      - type: bind
        source: ~/.aws
        target: /home/ec2-user/.aws
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
    image: localstack/localstack
    ports:
      - "4566:4566"
      - "4571:4571"
    environment:
      - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
      - "./share/localstack:/tmp/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"

先に書いたように2つのコンテナを定義しています。TypeScriptのプログラムを動かすためのコンテナについては、「Dockerfile」に定義を記述します。「Dockerfile」は以下のようになりました。

Dockerfile

FROM amazonlinux:2

# install amazon-linux-extras install
RUN amazon-linux-extras install -y

# yum update & install
RUN yum update -y \
    && yum install \
        git \
        systemd \
        tar \
        unzip \
        sudo \
        wget \
        -y

# install aws cli v2
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \
    && unzip awscliv2.zip \
    && sudo ./aws/install

# create user
RUN useradd "ec2-user" && echo "ec2-user ALL=NOPASSWD: ALL" >> /etc/sudoers

# chnage user
USER ec2-user
RUN echo -e 'export PATH="/usr/local/go/bin:$PATH"' >> ~/.bash_profile
RUN echo -e 'export CGO_ENABLED=0' >> ~/.bash_profile

# install node
RUN curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh" | bash \
    && . ~/.nvm/nvm.sh \
    && nvm install node

# init
CMD ["/sbin/init"]

ベースのイメージはAmazon Linux 2のものを使用しています。いろいろとやっていますが、今回はTypeScript、AWS SDK for JavaScriptを動かしたいため、「nodejs」をインストールするようにしました(30行目)。

これらを用意し、「$ docker-compose up -d」を実行すれば、2つのコンテナが立ち上がります。

AWS SDK for JavaScript V3を動かすプログラム

次にAWS SDKを呼び出すプログラムについてです。先に書いたようにTypeScriptで記述してみました。プログラムの処理は公式のGetting StartにあるDynamoDBを呼び出すものですが

  • localstack上のDynamoDBに接続すること
  • TypeScriptということで型の記述を確認したかった

ため、一部を改変してあります。

まずはnpmなどを使った環境の準備です。以下のコマンドを実行しました。

$ npm init -y

$ npm install --save-dev \
typescript \
ts-node

$ ./node_modules/.bin/tsc --init

クレデンシャルについては「~/.aws/config」にlocalstackに接続する定義を追加しました。プロファイル名は「localstack」、アクセスキー・シークレットキーはダミーの値で大丈夫です。

続いてTypeScriptのプログラムから呼び出すDynamoDBのテーブルを作成します。このコンテナは aws cli が使える状態であるため、以下のコマンドでDynamoDBのテーブルを作成します。

$ aws dynamodb create-table \
    --table-name Music \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput \
        ReadCapacityUnits=10,WriteCapacityUnits=5 \
    --endpoint-url=http://localstack:4566 \
    --profile=localstack

$ aws dynamodb list-tables --endpoint-url=http://localstack:4566 --profile=localstack

「Music」という名のテーブルがlocalstack上に作られるかと思います。

TypeScriptのプログラムは以下のようになります。

index.ts

import { DynamoDBClient, ListTablesCommand } from "@aws-sdk/client-dynamodb";
import { fromIni } from "@aws-sdk/credential-provider-ini";

const main = async () => {
  const client = new DynamoDBClient({
    region: "ap-northeast-1",
    credentials: fromIni({profile: 'localstack'}),
    endpoint: "http://localstack:4566",
  });
  let num : number;
  num = 100;
  console.log(`num = ${num}`)
  const command = new ListTablesCommand({});
  try {
    const results = await client.send(command);
    if (results.TableNames) {
      console.log(results.TableNames.join("\n"));
    }
  } catch (err) {
    console.error(err);
  }
};

main();

先頭(1、2行目)でimportしているAWS SDKのモジュールについては、「$ npm install」コマンドなどでインストールします。

またlocalstackに接続するため、「profile」と「endpoint」を明示的に指定しております(7、8行目)。

型の記述の確認についても、10行目で変数を型付きで定義してみました。

この「index.ts」を以下のコマンドなどで実行し、先に作成したDynamoDBのテーブル「Music」がコンソールに表示されれば完成です。

$ ./node_modules/.bin/ts-node index.ts

まとめ

このような感じで、ローカルでAWS SDK for JavaScript V3を実行出来ました。開発時の動作確認やユニットテストの実行など、ローカルでAWS SDKを実行した場合などの参考になれば幸いです。

参考サイト

  • https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/index.html
  • https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/getting-started-step-1.html