読者です 読者をやめる 読者になる 読者になる

頭の中は異空間

生活を日々ハックしてよりよくするブログ

AWSでのサービス制作(テストアプリ)

AWS Python

 

概要

前回の記事

notwodaily.hatenablog.com

から、AWS Lambda + Amazon API Gatewayを用いたwebサービス制作について実際の制作の部分を抜き出しました。なるべく画像を使って説明します。今までに出た記事と比較すると、多少AWS側にUIの変更があるようです。そしてLambdaを見れば一目瞭然ですが、英語文章も出てきます。しかし文字の意味を捉えて行けば読み替えることは容易なので、焦らずにいきましょう(;´∀`)

登録の先から順を追って説明していきます。

※この記事は画像のせいで縦に糞長いです(泣)

 

テストアプリ

AWS Lambda

ステップ 2.1: Hello World Lambda 関数を作成する - AWS Lambda

に沿って作ります。しかしここでの説明はところどころ端折られているように思えて不満なので、細かい解説も入れてメモします。

 

まずここから、テスト用のfunctionを作成します。

f:id:notwo:20161113230257p:plain

Get Started Nowをクリック

次の画面が出たら、言語はPython2.7を選択します。

f:id:notwo:20161113230612p:plain

brueprintはhello-world-pythonを選択。filterにhelloと入れて絞り込みます。

f:id:notwo:20161113232146p:plain

そうしたら、configure triggersで空欄はAmazon API Gatewayを選択。

その他の入力欄はデフォルトのままです。

f:id:notwo:20161113232605p:plain
f:id:notwo:20161113232810p:plain

次はfunctionを作成します。

Name: myTestFunction

Runtime: python 2.3(pythonのバージョンはこれしか選べませんでした)

f:id:notwo:20161114070732p:plain

Role Name: myTestRole

※テストアプリなので名前は適当です。

ほかはデフォルトの入力のままです。

Nextボタンで作成すると、次の画面に遷移します。所謂設定確認画面です。

f:id:notwo:20161114072425p:plain

設定内容が正しいか確認して、問題なければCreate functionボタンで次画面へ。

この後API Gatewayの編集ページへ遷移しました。そこでリソースを定義します。

/myTestFunctionにカーソルが合った状態で、画面右上のアクションボタン→メソッドの作成→GET→✔マークをクリック

オプション設定フォームが現れるので、下記のとおりに入力

統合タイプ: Lambda関数

Lambdaのリージョンは

docs.aws.amazon.com

で確認できます。どうやら東京リージョンが出来ているようですので、これを使いましょう。

ap-northeast-1を選択して保存。 

f:id:notwo:20161114070958p:plain

これでfunctionを1つ作成できました。作成後でもさっき決めた設定を変更できるので、安心ですね!

Codeでデプロイするコードを編集できます。今回はpythonを選んでいるので、pythonコードがデフォルトで記載されています。ここではテストアプリなのでデフォルトのコードを使います。

ではせっかく作ったのでテストまでやりましょうか。

真ん中のTestボタンをクリック

f:id:notwo:20161114212512p:plain

といった具合にLambda functionを定義、テストまで完了しました。通常であれば必要な関数をこのように定義して必要に応じて呼ぶことが可能になります。そしてこれがLambdaに関数を定義する流れとなります。ここではデプロイまではしません。

 

Amazon API Gateway

f:id:notwo:20161114235910p:plain

上記で合わせてやってしまったので、割愛。とくにここではやることはありません。

 

S3, DynamoDBはテストアプリでは不要なため、特に触れません。本命のアプリ(別記事)で実際に利用します。そして今回は認証しないのでCognito未使用です。

 

 

テストアプリ(micro service: 最低レベルの小さなサービス)

ここからは、pythonのコードをデプロイし、リクエストを受け付けてレスポンスを返す普通のwebサーバとしての機能をLambdaに持たせます。やっとwebサーバっぽくなってきます。

まずLambdaコンソールを開きます。

f:id:notwo:20161115074614p:plain

このページ。

Create Lambda functionボタンを押し、microservice-http-endpointをfilter欄に入れます。出てきたカセットのうち、pythonのついてる方を選択します。

f:id:notwo:20161115075433p:plain

今度もデフォルトのままNextを押します。

f:id:notwo:20161115081611p:plain

今度のfunction名は「myPythonFunction」にします。

DescriptionにA simple backend (read/write to DynamoDB) with a RESTful API endpoint using Amazon API Gateway.とあるとおり、DynamoDBを利用したテストアプリが出来上がります。

Role nameはそれとわかる適当な名前で大丈夫です。権限については、下のフォームにあるpolicy templateで選んだテンプレートについている権限に加えて、フォーム上の説明(英語)にある通り、必要な権限が自動で入力されます。だから今のところは権限について気張る必要はありません。

たとえば、ここではmyPythonAppliRoleとします。

それ以外の項目はデフォルト値でOK。そのままNextボタンをクリック。

下の画像のようになるはずです。

f:id:notwo:20161119151627p:plain

入力に問題なければCreate functionボタンをクリックして、関数を作成します。

f:id:notwo:20161119152642p:plain

こんな感じでしょう。

Actions→Configure test eventをクリック。コードを下記の様な感じに編集。

f:id:notwo:20161120133023p:plain

まだDynamoDBを設定していないので、下記画像の様に

ResourceNotFoundException

のエラーが出ます。

f:id:notwo:20161119172911p:plain

じゃあDynamoDBの登録しましょう。と言っても何を入れたらいいかわからないので、ここではチュートリアルに沿って進めます。画面右上の「チュートリアル」ボタンを押して、解説に沿って入力して行きましょう。

f:id:notwo:20161120131827p:plain

作成後は下記画像のようになります。

f:id:notwo:20161120133927p:plain

 

 今度はLambdaのページに戻りましょう。LambdaのチュートリアルではAPIを叩けと言ってますが、先にそもそもTestが通るかをチェック。DashboardTestボタンをクリック。

f:id:notwo:20161120134725p:plain

status codeが200, bodyにjsonが返ってきているのがわかりますね。これでひとまず成功です。

しかしまだ肝心のAPI Gatewayが準備されていないのでこのまま外部からAPIを叩いても"Missing Authentication Token"とか返されてしまいます。今、TriggerタブのMethodがANYになっているので、ここにPOSTとGETを定義して、リクエストを受け付けられるようにします。ANYリンクをクリックして、前回の記事と同様に操作してそれぞれ用意します。

新しい APIからAPI名をpythontest, 説明は何でも構いませんので入れてAPIの作成ボタンをクリック

今、リソースが/(ルート)のままなので先にリソースを追加します。アクション→リソースの作成をクリック→新しい子リソースのリソース名をmusic, リソースパスをgetMusicにしてリソースの作成ボタンをクリック。

次に/getmusicをクリックしてGETメソッドを作成します。 

  • 統合タイプ:Lambda関数
  • Lambdaリージョン:ap-northeast-1
  • Lambda関数:さっき作ったLambda関数名

 

このままだとエラーが出るので修正します。リクエストパラメータをいじってもいいんですが面倒なのでcodeをいじります。

operation = event['httpMethod']

以下をすべてコメントアウトして

respond(None, None)

に置き換えてSave and Testボタンをクリックしてエラーが出ない(responseはnull)になることをチェック。

更にAPI Gateway側でもテストを押してみて、エラーが出ない(responseはnull)になることをチェック。

ここまで問題なかったら更に少しコードを書き換えて、DynamoDBに実際にデータを入れてみます。

codeを開き、

respond(None, None)

dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
    table = dynamodb.Table('Music')

    Artist = "Artist Sample"
    songTitle = "songTitle Sample"

    response = table.put_item(
        Item={
            'Artist': Artist,
            'SongTitle': songTitle
        }
    )

に変えてAPI Gatewayからテストします。エラーなく完了するはず(responseはnull)。今度は読み込みも一応テストしておきます。

再度codeを開き、上記コードのdynamodb = 以下を下記の通りに修正します。

dynamodb = boto3.resource('dynamodb', region_name='ap-northeast-1')
    table = dynamodb.Table('Music')

    Artist = "Artist Sample"
    songTitle = "songTitle Sample"

    try:
        response = table.get_item(
            Key={
                'Artist': Artist,
                'SongTitle': songTitle
            }
        )

    except ClientError as e:
        print(e.response['Error']['Message'])
    else:
        print("getItem succeeded:")
        print(json.dumps(response, indent=4))
    

また、頭のfromの塊を

from __future__ import print_function
import boto3
import json
from boto3.dynamodb.conditions import Key, Attr
from botocore.exceptions import ClientError

と書き換えてSave and Testボタンをクリックしてください。

これでテストが成功して下画像の通りに出力されていればOK

f:id:notwo:20161122213422p:plain

関数自体の戻り値はnullですがlog出力結果に確かにさっき入れたばっかりのデータが見て取れます。これでDB出力も問題ないですね。

 

pythonからDynamoDBを叩く方法は

docs.aws.amazon.com

を参考にしました。

 

そしてデプロイ。つまりはAPIを公開します。

デプロイする時はステージを選ぶのですがここでは何でも良いのでstagingとでもしましょう。

デプロイしたいAPI名を選択してリソースをクリック→アクションからAPIのデプロイを選択。ダイアログが開くので、例えば下記のように入力して、デプロイ

f:id:notwo:20161126143235p:plain

するとステージが選択されて今デプロイしたAPIの履歴やURLが見れるはずです。

f:id:notwo:20161126144206p:plain

ただし今回はルートリソース(/)の下にgetmusicをつけていますので、URLの後ろに/getmusicとつければアクセスできます。戻り値nullだけど。。

デプロイ後にAPIに修正が入ったなら再度デプロイすればいいです。

 

こんな感じでテストアプリとしては完了です。開発の大雑把な流れとしてはつかめてきたんじゃないかと思います。実際にwebアプリ開発する際にはcodeを書き換えたりIAM Roleを使いこなしていきますし、他にもS3やSESなどを組み合わせて本格的なアプリに仕上げていきます。

 

なんか無駄な操作をしているかもしれないので、この辺が詳しい人からしたらこうしたらいいのにっていうのがあるかもしれません。