LocalStackをつかってローカルでLambdaを実行してみた

localstack

どうも!AWS勉強中の西村祐二@大阪です。

今回は前々からさわってみたいと思っていた
AWSのモックフレームワークを提供する「LocalStack」をつかって
ローカルでLambda関数を実行してみたいと思います。

LocalStackとは

クラウドアプリケーションを開発するための使いやすいテスト/モッキングフレームワークを提供するツールです。

イメージとしては、ローカルに擬似的なAWS環境を作ってくれて、
料金など気にせずにテストや動作確認を可能にしてくれます。

LocalStackが提供しているAWSサービス

  • API Gateway
  • Kinesis
  • DynamoDB
  • DynamoDB Streams
  • Elasticsearch
  • S3
  • Firehose
  • Lambda
  • SNS
  • SQS
  • Redshift
  • ES (Elasticsearch Service)
  • SES
  • Route53
  • CloudFormation
  • CloudWatch

LocalStackの使い方

Readmeを読むとawscliかプログラムで使用できると記載されています。
今回はaws cli を使って、--endpoint-url オプションに LocalStackの偽装エンドポイントを指定して実行する方法で実施していきます。

各サービスに対応するエンドポイントは下記のようになっております。

  • API Gateway at http://localhost:4567
  • Kinesis at http://localhost:4568
  • DynamoDB at http://localhost:4569
  • DynamoDB Streams at http://localhost:4570
  • Elasticsearch at http://localhost:4571
  • S3 at http://localhost:4572
  • Firehose at http://localhost:4573
  • Lambda at http://localhost:4574
  • SNS at http://localhost:4575
  • SQS at http://localhost:4576
  • Redshift at http://localhost:4577
  • ES (Elasticsearch Service) at http://localhost:4578
  • SES at http://localhost:4579
  • Route53 at http://localhost:4580
  • CloudFormation at http://localhost:4581
  • CloudWatch at http://localhost:4582

今回はLambdaを使いたいと思います。

手順

事前準備

docker、docker-composeを使えるようにしておいてください。

追記
aws-cliの設定を行っておいてください。
下記サイトが参考になります。
http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html

環境

Mac : macOS Sierra
docker : 17.06.0-ce-rc4
docker-compose : 1.14.0-rc2
LocalStack : v0.5.3

インストール

Githubのページなどに幾つかの方法が記載されていますが
一番簡単そうなdocker-composeを使いたいと思います。

# git clone https://github.com/atlassian/localstack.git
# cd localstack

起動

# docker-compose up

Creating network "localstack_default" with the default driver
Pulling localstack (atlassianlabs/localstack:latest)...
latest: Pulling from atlassianlabs/localstack
・
・
・
localstack_1  | Starting local Elasticsearch (port 4571)...
localstack_1  | Starting mock ES service (port 4578)...
localstack_1  | Starting mock S3 (port 4572)...
localstack_1  | Starting mock SNS (port 4575)...
localstack_1  | Starting mock SQS (port 4576)...
localstack_1  | Starting mock API Gateway (port 4567)...
localstack_1  | Starting mock DynamoDB (port 4569)...
localstack_1  | Starting mock DynamoDB Streams service (port 4570)...
localstack_1  | Starting mock Firehose service (port 4573)...
localstack_1  | Starting mock Lambda service (port 4574)...
localstack_1  | Starting mock Kinesis (port 4568)...
localstack_1  | Starting mock Redshift (port 4577)...
localstack_1  | Starting mock Route53 (port 4580)...
localstack_1  | Starting mock SES (port 4579)...
localstack_1  | Starting mock CloudFormation (port 4581)...

・
・
・
localstack_1  | [2017-06-19T05:46:58,703][INFO ][o.e.n.Node               ] [ql3nIad] started
localstack_1  | Ready.

Readyのログが出力されたら
LocalStackのダッシュボードの「http://localhost:8080」にアクセスし、ページが表示されるか確認しましょう。

問題なく起動していたら下記のようなページが出力されるかと思います。

2017-06-19 14.49.34

Lambda関数作成

▼適当なディレクトリでlambda.pyを作成します。

動作確認が目的のためプログラムは簡単にしています。

# mkdir localstack-test
# cd localstack-test
# vi lambda.py
---
def lambda_handler(event, context):
    print(event)
    return 'Hello from Lambda'
---

▼zipに固める

# zip lambda.zip lambda.py

▼LocalStack上にLambda関数を作成する

関数作成時のオプションで
--endpoint-url=http://localhost:4574
とすることで、LocalStack上に作成されます。

また今回次のように設定しました。
関数名 : f1 ※任意に設定可能
ランタイム : Python2.7 ※他は未対応?
ロール : r1 ※任意に設定可能、ロールの作成は必要ないぽい

aws --endpoint-url=http://localhost:4574 --region us-east-1 lambda create-function --function-name=f1 --runtime=python2.7 --role=r1 --handler=lambda.lambda_handler --zip-file fileb://lambda.zip

作成が完了したら、LocalStackのダッシュボードを確認してみましょう。 下記画像のように作成したLambda関数が表示されます。

2017-06-19 19.24.14

「Show Code」をクリックするとプログラムを確認することができます。

Lambda関数実行

▼先程同様にオプションを
--endpoint-url=http://localhost:4574
とすることでLocalStack上で実行してくれます。

今回は動作確認が目的のため
関数に渡すデータを
--payload '{"key1":"value1", "key2":"value2", "key3":"value3"}'
としており
出力先を result.log に出力するように指定しています。

# aws lambda --endpoint-url=http://localhost:4574 invoke --function-name f1 --payload '{"key1":"value1", "key2":"value2", "key3":"value3"}' result.log
200

上記のように200が帰ってきたら成功です。

▼出力結果を確認

実行が完了したらresult.logが作成されるので中身を確認してみます。

# cat result.log
START RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx Version: $LATEST
{u'key3': u'value3', u'key2': u'value2', u'key1': u'value1'}
END RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx
REPORT RequestId: xxxxxx-xxxx-xxxx-xxxxx-xxxxxxxxx Duration: 9 ms Billed Duration: 100 ms Memory Size: 1536 MB Max Memory Used: 14 MB
"Hello from Lambda"

作成したプログラム通り、eventの出力などされていることがわかります。

さいごに

いかがだったでしょうか。
とりあえずですが、LocalStackを使ってローカルでLambdaを実行してみました。

実際に触ってみてまだまだ発展途上な印象を受けましたが、
AWSのサービスを手軽に、料金を気にせずに利用できるため
テストや動作確認の際にかなり重宝しそうです。

誰かの参考になれば幸いです。

  • OHTSUKA Ko-hei

    お世話になります。
    有用な記事ありがとうございます。

    中途のaws –endpoint-url=http://localhost:4574 lambda create-function .. を試してみましたが、まず

    You must specify a region. You can also configure your region by running “aws configure”.

    とリージョンを聞かれました。これは適当に –region us-east-1 をつけたりすると回避できたのですが、その後

    Unable to locate credentials. You can configure credentials by running “aws configure”.

    と言われてしまいます。credentialということなので適当な値を設定しても動かないのではないかと思うのですが、この辺何か手順のアップデートがあったかなどの情報お持ちではないでしょうか。
    awscliのバージョンは
    aws-cli/1.11.111 Python/2.7.6 Linux/3.4.0+ botocore/1.5.74
    を使っております。

    もしご存知でしたら教えていただければ幸いです。

    • 西村祐二

      OHTSUKA Ko-hei さん

      コメントありがとうございます。
      西村祐二と申します。

      エラーについてですが、aws-cliのセットアップの際に作成した設定が読み込まれたため出力されなかったようです。
      –regionオプションについてもデフォルトでリージョンを指定する設定としていたためエラーが出なかったようです。
      なので、–region オプションがなくてもコマンドが通ったということになるかと思います。

      こちらで回答になっておりますでしょうか。
      手順については後ほど追記させていただきます。

      ちなみに私のaws-cliの環境は
      aws-cli/1.11.86 Python/3.6.0 Darwin/16.6.0 botocore/1.5.49
      となっております。

      aws-cliの設定ですが下記URLが参考になるかと思います。
      http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html