シャッフル主任の進捗報告

興味のあるものを作ります。進捗を不定期にご報告します。

そうだ、教祖になろう。出エジプト記 第3章1節 Cloud9でLambdaの開発環境を構築する

ソースはクラウドにいまし、


Route53以外のAWSサービスが繋がったので、アプリケーションを開発していきたいのですが、まずは開発環境が必要です。

PythonだとPCでPyCharmでやってもいいのですが、クライアントサイドのVue.jsもあるし、せっかくAWSなのでCloud9を使ってみます。
Cloud9はクラウドで開発ができちゃうというサービスです。
サーバレスではなく、サーバインスタンスであるEC2を立てます。起動時間で利用料が発生しますが、利用しないときは自動で停止され、最低スペックなら月額2ドルほどで済むようです。

では早速、始めてみましょう。

f:id:chief-shuffle:20191204195313j:plain

「Name」で開発環境の名前をつけます。

f:id:chief-shuffle:20191204195839j:plain

利用できるインスタンスはないので新規に「EC2」を作ります。
一番スペックの低い「t2.micro」を選択、OSは「Amazon Linux」を選択します。
自動で停止する設定はデフォルトの30分にしておきます。

f:id:chief-shuffle:20191204200730j:plain

すぐに開発環境の作成が始まります。

f:id:chief-shuffle:20191204200007j:plain

1分ほどで作成されました。 早いですね。

では、Lambda関数を作ってみましょう。
Lambda関数のベースを整えてくれるウィザード機能を使います。
このウィザードを使うと色々なリソースがプロビジョニングされます。
まだよくわからないところもあるので、適宜触れていきます。

右端の「AWS Resources」をクリック。
表示される「λ+」マークをクリック。

f:id:chief-shuffle:20191204201413j:plain

「Function Name」にLambda関数名、「Application Name」にLambdaアプリケーション名を入力します。

AWS Lambda アプリケーションは、 Lambda 関数、イベントソース、およびその他のリソースを組み合わせたもので、協調して動作することによってタスクを実行します。

ということなんで単にLambda関数を作るより余計なものまでできそうなのですが、ここは大いなるCloud9の意思にしたがっておきます。

f:id:chief-shuffle:20191204201815j:plain

ランタイムは「Python 3.6」が最新のようです。
テンプレートは「empty-python」を選びます。

f:id:chief-shuffle:20191204202326j:plain

あとでCloudFrontと連携するので、「Function trigger」に「API Gateway」を選択、「Resource Path」に第2章2節 CloudFrontでAPI Gatewayを同一ドメイン化するで作ったAPIと同じパスを入力。
第2章2節の続き CloudFront以外からAPI Gatewayへのアクセスを閉じると同じくAPIキー必須にしたいので「Security」を「NONE_KEY」にします。

f:id:chief-shuffle:20191204203148j:plain

メモリとロールはデフォルトにしておきます。

f:id:chief-shuffle:20191204203237j:plain

「Finish」で作成終了です。

f:id:chief-shuffle:20191204203303j:plain

数秒で作成が終わります。楽。
左側のフォルダ構造は
ルート/Lambdaアプリケーション名/Lambda関数名
になります。

f:id:chief-shuffle:20191205194631j:plain

Cloud9は、クラウドリソースをテンプレートによりプロビジョニングするCloudFormationを使って色々なリソースをデプロイします。
CloudFormationを見てみると新しいスタックが存在しています。

f:id:chief-shuffle:20191205195746j:plain

このCloud Formationにより色々なリソースが作成されています。

IAMのロール。

f:id:chief-shuffle:20191205195422j:plain

Lambda関数。

f:id:chief-shuffle:20191205194804j:plain

同じくLambdaアプリケーションもありました。

f:id:chief-shuffle:20191205195431j:plain

API Gatewayもできています。
エンドポイントタイプが「Regional」でなく「Edge」になっていますが、本家サイトだとエッジ最適化は

CloudFront ディストリビューション経由でアクセスするエンドポイントです。

ともあるので、まあいいでしょう。

f:id:chief-shuffle:20191205195512j:plain

作成されたAPIを表示し、「メソッドリクエスト」をクリックすると、

f:id:chief-shuffle:20191204205909j:plain

APIキーの必要性」が「false」になっています。
さきほど「NONE_KEY」を選んだのですが、ここに反映されるわけではないのでしょうか。
よくわかりません。

f:id:chief-shuffle:20191204205943j:plain

「ステージ」を見ると、すでに「Prod」と「Stage」という2つのステージがデプロイされています。

f:id:chief-shuffle:20191204210154j:plain

ウィザードでできたものが多すぎて追いきれていない気がします。
CloudFormationのテンプレートを読めば全容が分かるんでしょう。

世はすべて事もなし


なにはともあれ、動かしてみましょう。

動くは正義です。

「Stage」のURL+/+リソース名にアクセスしますが、いきなりHTTPステータス502が返ってきました。
動かないじゃん。

f:id:chief-shuffle:20191204210356j:plain

これは、ウィザードで作ったlambda_function.pyの戻り値がHTTPレスポンス形式になってないからです。 ここまで色々作ってくれて、そこはやらないんかい!と思いますが、

f:id:chief-shuffle:20191204203338j:plain

lambda_function.py第2章2節 CloudFrontでAPI Gatewayを同一ドメイン化すると同じにします。
レスポンスのbodyはちょっと変えてみます。

f:id:chief-shuffle:20191205200402j:plain

import datetime
import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('The sources\'re in the cloud, all\'s right with the world! at ' + str(datetime.datetime.now()))
    }

Ctrl+Sで保存して動きを確認します。
「Run」をクリックして、「API Gateway(local)」を選択します。

f:id:chief-shuffle:20191205200423j:plain

実行すると「Status 200 OK」が返ってきました。
ちなみに「API Gateway(remote)」を選ぶと表示されているソースではなく、Lambdaにデプロイされているソースが実行されるようです。

f:id:chief-shuffle:20191205200506j:plain

修正したソースをLambdaにデプロイしましょう。 右側のLambda関数名を選択して「↑」ボタンをクリックするだけです。これはいい。

f:id:chief-shuffle:20191205200517j:plain

APIキー必須にしたいので、API Gatewayの「使用量プラン」の「APIステージの追加」をクリック。

f:id:chief-shuffle:20191204213320j:plain

先ほどCloud9が作ってくれた「Stage」ステージを追加します。

f:id:chief-shuffle:20191204213538j:plain

「リソース」の方で「APIキーの必要性」を「true」に変えます。

f:id:chief-shuffle:20191205073116j:plain

「Stage」を再度デプロイします。
リソースを選んで、「APIのデプロイ」をクリック。

f:id:chief-shuffle:20191205073301j:plain

「Stage」を選択して「デプロイ」。

f:id:chief-shuffle:20191205073414j:plain

API Gatewayに直アクセスしてみると、無事「Fobidden」になってAPIキーなしのアクセスが拒否されているのが分かります。

f:id:chief-shuffle:20191204215326j:plain

ちなみにCloud9ではAPIキー不足によるエラーにはなりません。Cloud9はあくまでLambdaのテストのようです。

f:id:chief-shuffle:20191204215205j:plain

それでは、CloudFront経由でアクセスできるように設定していきます。

第2章2節の続き CloudFront以外からAPI Gatewayへのアクセスを閉じるで修正したDistributionを選択。

f:id:chief-shuffle:20191204215539j:plain

「Create Origin」をクリック。

「Origin Domain Name」に「Stage」のURLを貼り付けます。
「Origin Protocol Policy」は「HTTPS Only」、「Origin Custom Headers」にAPI GatewayAPIキーを登録します。

f:id:chief-shuffle:20191204220006j:plain

次に「Behaviors」で/api/*を選択して、「Edit」をクリック。
「Origin or Origin Group」をさきほど作ったOriginに変更します。

f:id:chief-shuffle:20191204220457j:plain

デプロイを待ってアクセスを確認すると、

f:id:chief-shuffle:20191204220613j:plain

新しく作ったLambda関数の結果に差し替えられました。

これでサーバサイドの開発環境が整いました。

f:id:chief-shuffle:20191204221129p:plain

次回はいよいよGoogleスプレッドシートにアクセスしていきます。

なお、EC2の一覧でCloud9用のインスタンスを確認できます。 Cloud9をしばらく放っておくと、ちゃんと「Stopped」になるみたいですね。

f:id:chief-shuffle:20191204220938j:plain