aws-cdk(typescript)のテストで RangeError: Maximum call stack size exceededが出た

現象

cdkコマンドでコードを自動生成した後に以下のようなサンプルのテストコードがついてきます

import {
  expect as expectCDK,
  matchTemplate,
  MatchStyle,
} from "@aws-cdk/assert";
import * as cdk from "@aws-cdk/core";
import * as multiAz from "../lib/multiAz-stack";

test("Empty Stack", () => {
  const app = new cdk.App();
  // WHEN
  const stack = new multiAz.MultiAZStack(app, "MyTestStack");
  // THEN
  expectCDK(stack).to(
    matchTemplate(
      {
        Resources: {},
      },
      MatchStyle.EXACT
    )
  );
});

npm testを入力すると RangeError: Maximum call stack size exceededでテストができませんでした

      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:170:14)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:176:18)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:176:18)
          at Array.map (<anonymous>)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:170:14)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:176:18)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:176:18)
          at Array.map (<anonymous>)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:170:14)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:176:18)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:176:18)
          at Array.map (<anonymous>)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:170:14)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:176:18)
      at deepCopy (node_modules/@aws-cdk/cloudformation-diff/lib/diff-template.ts:176:18)

解決 ?

以下のリンクに書いてあるように

1: package-lock.jsonを削除
2: node_modulesを削除

をしました。その後

3: package.jsonにあるaws-cdk関連のmoduleバージョンを最新に揃える
4: npm install

で解決しました stackoverflow.com

まとめ

残念ながら私はjavascriptに詳しいわけではないので原因が全く分かりませんが、すぐに解決したい人の役に立てればと思います。

aws-cdk(typescript)でVPCを作成してみよう

はじめに

今回は aws-cdkを使用してVPCを作成していきたいと思います

nodejsが入っていることが前提の記事となります

環境

バージョン
Node.js v12.18.3
Typescript 3.9.7
aws-cdk 1.72.0

環境構築

まずはじめにグローバルにaws-cdkをインストールします

npm install -g aws-cdk

ローカルにインストールでは動かない??

普段はyarnを使ってコーディングしているので、yarn add aws-cdkを入力してcdkコマンドを実行しようとすると

`cdk init` cannot be run in a non-empty directory!
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

といったように怒られました。

もちろんそのコマンドを入力する前に mkdir src && cd srcをしています

なので大人しく -gオプションでグローバルに入れた方が良さそうです

credentialを設定しよう

もし ~/.aws/credentialsに accesskeyを設定していないのであれば設定しましょう

[default]
aws_access_key_id=xxxxxxxx
aws_secret_access_key=xxxxxxxx

設定していない場合 deployする時にエラーが出ます

$ cdk deploy
Unable to resolve AWS account to use. It must be either configured when you define your CDK or through the environment

appを作成しよう

メモ: gitを使用してコードを管理したい場合は README.mdを含めない空のリポジトリを作成しておくと良い

appを指定すると空のディレクトリ以下にnode_modulesを含めたファイルが作成されます

$ cdk init app --language=typescript 
$ tree -L 1 -l src/
src/
├── README.md
├── bin
├── cdk.json
├── jest.config.js
├── lib
├── node_modules
├── package-lock.json
├── package.json
├── test
└── tsconfig.json

VPCを作成しよう

npm i -D @aws-cdk/aws-ec2

libディレクトリ配下にあるtsファイルが一つあると思います
以下のようにVPCを付け足します

import * as cdk from '@aws-cdk/core';
import { Vpc } from "@aws-cdk/aws-ec2";   // 追加

export class HogeStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // ↓を追加
    const vpc = new Vpc(this, 'TheVPC', {
      cidr: "10.0.0.0/16"
    })

  }
}

ターミナルで code deployを入力すると以下の図のような構成が作成されます

f:id:kntks:20201101165725p:plain

NATゲートウェイのデフォルト値

default: One NAT gateway/instance per Availability Zone)

サブネットのデフォルト値

default: The VPC CIDR will be evenly divided between 1 public and 1 private subnet per AZ.

class VPC - AWS-CDK document

デフォルトで

を作成するようです

今回東京リージョンを使用しているのですが、その場合AZはap-northeast-1aap-northeast-1cが選択されていました

f:id:kntks:20201114113638p:plain

VPCのみ作成したい

下を追加しましょう

const vpc = new Vpc(this, 'TheVPC', {
      cidr: "10.2.0.0/16",
      natGateways: 0,  # 追加
      subnetConfiguration: [], # 追加
    })

subnetを追加しよう

以下のようにコードを追加してみましょう

const vpc = new Vpc(this, 'TheVPC', {
      cidr: "10.2.0.0/16",
      natGateways: 0, 
      subnetConfiguration: [
       {
          cidrMask: 24,
          subnetType: ec2.SubnetType.PUBLIC,
          name: "Public"
        },
      ], # 追加
    })

そうすると以下のようにパブリックサブネットが2つ作成されます f:id:kntks:20201114132921p:plain

もしAZを一つにしたいのであれば、maxAzsを追加します

const vpc = new Vpc(this, 'TheVPC', {
      cidr: "10.2.0.0/16",
      natGateways: 0, 
      maxAzs: 1,    # 追加
      subnetConfiguration: [
       {
          cidrMask: 24,
          subnetType: ec2.SubnetType.PUBLIC,
          name: "Public"
        },
      ],
    })

GitHub - aws/aws-cdk: The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code

https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html

まとめ

この記事ではaws-cdk(typescript)の導入としてVPC,サブネットのみに注目して書きました

コードで管理することによってインフラの属人化を軽減できればと思います

NoSQL Workbenchとdynamodb-localでローカル開発環境を構築する

はじめに

環境構築で躓くのは時間がもったいないなと思ったので簡単に構築できるように備忘録を残します!

本記事について

amazon/dynamo-localNoSQL Workbench for DynamoDB GUI Clientを利用したローカル環境構築の手順を示した記事です

dockerコンテナを使用するので、dockerの使用経験があることを前提に話を進めていきます

最終的にローカル環境だけれどもデータの操作はGUIでできるようになるところまでを目指します

環境

ツール version
docker engine 19.03.12
docke compose 1.27.2
mac Catalina 10.15.6
NoSQL Workbench for Amazon DynamoDB 1.1.0

対象

  • awsのdynamodbを使用して開発することになったエンジニア
  • お金、awsアカウントはないが、好奇心はあるエンジニア

環境構築

aws cliのインストール

まず最初にaws-cliをインストールします

brew install awscli

homebrew以外のインストール方法はこちら

インストール終了後、cliのバージョンを確認してみましょう

~ $ aws --version
aws-cli/2.0.50 Python/3.8.5 Darwin/19.6.0 source/x86_64

dynamodbコンテナを立ち上げる

公式で掲載されているymlを拝借して、commandを追加します

NoSQL Workbenchが正しくテーブルを認識してくれるように-sharedDbを入れておきます

DynamoDB をコンピュータにローカルでデプロイする - Amazon DynamoDB

version: '3.7'
services:
 dynamodb-local:
   image: amazon/dynamodb-local:latest
   container_name: dynamodb-local
   command:  ["-jar", "DynamoDBLocal.jar", "-sharedDb", "-inMemory"]
   ports:
    - "8000:8000"

ターミナルでdocker-compose upを入力してdynamodb localを立ち上げます
SharedDb: trueになっていることを確認してください

筆者は別serviceをdocker-compose.ymlに書いているので、docker-compose up dynamodb-localと入力しています

dynamodb-local    | Initializing DynamoDB Local with the following configuration:
dynamodb-local    | Port:   8000
dynamodb-local    | InMemory:   true
dynamodb-local    | DbPath: null
dynamodb-local    | SharedDb:   true
dynamodb-local    | shouldDelayTransientStatuses:   false
dynamodb-local    | CorsParams: *
dynamodb-local    |

NoSQL Workbench のダウンロード - Amazon DynamoDB

aws cliからdynamoテーブルを作成する

ドキュメントのコマンドを拝借しましょう

しかし、このまま入力すると失敗すると思います
なぜならクラウド側のawsに繋ぎにいくからです

なので、コマンドラインオプション--endpoint-urlを使用します

aws dynamodb create-table \
    --table-name MusicCollection \
    --attribute-definitions AttributeName=Artist,AttributeType=S AttributeName=SongTitle,AttributeType=S \
    --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \
    --endpoint-url http://localhost:8000

AWS CLI で Amazon DynamoDB の使用 - AWS コマンドラインインターフェイス

DynamoDB Local の使用に関する注意事項 - Amazon DynamoDB

NoSQL Workbenchをダウンロード

f:id:kntks:20200923225427p:plain

NoSQL Workbench のダウンロード - Amazon DynamoDB

NoSQL Workbenchを起動する

インストールが完了しているなら最初に開いた画面からOperation builder > + Add connectionを選択してください f:id:kntks:20200924004526p:plain

次にDynamoDB local > Connectをクリックしてください f:id:kntks:20200924004738p:plain

いかがでしょうか?
先ほどaws-cliで入力したaws dynamodb create-table --table-name MusicCollection xxxxMusicCollectionが見れたと思います f:id:kntks:20200924004917p:plain

テーブルを削除する

aws dynamodb delete-table  --table-name MusicCollection \
--endpoint-url http://localhost:8000

amazon/aws-cliamazon/dynamo-localのdockerコンテナを使用して構築できないのか?

一応可能ですが、お勧めはしません

こちらの記事でも紹介されていて、自分でも実際に手を動かした結果、結構大変でした

他にもaws-cliのコマンドを叩きたいだけなのに、コンテナをずっと立ち上げておかないといけないのが結構気になりました

最後に

ここまで読んでいただきありがとうございます!!

この記事はいかがだったでしょうか? 再現性のある記事を書こうと事細かく記述したつもりです

一人でも多くの人が開発に集中できるようになればいいなと思っています

参考

公式の AWS CLI バージョン 2 Docker イメージを使用する - AWS コマンドラインインターフェイス

dynamodb — AWS CLI 2.2.9 Command Reference