【AWSアカウント不要】ローカル環境でAWS CDKのデプロイ&動作確認をするチュートリアル

# 1. はじめに

## 1-1. この記事で行うこと

- [LocalStack](https://github.com/localstack/localstack)コンテナをセットアップし、動作確認
- Node.js環境コンテナ内に[AWS CDK](https://aws.amazon.com/jp/cdk/)プロジェクトを作成
- AWS CDKプロジェクトをLocalStackへデプロイし、動作確認

## 1-2. この記事の対象者

- AWS CDKを本物のAWSを使わずに動かしたい方
- AWS CDKをすぐに捨てられる環境で色々と試してみたい方

## 1-3. 動作環境

このチュートリアルは、Bashなどのコマンドが利用でき、DockerとDocker Composeがインストール済みの環境で実行できます。

## 1-4. 各種のバージョン

2022年2月19日時点で動作確認済のバージョンは以下の通りです。

- docker
    - Docker version 20.10.0, build 7287ab3
- docker-compose
    - docker-compose version 1.26.0, build unknown
- localstack
    - 0.14.0
- aws-cli
    - aws-cli/1.22.58 Python/3.8.5 Linux/4.4.0-210-generic botocore/1.24.3
- aws-cdk
    - 1.145.0
- aws-cdk-local
    - 1.65.8

# 2. チュートリアル


このチュートリアルではLocalStackというローカルでAWSを擬似的に使用できるツールを用います。詳しい説明は以下の記事をご参考ください。
[LocalStack を使って無料で AWS を学ぶ](https://qiita.com/amenoyoya/items/9ac32acd0c20e1811725)

このLocalStackのDockerコンテナ内に擬似的なAWS環境を立て、そこへAWS CDKをデプロイし、動作確認を行っていきます。

## 2-1. 最終的なファイル構成

いきなりですが、このチュートリアルが完了した状態のファイル構成です。
以下の「▶︎ 詳細」をクリックしてご確認ください。

<DETAILS>
<pre>
$ tree -L 5 -I node_modules
.
├── localstack
│   ├── CHANGELOG.md
│   ├── Dockerfile
│   ├── LICENSE.txt
│   ├── MANIFEST.in
│   ├── Makefile
│   ├── README.md
│   ├── bin
│   │   └── 略
│   ├── doc
│   │   └── 略
│   ├── docker-compose.yml
│   ├── localstack
│   │   └── 略
│   ├── requirements.txt
│   ├── setup.py
│   └── tests
│       └── 略
├── node_workdir
│   ├── Dockerfile
│   ├── app
│   │   └── sample
│   │       ├── README.md
│   │       ├── bin
│   │       │   ├── sample.d.ts
│   │       │   ├── sample.js
│   │       │   └── sample.ts
│   │       ├── cdk.json
│   │       ├── cdk.out
│   │       │   ├── SampleStack.template.json
│   │       │   ├── cdk.out
│   │       │   ├── manifest.json
│   │       │   └── tree.json
│   │       ├── jest.config.js
│   │       ├── lib
│   │       │   ├── sample-stack.d.ts
│   │       │   ├── sample-stack.js
│   │       │   └── sample-stack.ts
│   │       ├── package-lock.json
│   │       ├── package.json
│   │       ├── test
│   │       │   ├── sample.test.d.ts
│   │       │   ├── sample.test.js
│   │       │   └── sample.test.ts
│   │       └── tsconfig.json
│   └── docker-compose.yml
└── s3.txt
</pre>
</DETAILS>

## 2-2. LocalStackのセットアップ

### 2-2-1. LocalStackをダウンロードする

```bash
$ git clone https://github.com/localstack/localstack
Cloning into 'localstack'...
remote: Enumerating objects: 27765, done.
remote: Counting objects: 100% (2217/2217), done.
remote: Compressing objects: 100% (1063/1063), done.
remote: Total 27765 (delta 1355), reused 1793 (delta 1044), pack-reused 25548
Receiving objects: 100% (27765/27765), 12.74 MiB | 21.92 MiB/s, done.
Resolving deltas: 100% (20109/20109), done.
```

### 2-2-2. LocalStackコンテナを起動する

``` bash
$ cd localstack

# デフォルトで存在するDockerネットワーク「bridge」では、他のコンテナからコンテナ名で名前解決できないため、
# 「network_mode: bridge」をコメントアウトし、Dockerネットワーク「localstack_default」が自動生成されるようにする
$ sed -i 's/network_mode: bridge/# network_mode: bridge/' docker-compose.yml

$ docker-compose up -d
Creating network "localstack_default" with the default driver
Pulling localstack (localstack/localstack:)...
latest: Pulling from localstack/localstack
# ・・・(中略)
Digest: sha256:0ab755bf60c1c1ce03aa5adb51e947b04bdac75607cbaea64460802ca3f5de75
Status: Downloaded newer image for localstack/localstack:latest
Creating localstack_main ... done

$ cd ..
```

### 2-2-3. LocalStackのステータスを確認する

```bash
$ curl http://localhost:4566
{"status": "running"}
```

>https://github.com/localstack/localstack
2020-09-15: A major (breaking) change has been merged in PR #2905 - starting with releases after v0.11.5, all services are now exposed via the edge service (port 4566) only! Please update your client configurations to use this new endpoint.
(DeepLによる翻訳)
PR #2905 に主要な (壊すような) 変更がマージされました - v0.11.5 以降のリリースから、すべてのサービスがエッジサービス (ポート 4566) のみを介して公開されるようになりました! この新しいエンドポイントを使用するために、クライアントの設定を更新してください。

公式githubにport 4566のみで動いてると書いてあるので、curlのポートに`:4566`を指定しています。
上手く動いていると`{"status": "running"}`が返ってきます。

### 2-2-4. aws-cliをインストールする

```bash
$ pip install awscli
Collecting awscli
  Downloading awscli-1.22.58-py3-none-any.whl (3.8 MB)
     |████████████████████████████████| 3.8 MB 8.3 MB/s 
# ・・・(中略)
Installing collected packages: pyasn1, rsa, jmespath, python-dateutil, botocore, s3transfer, docutils, awscli
Successfully installed awscli-1.22.58 botocore-1.24.3 docutils-0.15.2 jmespath-0.10.0 pyasn1-0.4.8 python-dateutil-2.8.2 rsa-4.7.2 s3transfer-0.5.1
```

LocalStackは基本的にはGUIで操作できないのでaws-cliを使用する必要があります。

### 2-2-5. LocalStack用のaws-cliのconfigureを設定する

```bash
$ aws configure set aws_access_key_id dummy --profile local

$ aws configure set aws_secret_access_key dummy --profile local

$ aws configure set region ap-northeast-1 --profile local
```

LocalStack用なので`aws_access_key_id`と`aws_secret_access_key`は適当な値 (`dummy`等) で大丈夫です。

## 2-3. LocalStackの動作確認

[Amazon Simple Storage Service](https://aws.amazon.com/jp/s3/) (以降、S3) へバケットを登録し、テキストファイルをアップロードできるかを確認します。

### 2-3-1. S3にバケットを登録する

```bash
$ aws s3 mb s3://test-s3 \
  --endpoint-url http://localhost:4566 \
  --profile local
make_bucket: test-s3
```

### 2-3-2. S3のバケット一覧を取得する

```bash
$ aws s3 ls \
  --endpoint-url http://localhost:4566 \
  --profile local
2022-02-19 06:50:52 test-s3
```

### 2-3-3. S3へファイルをコピーする

```bash
$ echo "test text" > s3.txt

$ aws s3 cp ./s3.txt s3://test-s3 \
  --endpoint-url http://localhost:4566 \
  --profile local
upload: ./s3.txt to s3://test-s3/s3.txt 
```

### 2-3-4. 指定したS3のバケットのファイル一覧を取得する

```bash
$ aws s3 ls test-s3 \
  --endpoint-url http://localhost:4566 \
  --profile local
2022-02-19 06:53:10         10 s3.txt
```

## 2-4. Node.js環境のセットアップ

今回はAWS CDKをTypeScriptを使用して作成するので、Node.js環境が必要となります。
特別な理由はないですが、Node.js環境もDockerで準備していきます。

### 2-4-1. Node.js環境作業ディレクトリを作成する

```bash
$ mkdir node_workdir && cd node_workdir

$ mkdir app
```

### 2-4-2. Dockerfileを作成する

```bash
$ vi Dockerfile
```

以下のファイルの中身をコピペしてください。

```dockerfile:Dockerfile
FROM node:14-alpine
WORKDIR /app
CMD ["sh"]
```

### 2-4-3. docker-compose.ymlを作成する

```bash
$ vi docker-compose.yml
```

以下のファイルの中身をコピペしてください。

```yaml:docker-compose.yml
version: '3'

services:
  app:
    build: .
    image: my-node-image
    networks:
      - localstack_default
    volumes:
      - ./app:/app
    environment:
      - LOCALSTACK_HOSTNAME=localstack_main
    tty: true

networks:
  localstack_default:
    external: true
```

`networks`に「2-2-2. LocalStackコンテナを起動する」で生成されたDockerネットワークを`localstack_default`指定しています。
また、`environment`の`LOCALSTACK_HOSTNAME`に「2-2-2. LocalStackコンテナを起動する」で生成されたコンテナ名の`localstack_main`を指定することで、後ほど出てくる`cdklocal`コマンド実行時にLocalStackコンテナへ接続可能となります。

### 2-4-4. Node.js環境コンテナを起動する

```bash
$ docker-compose up -d
Building app
Step 1/3 : FROM node:14-alpine
14-alpine: Pulling from library/node
59bf1c3509f3: Pull complete
39aa0d19fbe1: Pull complete
f0b94cdce0f3: Pull complete
664688b94c15: Pull complete
Digest: sha256:9a2aa545388a135b496bd55cef2be920b96c4526c99c140170e05a8de3fce653
Status: Downloaded newer image for node:14-alpine
 ---> 755b96824e40
Step 2/3 : WORKDIR /app
 ---> Running in 4cbba13c1a78
Removing intermediate container 4cbba13c1a78
 ---> 852f95361e20
Step 3/3 : CMD ["sh"]
 ---> Running in ce69f75cc813
Removing intermediate container ce69f75cc813
 ---> 6776a5c22ebe
Successfully built 6776a5c22ebe
Successfully tagged my-node-image:latest
WARNING: Image for service app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating node_workdir_app_1 ... done
```

コンテナの起動に成功すると`Creating node_workdir_app_1 ... done`のように生成されたコンテナの名前が出力されます。

### 2-4-5. Node.js環境コンテナの中に入る

```bash
$ docker exec -it node_workdir_app_1 sh
/app # 
```

先ほど生成されたコンテナの名前を指定して`docker exec`コマンドを実行します。
オプションに`-it`を、コマンドに`sh`を指定しているので、コンテナの中に入ることができます。
Dockerコンテナに入る方法については以下の記事をご参考ください。
[docker exec -itって実際は何をしてるの？【90日目】](https://www.nyamucoro.com/entry/2018/01/11/224932)

なお、「2-5. AWS CDKプロジェクトの作成〜デプロイ」は、このコンテナの中に入っている状態で進めていきます。

## 2-5. AWS CDKプロジェクトの作成〜デプロイ

[aws-cdk](https://github.com/aws/aws-cdk)でプロジェクトを作成し、[aws-cdk-local](https://github.com/localstack/aws-cdk-local)でLocalStackへデプロイしていきます。

### 2-5-1. aws-cdkとaws-cdk-localをグローバルインストールする

```shell-session
/app # npm install -g aws-cdk@1
/usr/local/bin/cdk -> /usr/local/lib/node_modules/aws-cdk/bin/cdk
+ aws-cdk@1.145.0
added 217 packages from 231 contributors in 11.003s

/app # npm install -g aws-cdk-local
/usr/local/bin/cdklocal -> /usr/local/lib/node_modules/aws-cdk-local/bin/cdklocal
+ aws-cdk-local@1.65.8
added 2 packages from 1 contributor in 0.874s
```

補足ですが、下記のIssueを参考にし、`npm install -g aws-cdk@1`とすることで、`aws-cdk`のv2がインストールされないようにしています。

「[Error: The stack named CDKToolkit failed to deploy: CREATE_FAILED (Deployment failed) #57] (https://github.com/localstack/aws-cdk-local/issues/57)」
> Localstack Free version doesn't support ECR so you must upgrade to Pro-version if you want to use aws-cdk@2

### 2-5-2. サンプルcdkプロジェクト用ディレクトリを作成し、移動する

```shell-session
/app # mkdir sample && cd sample
```

### 2-5-3. サンプルcdkプロジェクトを作成する

```shell-session
/app/sample # cdk init sample-app --language=typescript
Applying project template sample-app for typescript
# Welcome to your CDK TypeScript project

You should explore the contents of this project. It demonstrates a CDK app with an instance of a stack (`SampleStack`)
which contains an Amazon SQS queue that is subscribed to an Amazon SNS topic.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

## Tutorial

See [this useful workshop](https://cdkworkshop.com/20-typescript.html) on working with the AWS CDK for Typescript projects.

## Useful commands

* `npm run build`   compile typescript to js
* `npm run watch`   watch for changes and compile
* `npm run test`    perform the jest unit tests
* `cdk deploy`      deploy this stack to your default AWS account/region
* `cdk diff`        compare deployed stack with current state
* `cdk synth`       emits the synthesized CloudFormation template

Initializing a new git repository...
/bin/sh: git: not found
Unable to initialize git repository for your project.
Executing npm install...
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated uuid@3.3.2: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated sane@4.1.0: some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added
npm WARN deprecated source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^2.1.2 (node_modules/jest-haste-map/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN sample@0.1.0 No repository field.
npm WARN sample@0.1.0 No license field.

✅ All done!
*************************************************************************************************************************************************
*** Newer version of CDK is available [2.13.0]                                                                                                ***
*** Information about upgrading from version 1.x to version 2.x is available here: https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html ***
*** Upgrade recommended (npm install -g aws-cdk)                                                                                              ***
*************************************************************************************************************************************************
```

`cdk init`コマンドで`--language=typescript`を指定してTypeScriptでファイルが生成されるようにしています。
また、`sample-app`と指定すると、簡単なサンプルを含んだプロジェクトが生成されます。出力の中に簡単なサンプルについての説明があります。

```
You should explore the contents of this project. It demonstrates a CDK app with an instance of a stack (`SampleStack`)
which contains an Amazon SQS queue that is subscribed to an Amazon SNS topic.
```

>(DeepLによる翻訳)
このプロジェクトの内容を探ってみてください。スタック (`SampleStack`) のインスタンスを持つ CDK アプリのデモを行います。
これは、Amazon SNSのトピックにサブスクライブされているAmazon SQSキューを含んでいます。

生成された簡単なサンプルのソースコードを、ちょっとだけ見てみましょう。

```shell-session
/app/sample # vi ./lib/sample-stack.ts
```

```typescript:./lib/sample-stack.ts
import * as sns from '@aws-cdk/aws-sns';
import * as subs from '@aws-cdk/aws-sns-subscriptions';
import * as sqs from '@aws-cdk/aws-sqs';
import * as cdk from '@aws-cdk/core';

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

    const queue = new sqs.Queue(this, 'SampleQueue', {
      visibilityTimeout: cdk.Duration.seconds(300)
    });

    const topic = new sns.Topic(this, 'SampleTopic');

    topic.addSubscription(new subs.SqsSubscription(queue));
  }
}
```

[Amazon Simple Queue Service](https://aws.amazon.com/jp/sqs/) (以降、SQS) のキューと[Amazon Simple Notification Service](https://aws.amazon.com/jp/sns/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc) (以降、SNS)のトピックとサブスクリプションが定義されています。SNSトピックからメッセージを発行すると、サブスクリプションとして登録されているキューに登録されるようになっています。

### 2-5-4. TypeScriptファイルをJavaScriptファイルにトランスパイルする

```shell-session
/app/sample # npm run build

> sample@0.1.0 build /app/sample
> tsc
```

ブラウザやNode.js環境はJavaScriptしか実行できないため、TypeScriptファイルをJavaScriptファイルへ必ず変換しましょう。

### 2-5-5. デプロイ先のリージョンを環境変数として設定する

```shell-session
/app/sample # export AWS_DEFAULT_REGION=ap-northeast-1
```

### 2-5-6. 初めてデプロイする場合、デプロイ用のS3バケットなどを作成する

```shell-session
/app/sample # cdklocal bootstrap
 ⏳  Bootstrapping environment aws://000000000000/ap-northeast-1...
CDKToolkit: creating CloudFormation changeset...



 ✅  Environment aws://000000000000/ap-northeast-1 bootstrapped.
```

### 2-5-7. LocalStackへデプロイする

```shell-session
/app/sample # cdklocal deploy

✨  Synthesis time: 4.55s

This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

IAM Statement Changes
┌───┬─────────────────────────┬────────┬─────────────────┬─────────────────────────┬───────────────────────────┐
│   │ Resource                │ Effect │ Action          │ Principal               │ Condition                 │
├───┼─────────────────────────┼────────┼─────────────────┼─────────────────────────┼───────────────────────────┤
│ + │ ${SampleQueue.Arn}      │ Allow  │ sqs:SendMessage │ Service:sns.amazonaws.c │ "ArnEquals": {            │
│   │                         │        │                 │ om                      │   "aws:SourceArn": "${Sam │
│   │                         │        │                 │                         │ pleTopic}"                │
│   │                         │        │                 │                         │ }                         │
└───┴─────────────────────────┴────────┴─────────────────┴─────────────────────────┴───────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Do you wish to deploy these changes (y/n)? y
SampleStack: deploying...
SampleStack: creating CloudFormation changeset...




 ✅  SampleStack

✨  Deployment time: 5.26s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:000000000000:stack/SampleStack/8775e216

✨  Total time: 9.81s
```

途中で`Do you wish to deploy these changes (y/n)?`と入力を求められるので、問題がなければ`y`を入力しましょう。

### 2-5-8. Node.js環境コンテナから抜け出す

```shell-session
/app/sample # exit
$ 
```

## 2-6. AWS CDKからLocalStackへデプロイされたリソースの動作確認

「リソースが生成されているか」と「SNSトピックからメッセージを発行し、サブスクリプションとして登録されているキューに登録されるか」を確認していきます。

### 2-6-1. SQSキューの一覧を取得する

```bash
$ aws sqs list-queues \
  --endpoint-url http://localhost:4566 \
  --profile local
{
    "QueueUrls": [
        "http://localhost:4566/000000000000/SampleStack-SampleQueue49AAAEFF-c0802178"
    ]
}
```

SQSキューがちゃんと生成されていますね。
ちなみに、`QueueUrls`に表示されている値は各自の環境で異ります。

### 2-6-2. 指定したSQSキューの詳細を取得する

```bash
$ aws sqs get-queue-attributes \
  --queue-url http://localhost:4566/000000000000/SampleStack-SampleQueue49AAAEFF-c0802178 \
  --attribute-names All \
  --endpoint-url http://localhost:4566 \
  --profile local
{
    "Attributes": {
        "ApproximateNumberOfMessages": "0",
        "ApproximateNumberOfMessagesDelayed": "0",
        "ApproximateNumberOfMessagesNotVisible": "0",
        "CreatedTimestamp": "1645254466.340205",
        "DelaySeconds": "0",
        "LastModifiedTimestamp": "1645254467.617937",
        "MaximumMessageSize": "262144",
        "MessageRetentionPeriod": "345600",
        "QueueArn": "arn:aws:sqs:ap-northeast-1:000000000000:SampleStack-SampleQueue49AAAEFF-c0802178",
        "Policy": "{\"Statement\": [{\"Action\": \"sqs:SendMessage\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"arn:aws:sns:ap-northeast-1:000000000000:SampleStack-SampleTopic5FE9B5DC-c2e948f9\"}}, \"Effect\": \"Allow\", \"Principal\": {\"Service\": \"sns.amazonaws.com\"}, \"Resource\": \"arn:aws:sqs:ap-northeast-1:000000000000:SampleStack-SampleQueue49AAAEFF-c0802178\"}], \"Version\": \"2012-10-17\"}",
        "ReceiveMessageWaitTimeSeconds": "0",
        "VisibilityTimeout": "300"
    }
}
```

`--queue-url`に指定する値は「2-6-1. SQSキューの一覧を取得する」で取得した**各自の値**を指定してください。
今回はとりあえず出力結果のうち、次の一項目だけ確認します。`ApproximateNumberOfMessages` (キューから取得可能なメッセージのおおよその数) が`"0"`になっていることが確認できましたでしょうか。

### 2-6-3. SNSトピックの一覧を取得する

```bash
$ aws sns list-topics \
  --endpoint-url http://localhost:4566 \
  --profile local
{
    "Topics": [
        {
            "TopicArn": "arn:aws:sns:ap-northeast-1:000000000000:SampleStack-SampleTopic5FE9B5DC-c2e948f9"
        }
    ]
}
```

SNSトピックもちゃんと生成されていますね。
`TopicArn`も同様に表示されている値は各自の環境で異ります。

### 2-6-4. 指定したSNSトピックへメッセージを発行する

```bash
$ aws sns publish \
  --message test_message \
  --topic-arn arn:aws:sns:ap-northeast-1:000000000000:SampleStack-SampleTopic5FE9B5DC-c2e948f9 \
  --endpoint-url http://localhost:4566 \
  --profile local
{
    "MessageId": "47899304-fe28-4c3a-b7d0-d35a41c44202"
}
```

`--topic-arn`に指定する値は「2-6-3. SNSトピックの一覧を取得する」で取得した**各自の値**を指定してください。
発行に成功すると`MessageId`が入ったJSONが返ってきます。


### 2-6-5. 指定したSQSキューの詳細を取得し、ApproximateNumberOfMessagesを確認する

```bash
$ aws sqs get-queue-attributes \
  --queue-url http://localhost:4566/000000000000/SampleStack-SampleQueue49AAAEFF-c0802178 \
  --attribute-names All \
  --endpoint-url http://localhost:4566 \
  --profile local
{
    "Attributes": {
        "ApproximateNumberOfMessages": "1",
        "ApproximateNumberOfMessagesDelayed": "0",
        "ApproximateNumberOfMessagesNotVisible": "0",
        "CreatedTimestamp": "1645254466.340205",
        "DelaySeconds": "0",
        "LastModifiedTimestamp": "1645254467.617937",
        "MaximumMessageSize": "262144",
        "MessageRetentionPeriod": "345600",
        "QueueArn": "arn:aws:sqs:ap-northeast-1:000000000000:SampleStack-SampleQueue49AAAEFF-c0802178",
        "Policy": "{\"Statement\": [{\"Action\": \"sqs:SendMessage\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"arn:aws:sns:ap-northeast-1:000000000000:SampleStack-SampleTopic5FE9B5DC-c2e948f9\"}}, \"Effect\": \"Allow\", \"Principal\": {\"Service\": \"sns.amazonaws.com\"}, \"Resource\": \"arn:aws:sqs:ap-northeast-1:000000000000:SampleStack-SampleQueue49AAAEFF-c0802178\"}], \"Version\": \"2012-10-17\"}",
        "ReceiveMessageWaitTimeSeconds": "0",
        "VisibilityTimeout": "300"
    }
}
```

「2-6-2. 指定したSQSキューの詳細を取得する」と同じコマンドを実行しましょう。
`ApproximateNumberOfMessages` (キューから取得可能なメッセージのおおよその数) が`"1"`になっていたら、SNSトピックから発行されたメッセージがSQSキューに登録される処理がうまくいった証拠です！