Edited at

AWS samの環境構築 RubyでLambda実行


AWS samの環境構築

AWS samの環境構築をし基本的にAWSの公式ドキュメントをもとに進め、LambdaはRubyで動かす

Installing the AWS SAM CLI - AWS Serverless Application Model


動作環境

MacOS 10.14.2 Mojave


AWS SAM CLIに必要なものの用意


  • Docker

  • Python 2.7または3.6のPipコマンド

  • AWS CLI: コマンドラインツール

Dockerのインストール

Docker for macはすでにインストール済みだが、参考までにDockerもhomebrewコマンドでHomebrew Caskを利用することでこのようにインストールできる

brew cask install docker

Pipがインストールされているか確認

pythonの2.7系か3系が入っていてpipがインストールされていれば良さそうなので、macのデフォルトでpipが使えるかどうかバージョンを確認してみる

pip --version

pip 18.1 from /usr/local/lib/python2.7/site-packages/pip (python 2.7)

どうやらmacのデフォルトのPython環境にpipがあるので2.7系だがそのまま使うことにする

AWS CLI: コマンドラインツールのインストール

awscliのインストールはこちらの公式のページを参考にする

AWS Command Line Interface をインストールする - AWS Command Line Interface

こちらのコマンド一発でよい

pip install awscli --upgrade --user

# --upgradeオプションはすでにインストール済みのawscliを更新する
# --userオプションは実行ファイルなどシステム領域に置かないようだ。 awsコマンドはここにある /usr/local/bin/aws
# 素の環境のサーバでこのコマンドを入れる場合はこれらのオプションはいらないだろう

aws cliでコンフィギュレーションをする

Quick Start - AWS Serverless Application Model より


Before You Begin

You must have an AWS account with an IAM user that has administrator permissions.


とあるのでアドミン権限のあるIAMユーザを作成ておく。

デプロイする際にはCloudformationの権限のみあればいいようなのだが、ローカル開発で必要な権限は何で、デプロイさせない権限の開発者の場合はCloudformationの権限を付けたくない、このような要件については別途調査する。それにしてもこいう説明はAWSのドキュメントってなんかいまいちなんだよなぁ

cliからコンフィギュレーションを実行する。とりあえずregionはap-northeast-1(東京リージョン)にしておく

aws configure

AWS Access Key ID [****************AAAA]:
AWS Secret Access Key [****************BBBBB]:
Default region name [None]: ap-northeast-1
Default output format [None]:

python環境をvirtualenvを使って構築している場合は仮想環境で AWS Command Line Interface をインストールする - AWS Command Line Interfaceを参考にすれば良さそうだ


AWS SAM CLIをインストールする

インストールする全体条件のものが全て揃ったのでAWS SAM CLIを入れる。

こちらもAWS CLIと同様にpipコマンド一発だ

pip install --user --upgrade aws-sam-cli

# --userや--upgradeのオプションもaws-cliと同様の意味


AWS SAM CLIを使ってローカル環境でLambdaを動かしてみる

こちらの公式ドキュメントをもとにLambda開発環境を構築する

Quick Start - AWS Serverless Application Model

いったんsample用のディレクトリを作って移動する

mkdir sam_sample && cd sam_sample

QuickStartではPythonで書いてるけど、Rubyで構築してみるBuilding Lambda Functions with Ruby - AWS Lambda


初期化

Rubyでsamプロジェクトを初期化するとsam-appというディレクトリが作られてlambdaのテンプレートなるファイルが作られた

sam init --runtime ruby2.5

Gemfileにhttpartyという全然知らないhttp clientがある

cd sam-app

sam_sample/sam-app » sam build --use-container
2019-01-10 20:39:56 Starting Build inside a container
2019-01-10 20:39:56 Found credentials in shared credentials file: ~/.aws/credentials
2019-01-10 20:39:56 Building resource 'HelloWorldFunction'

# aws-cliでアクセストークンやシークレットキー、リージョンの設定を入力していないとエラーになる

ビルドする際に sam build --use-container を使うとAWSのLambdaが実際に動いている環境に近いコンテナで実行してくれるとかなんとか書いてあるが、オプション無しでも実行時にDockerを使うので正直ようわからん


ローカル起動


API Gatewayで起動

Running API Gateway Locally - AWS Serverless Application Modelを参考に実行

sam local start-api

ブラウザで下記にアクセス

http://127.0.0.1:3000/hello

{

"message": "Hello World!",
"location": "175.131.178.24\n"
}


単独で起動

Invoking Functions Locally - AWS Serverless Application Modelを参考に実行

sam-app下にあるtemplate.yamlファイルを見ると、

Resourcesの直下のキー 'HelloWorldFunction' が一つ一つのLambdaファンクションの設定となっている

Resources:

HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: ruby2.5

標準入力からからのオブジェクトを渡して起動してあげる

echo "{}" | sam local invoke "HelloWorldFunction"

START RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Version: $LATEST
END RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72
REPORT RequestId: 52fdfc07-2182-154f-163f-5f0f9a621d72 Duration: 656.91 ms Billed Duration: 700 ms Memory Size: 128 MB Max Memory Used: 29 MB
{"statusCode":200,"body":"{\"message\":\"Hello World!\",\"location\":\"175.131.178.24\\n\"}"}

timeコマンドで測ってみると6.5秒ほどかかる。結構遅い。

sam buildした際に--use-containerを付けても付けなくても遅い。次で説明するテストコードを実行することでサクサクっと開発してある程度作ったら確認するのが良さそうだ

template.yml にcloudformationみたいな(同じ?)設定がありAPI GatewayでLambdaが呼び出されるようになっている


テスト実行方法


テスト実行で使うgemのインストール

gem install mocha

これ以外にもLambda本体で利用するgemのインストールする必要がある。

gem install httparty


rubyコマンドでテストを実行する

テストの内容は

ruby tests/unit/test_handler.rb

Loaded suite tests/unit/test_handler
Started
.
Finished in 0.001067 seconds.
-------------------------------------------------------------------------------------------------------
1 tests, 4 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
-------------------------------------------------------------------------------------------------------
937.21 tests/s, 3748.83 assertions/s

こちらは爆速である。デフォルトで設定されているテストはlambda_handlerで必要なeventのモックと、lambda内で通信するモックをつくり想定したレスポンスをlambda_handlerで返しているかどうか見ている。フィーチャーテストっぽい。


まとめ

* aws samの環境構築から、ローカル実行、テストの実行までできた

* 最近できたRubyでlambdaを動かせた

今後の課題


  • samを使ってローカル開発する場合の最小のIAMユーザの権限はなにか、またAWSにデプロイする際に必要な権限はなにか調査

  • Lambdaが実行時にS3をファイルに置くよような場合のIAMはどこで設定するのか調査

  • 開発、テスト、デプロイ、運用のライフサイクルを検討する。コマンドでデプロイではなくGithubでマージされたらデプロイするなど実運用を想定して検証

  • aws sam環境をDockerでコンテナにしてローカル開発環境を作れないか検討

参考情報

Installing the AWS SAM CLI - AWS Serverless Application Model

AWS Command Line Interface をインストールする - AWS Command Line Interface

AWS SAM で Hello World する - Qiita

ローカルで TypeScript + AWS SAM (Lambda/DynamoDB) の開発環境を構築する - Qiita

aws-sam-localだって!?これは試さざるを得ない! - Qiita

Lambda 関数のビルド - AWS Lambda

デプロイパッケージの作成 - AWS Lambda