LocalStack環境の構築(と好きなラーメンの話)

# はじめに
今年はAWSの技術習得に挑戦した一年でした！
テーマが「今年がんばった技術と好きなラーメン」ということなので
自己学習のためにLocalStack環境を構築した記事を投稿します。

# LocalStackとは
ローカルマシンでAWS環境をエミュレートできる機能を持つクラウドサービスエミュレータです。
AWS Lambda、S3、DynamoDB、Kinesis、SQS、SNS などのAWSサービスをローカル環境で実行できます。
無料で使える「Community版」と有料の「Pro版」があります。
詳しくは以下の公式サイトを参照してください。

https://localstack.cloud/

# 構築した環境
WSL2を使用しました。

* Windows11
* WSL2
* Ubuntu
* docker
* docker-compose
* awscli
* awslocal
* LocalStack

# WSL2とUbuntuインストール
- コマンドプロンプトを起動して以下のコマンドを実行
```
> wsl --install
```
- インストール後にUbuntuのユーザ名とパスワードを設定

https://learn.microsoft.com/ja-jp/windows/wsl/install


# dockerインストール
- dockerの公式サイトからインストーラをダウンロードしてインストール

https://www.docker.com/

# LocalStack接続準備

- awscliインストール
```
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
```
- awscli-localインストール

:::note info
必須ではないがインストールすることでLocalStackでawscliを使うときにエンドポイントを入力しなくてもよくなる。
:::

```
$ sudo apt -y install python3-pip
$ pip3 install awscli-local
```

https://github.com/localstack/awscli-local

- コマンドのパスを通す
```
$ echo 'export PATH="$PATH:~/.local/bin"' >> ~/.bashrc
$ source ~/.bashrc
```

- LocalStack接続用ダミーファイル作成
```
$ aws configure --profile=localstack
AWS Access Key ID [None]: dummy
AWS Secret Access Key [None]: dummy
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

# LocalStack設定
- githubからLocalStackをクローン

```
$ git clone https://github.com/localstack/localstack.git
$ cd localstack
```
https://github.com/localstack/

- Pro版は使用しないのでdocker-compose.ymlを編集して、Pro用の設定を削除する
```
$ vi ./docker-compose.yml
```
:::note info
「only required for Pro」と記載されている行を削除しました。
:::

# LocalStack起動

```
$ docker-compose up -d
```
::: note info
停止するときは`docker-compose down`
:::

- 起動したら`http://localhost:4566/health`にアクセスしてサービスの起動状況を確認する。

# S3を試してみる
- バケットの作成
```
$ awslocal s3 mb s3://test-bucket --profile=localstack
```
::: note info
awscli-localをインストールしていると上記のようにエンドポイントの指定なしでコマンドが実行できる。
:::

- バケットの確認
```
$ awslocal s3 ls --profile=localstack
2022-12-12 01:22:44 test-bucket
```

- 画像ファイルをアップロード
```
$ awslocal s3 cp ./test.JPG s3://test-bucket --profile=localstack
upload: ./test.JPG to s3://test-bucket/test.JPG
```

- `http://localhost:4566/test-bucket/test.JPG`にアクセスしてアップロードされていることを確認。

![s3test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957750/493382eb-d4f1-4652-740b-048155a9e6ec.png)


アップロードできました！

# Lambdaを試してみる
- テストファイル作成
```
$ vi test.py
def handler(event, context):
    print(event)
    return 'localstackてすと'
```

- Lamda関数作成
```
$ zip test.zip test.py
  adding: test.py (deflated 8%)
$ awslocal lambda create-function --function-name test5 --runtime python3.8
--role localstack --handler test.handler --zip-file fileb://test.zip --profile=localstack
{
    "FunctionName": "test5",
    "FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:test5",
    "Runtime": "python3.8",
    "Role": "localstack",
    "Handler": "test.handler",
　　～
    "LastUpdateStatus": "Successful",
    "PackageType": "Zip",
    "Architectures": [
        "x86_64"
    ]
}
```

- 実行
```
$ awslocal lambda invoke --function-name test5 output.log --profile=localsta
ck
{
    "StatusCode": 200,
    "LogResult": "",
    "ExecutedVersion": "$LATEST"
}
```

- 実行結果確認
```
$ echo -e `cat output.log`
"localstackてすと"
```

結果が出力されました！

# DynamoDBを試してみる
- テーブル作成
```
$ awslocal dynamodb create-table \
--table-name 'test' \
--attribute-definitions '[{ "AttributeName": "id", "AttributeType": "N"}, { "AttributeName": "name", "AttributeType": "S" }]' \
--key-schema '[{ "AttributeName": "id", "KeyType": "HASH" }, { "AttributeName": "name", "KeyType": "RANGE" }]' \
--provisioned-throughput '{"ReadCapacityUnits": 10, "WriteCapacityUnits": 10}' --profile=localstack
```

- テーブル確認
```
$ awslocal dynamodb list-tables --profile=localstack
{
    "TableNames": [
        "test"
    ]
}
```

```
$ awslocal dynamodb describe-table --table-name test --profile=localstack
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "id",
                "AttributeType": "N"
            },
            {
                "AttributeName": "name",
                "AttributeType": "S"
            }
        ],
        "TableName": "test",
        "KeySchema": [
            {
                "AttributeName": "id",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "name",
                "KeyType": "RANGE"
            }
        ],
～
}
```

- テーブルにitem挿入
```
$ awslocal dynamodb put-item --table-name test --item '{ "id": { "N": "1" }, "name": { "S": "sio" } }' --profile=localstack
$ awslocal dynamodb put-item --table-name test --item '{ "id": { "N": "2" }, "name": { "S": "miso" } }' --profile=localstack
$ awslocal dynamodb put-item --table-name test --item '{ "id": { "N": "3" }, "name": { "S": "tonkotu" } }' --profile=localstack
```

- 挿入した全itemの取得
```
$ awslocal dynamodb scan --table-name test --profile=localstack
{
    "Items": [
        {
            "name": {
                "S": "miso"
            },
            "id": {
                "N": "2"
            }
        },
        {
            "name": {
                "S": "sio"
            },
            "id": {
                "N": "1"
            }
        },
        {
            "name": {
                "S": "tonkotu"
            },
            "id": {
                "N": "3"
            }
        }
    ],
    "Count": 3,
    "ScannedCount": 3,
    "ConsumedCapacity": null
}
```

DynamoDBも使えました！


# 所感
結構簡単に環境が構築できました。
今後もいろいろ試したいです！


# さいごに好きなラーメン
塩ラーメンが好きですが何でも食べます！笑
個人的に好きなラーメン店ベスト3です！

第3位
[ようすけ 鶏煮亭](https://tabelog.com/kanagawa/A1405/A140501/14049652/)
鶏白湯で味が濃厚です！

第2位
[三三七](https://tabelog.com/kanagawa/A1405/A140501/14032399/)
「つけめん煮番搾り」がおすすめです！

第1位
[函館塩ラーメン 五稜郭](https://tabelog.com/tokyo/A1319/A131906/13154596/)
スープが美味しくて毎日食べたくなる味です！

# 参考
https://zenn.dev/s_ryuuki/articles/412b5f004595b7

https://ikodatech.com/entry/2021/09/07/080000

https://techblog.styleedge.co.jp/entry/2022/08/05/164135

https://www.wakuwakubank.com/posts/675-aws-cli-dynamodb/