この記事は 『CRESCO Advent Calendar 2017』 5日目の記事です。

 

こんにちは、Y K です。

普段はAWS関連のお仕事がメインです。
開発、構築、テスト、アーキテクトやら、運用保守となんか役割がよくわかりません。
見積もりもやったりします。
さっさと、Admin権限つけたロールを付与してほしいものです。

弊社でも、最近サーバーレスアーキテクチャを適用しているプロジェクトがちらほら見られます。

先日、私は「ServerlessConf Tokyo 2017」で Serverless Tech Challenge に参加してきました。
1dayハッカソンみたいなものです。
惜しくも商品であるギフト券は逃しましたが、それ以上の収穫があったように思います。

ちなみに、お題は

作るのは以下から選択

・Chat、SNS、掲示板、マッチング

制約事項

・認証機能、GUI、画像処理があること
・AWSのみであること
・これはServerlessConfのWorkshopであること

でした。

当日の風景はこんな感じ。

私は、当日参加者リストに名前が載っておらず、
他にもリストに載ってない方がいたので、その方とチームを組みました。
私のチームは掲示板を選択し、このような構成で作成。

iOSエンジニアの方だったので、GUIをiOSで提供し、AWS側を私が作成する役割分担。
そこで使用したのが、「Chalice」です。

この記事の主題でもある「簡単にサーバーレスアーキテクチャ」を実現できるフレームワークです。
AWSが提供してくれています。

ということで、さっそく使っていきましょう。
インストール手順は、上記のgithubにも記載がありますが、

$ pip install chalice

だけでいいです。(pipは入ってる前提ですけど。。。)

$ chalice new-project cresco_adventcalendar

で、プロジェクト開始できます。
ディレクトリが作成され、サンプルが作成されます。
こんな構成。

$ tree
.
├── app.py
└── requirements.txt

これですでに動く状態なので、ローカルで動かしてみましょう。

$ chalice local
Serving on localhost:8000

デフォルトでは、8000ポートで受付です。
なので、curlすればこのように動作します。

$ curl http://localhost:8000/
{“Merry”: “Christmas”}

戻って見てみると

127.0.0.1 - - [26/Nov/2017 11:42:06] "GET / HTTP/1.1" 200 -

とリクエストが見えます。
chalice で作成したアプリのdebugは、ngrokと組み合わせて使用するととても便利です。
以下のコマンドを実行すると、

$ ngrok http 8000
ngrok by @inconshreveable

Session Status online
Version 2.2.8
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://eff3c3c1.ngrok.io -> localhost:8000
Forwarding https://eff3c3c1.ngrok.io -> localhost:8000

Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00

こんな感じで、publicなドメインをローカルに経由してくれます。
その状態でcurlすると、ローカルの動いているプログラムが応答します。

$ curl https://eff3c3c1.ngrok.io/
{“Merry”: “Christmas”}

chalice の良いところは、ここだけではなく、
そのままAWS上にデプロイできるところです。

$ chalice deploy
Creating role: cresco_adventcalendar-dev
Creating deployment package.
Creating lambda function: cresco_adventcalendar-dev
Initiating first time deployment.
Deploying to API Gateway stage: api
https://fzi1nliael.execute-api.ap-northeast-1.amazonaws.com/api/

はい、これでAWS上に、
サーバーレスのAPIが動作している状態となります。

curl してみましょう。

$ curl https://fzi1nliael.execute-api.ap-northeast-1.amazonaws.com/api/
{"Merry": "Christmas"}

動作しました!
複雑なものは厳しいかもしれませんが、PoCとか重宝しそうです。

ちなみに、3rd Partyのライブラリや自作ライブラリなどを使う場合は
vendorディレクトリに3rd partyのもの、chalicelibには自作のものを格納するのが作法みたいです。
configとかもchalicelibになります。
AWSのコンソールからはapp.pyのソースしか見えないので、ハマるポイントになるかもしれません。
またvendor配下の者はwheelして置く必要があります。

$ tree
.
├── app.py
├── chalicelib
│ └── myOriginalLib.py
├── requirements.txt
└── vendor
├── slackweb-1.0.5-py3-none-any.whl
└── slackweb-1.0.5.tar.gz

これでSDK提供されているのも、簡単に作成できそうですね!!
backlogとslackを連携したりとか、backlogのAPIを使って操作するものなんかは、
この構成ならほぼ無課金でいけるんじゃないでしょうか。

Cloud9でもやってみる
さて、先日のre:Inventで、AWSについにcloud9が登場しました。
AWSが買収した時から楽しみでした。

さっそく使ってみましょう!
コンソールからポチポチと行きますとウィザードが開きます。

プロジェクト名を決めます。

次に、EC2を新規に作成するか、既存のサーバーを使用するかを選択します。

進んでいくとサマリが出てくるので、「Create Environment」を押下すると、自動でインスタンスが立ち上がってきます。

 

ちょっと待ちます。

立ち上がってきました。
ここからサーバーレスのAPI gateway+Lambda構成をする準備を行っていきます。

右側の「AWS Resources」をクリックして「λ+」をクリックすると、
Lambdaを使用するためのウィザードが開始します。

ここは画面に従っていきましょう。

言語だったり、テンプレートを指定します。

トリガーにAPIを指定し、

pathを指定していきます。

そうすると、こんな感じで、テンプレートが作成されます。

今回は、動作検証だけなので、シンプルにしましょう。

import boto3
import json
print('Loading function')
dynamo = boto3.client('dynamodb')
def respond(err, res=None):
return {
'statusCode': '400' if err else '200',
'body': err.message if err else json.dumps(res),
'headers': {
'Content-Type': 'application/json',
},
}
def lambda_handler(event, context):
return respond(None, {"cresco":"advent"})

右側のパネルからLambdaを右クリックすると以下のようになります。

Runから
Lambdaのローカル実行、リモート実行
API gatewayのローカル実行、リモート実行
が利用できます。
Lambda、API gatewayのローカル実行ってかなり素敵ですよね。

もちろん、「deploy」をクリックすると、Apigateway+Lambda構成が作られていました。

$ curl https://6du10u5jk8.execute-api.ap-southeast-1.amazonaws.com/Prod/sample
{"cresco": "advent"}

chaliceと似た挙動ですが、ちょっと違うのでまた別物が動いていそう。

今後、自前インスタンスで環境を構成してみたときに、中身見てみることにします!
cloud9を使用することで、サーバーレス環境の開発がもっと捗りそう。

cloud9の言語メニューには、
goとかあったので、プレアナウンスのあったlambda-goは
ここから始まっていくのかもしれませんね。

AWSとともに、素敵なAPIライフを!!
※今回作成したAPIは、クリスマスまではAPI可能にしておきます!