LocalStack導入から実行まで

# はじめに

最近、AWS API GateWay + Lambdaを使用して、サーバレスでWeb APIを作成する機会がありました。
AWS コンソールから関数の作成、コードの編集を行う、といった体制で進めていましたが、一つの問題が出ました。

それが「コード書き換えてしまう問題」です

具体的に説明しますと、作業者AがとあるLambda関数を編集中に、作業者Bが同じLambda関数を更新しました。
その後、作業者Aが編集内容を更新すると、作業者Bの編集した内容が消えてしまうという問題です。
当時はバージョンの発行を行なっておらず、消えてしまったコードを遡ることができませんでした（このことを機にバージョン発行を覚えました）

元々、Lambdaで作成したソースコードをGitで管理したい、ローカル環境でテストしてから反映したい、等の意見を頂いていたので、ローカルによるLambda関数の実行、バージョンの管理をテーマに調べました、

そこで出会ったのが```LocalStack```でした。

## LocalStackとは

LocalStackは、ローカルにAWSのモック/テスト環境を作ってくれてるツールです。

イメージとしては、ローカルに擬似的なAWS環境を作ってくれて、料金など気にせずにテストや
動作確認を可能にしてくれます。
他にもツールはありましたが、LocalStackの導入が比較的簡単そうであったため、今回はこれを使用します。

## 要件

- ローカルにてLambda関数の実行
- ソースコードをGitにて管理
- AWS Lambda反映時に自動でバージョンを作成

## 環境

- OS: macOS High Sierra(10.13.2)
- Lambda ランタイム: Python3.6

# 事前準備

## docker, docker-composeのインストール

公式サイトは[コチラ](https://docs.docker.com/)

## aws-cliのインストール

```
$ brew install awscli
```

## aws アクセスキーの発行

[公式サイト](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html)にて方法が記載されているので、各自発行してください。

## aws プロファイルの設定

```
$ aws configure --profile localstack

AWS Access Key ID [None]: アクセスキー
AWS Secret Access Key [None]: シークレットキー
Default region name [None]: ap-northeast-1
Default output format [None]: text
```

## jqコマンドのインストール

```
$ brew install jq
```

---

# LocalStack導入手順

## LocalStackインストール&起動

```
$ git clone https://github.com/localstack/localstack
$ cd localstack
$ TMPDIR=/private$TMPDIR docker-compose up -d
```

上記実行後、```http://localhost:8080```にてlocalstackのダッシュボート表示

<img width="960" alt="スクリーンショット 2018-01-23 17.35.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/186189/42986c84-1480-cb6c-0d7c-8ad96c73c754.png">

## Lambda関数作成

```
$ mkdir 任意の作業ディレクトリ名
$ cd 任意の作業ディレクトリ名
$ vi lambda.py
```

```lambda.py
# サンプルコードです
def lambda_handler(event, context):
    return 'Hello from Lambda'
```

## localstack上にLambda関数を作成

1. zipで固める

```
$ zip lambda.zip lambda.py
```

2. localstack上に作成

```
$ aws --endpoint-url=http://localhost:4574 --region ap-northeast-1 --profile localstack lambda create-function --function-name="作成する関数名" --runtime=python3.6 --role="実行ロール名" --handler=lambda.lambda_handler --zip-file fileb://lambda.zip
```

<img width="960" alt="スクリーンショット 2018-01-24 11.01.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/186189/70c553ef-42fb-7a2f-50ed-3209d6d7a706.png">

## lambda関数実行

```
$ aws lambda --endpoint-url=http://localhost:4574 invoke --function-name "実行する関数名" --payload '{"key1":"value1", "key2":"value2", "key3":"value3"}' result.log
200
```

200が返って来たら成功

## レスポンスの確認

```
$ cat result.log | jq
```

result.logをjqコマンドでJSON形式に変換して出力することで確認できます。

---

## localstack上のlambda関数の一覧取得

```
$ aws --endpoint-url=http://localhost:4574 --region ap-northeast-1 --profile localstack lambda list-functions
```

## localstack上のlambda関数の削除

```
$ aws --endpoint-url=http://localhost:4574 --region ap-northeast-1 --profile localstack lambda delete-function --function-name "削除する関数名"
```

## localstack上のlambda関数の更新

```
$ aws --endpoint-url=http://localhost:4574 --region ap-northeast-1 --profile localstack lambda update-function-code --profile localstack --function-name "更新する関数名" --zip-file fileb://lambda.zip --publish
```

# 感想

dockerでローカルにawsテスト用のエンドポイントを作成し、awscliでlambda関数をLocalStackにあげて実行するような形です。
コマンドが少し長くて大変ですが、そこはエイリアスを設定したりでカバーできたらと思っています。
lambda関数の実行/作成/削除/更新のコマンドオプションに```--endpoint-url=http://localhost:4574```という指定があります。
これがLocalStackでの実行を指定しており、このオプションをつけないことによって、運用しているAWSに対して直接lambda関数の作成や更新など行うことができるため、localでテストしてすぐ本番に反映できるような感じです。
lambda関数更新時は、Lambda側が勝手にバージョンを作成してくれるため、Lambda側のバージョン管理も簡単にできるように感じました。

## 落とし穴

Lambdaにて関数を作成した場合、ファイル名は```lambda_function.拡張子```で固定されています。
ローカルでファイル名を```hogehoge.py```のように適当につけて、既存lambda関数に対して更新をかけると、ファイルがないと怒られて動かなくなるため、注意が必要です。(テスト環境が一時停止して結構焦りました。)

---

# 参考サイト

- LocalStackをつかってローカルでLambdaを実行してみた
https://dev.classmethod.jp/cloud/aws/localstack-lambda/

- AWS CLIのインストール
https://qiita.com/yuyj109/items/3163a84480da4c8f402c

- localstackをdockerを使ってセットアップする
https://qiita.com/liris/items/d89e88db44b4c30a6896

- aws-cli コマンド一覧(随時追記)
https://qiita.com/bakira/items/8a9481c99ed56a367415

- エンコードマニアックス
https://encodemaniax.com/