こんにちは。ざわかかける!のざわ(@zw_kakeru)です。
今回はWebアプリケーションのチュートリアルとして、AWS API Gateway経由でLambdaを動かそうと思います。
この手の記事はネットにたくさんありますが、API Keyによる検証を挟むことにより、API Keyを持っている人しかサービスを利用できないようにしてみます。
付与するIAMロールも、必要最低限のものを作成しながら進めていきます。
はじめに
今回の手順としては、まず下準備として
- CloudWatch上にロググループを作成
- IAMポリシー&ロールの作成
を行った後で
- Lambdaの作成
- API Gatewayの作成
を行います。
順を追って説明していきます。
ロググループの作成
サーバー上で何かが起きた時、あるいは何も起きなかった時にその原因を探る手がかりを残しておけるようにログを吐き出す場所を作成します。
この手順をめんどくさがらずにやっておくことで、後々の開発でとても助けられることになります。
AWS CloudWatchを開いて左側の「ロググループ」タブからロググループを表示し、「ロググループを作成」ボタンを押します。
ロググループ名は何でもいいですが、Lambdaでのログを出力することが分かるように「/aws/lambda/hoge」などがいいでしょう。
(hogeの部分は自分が作りたいサービスの名前に変えてください。)
設定できたら「作成」ボタンを押してください。これでロググループの作成ができました。
ロググループ一覧のページでも今自分が作ったグループが表示されているかと思います。
IAMの作成
LambdaにアタッチするためのIAMポリシーとロールを作成します。
付与する権限は、CloudWatch上のログ取得と書き込みです。
先ほどログを出す場所を作成したので、ここに書き込む権限のついたパスポートのようなものを作成するイメージです。
IAMポリシーの作成
まずはポリシーの作成です。
ログを書き込む権限そのものの作成を行います。
AWS IAMを開いて、左側の「ポリシー」タブからポリシーのページを開き、「ポリシーの作成」をクリックします。
するとサービスを選択するための空欄が表示されるので、ここに「CloudWatch Logs」と入力してCloudWatch Logsを選択します。
そうすると次にアクション許可を選択することができるようになるので、「書き込み」の一覧から「CreateLogStream」と「PutLogEvents」を選択します。
すると、「リソース」の箇所に「ARNを追加」と書かれたリンクが出現するのでここをクリックします。
ログを書き込めるようになったのですが、この権限ではCloudWatch上の全てのロググループに書き込める必要はなく、先ほど作成した「/aws/lambda/hoge」にだけ書き込めればいいわけです。
よってこの設定を記述します。
「Resource log group name」に先ほど作成したロググループ「/aws/lambda/hoge」と入力します。
「Resource log stream name」については、グループ内であれば全てのストリームにアクセスできて良いでしょう。
ここは空欄にして、右側の「任意の log stream name」にチェックを入れます。(*が自動で入力されます。)
リソースのリージョンについては、ログストリームを作成したリージョンを記入します。東京であればap-northeast-1です。
以上が設定できたら「ARNを追加」のボタンを押します。(「リソース ARN」の項目は、上記3つの項目を入力すると自動で設定されます。)
設定できていることが確認できたら「次へ」を押してポリシー名に自分が作りたいサービス名などを入力し、「ポリシーの作成」を押します。
これで必要最低限の権限だけを持ったIAMポリシーが作成されました。
ポリシー一覧の画面でも今作ったポリシーが表示されるようになります。
IAMロールの作成
続いてIAMロールの作成に移ります。
先ほどのIAMポリシーでログを書き込む権限自体が作成できたので、次はこの権限をICパスポートか何かに焼き付けるイメージです。
AWS IAM左側の「ロール」タブからロールのページを開き、「ロールを作成」をクリックします。
「信頼されたエンティティタイプ」は今回はLambdaで使うため「AWSのサービス」、下に表示されるユースケースは「Lambda」を選択します。
次に進み、許可ポリシーの選択画面で先ほど作成したIAMポリシーにチェックを入れて次に進みます。
最後にロール名に自分が作りたいサービス名などを入力し、「ロールの作成」を押します。
これで必要最低限の権限だけを持ったIAMロールが作成できました。
Lambdaの作成
やっと準備が整ったのでLambdaの作成に入ります。
AWS Lambdaを開き、左側の「関数」タブから関数一覧を表示して「関数の作成」を選択します。
関数は「一から作成」を選択し、関数名に自分が作りたいサービス名などを入力します。
ランタイム、アーキテクチャも自分が作りたいサービスや使う言語に応じて設定します。
実行ロールは「既存のロールを使用する」を選択し、表示される「既存のロール」欄に先ほど作成したIAMロールを入力します。
IAMポリシーでログを書き込む権限自体を作成し、IAMロールその権限をICパスポートに焼き付けたので、このICパスポートをLambdaに渡すことでLambdaくんは実際にログを書き込めるようになったというイメージです。
確認できたら「関数の作成」ボタンを押します。これでLambdaの作成ができました。
初期状態では「Hellow, Lambda!」と出力してくれるプログラムが書かれています。
右上の「アクション」のボタンから「新しいバージョンを発行」を行います。
「発行」ボタンを押すことで発行できました。
ここからはおまけです。
やってもやらなくても構いません。
右上の「アクション」のボタンから「エイリアスの作成」を行います。
エイリアス名を「prod」(名前は何でもいいです)などにし、バージョンに「$LATEST」を指定して作成します。
prodエイリアスを指定することで常に最新バージョンのLambdaが実行されるようになります。
こうすることでLambdaを編集して新しいバージョンが発行されるたびに後述のAPI Gatewayの接続先を変える、という手間を省くことができます。
API Gatewayの作成
Lambdaができたので、あとはこのLambdaを実行する口を用意してトリガーに設定してあげたら完了です。
APIの作成とデプロイ
AWS API Gatewayを開き、左側の「API」タブでAPI一覧画面を表示して「APIを作成」を押します。
するとAPIタイプを選択できるので、普通の「REST API」を構築します。
種類は「新しいAPI」で、APIの名前に自分が作りたいサービス名などを入力します。
エンドポイントタイプは「リージョン」に設定して「作成」を押します。これでAPIの作成ができました。
次にリクエストに対するメソッドの作成に移ります。
一覧から今作成したAPIを選択し、リソースページのメソッド一覧(今は何もメソッドはないですが)右側にある「メソッドを作成」を押します。
メソッドタイプに自分が作りたいサービスに応じて設定し、統合タイプにLambda関数を指定してください。
するとLambda関数を指定する欄が表示されるので、先ほど作成したLambdaとそのリージョンを指定します。
この時、先ほどのおまけでprodのエイリアスを作成した人は末尾に「:prod」を追加してください。
(補完で出なければ手動で打ち込みます。)
設定できたら作成ボタンを押します。
リソース画面に戻ってくるので、右上の「APIをデプロイ」ボタンを押します。
ステージ名をprodとか適当に入力してデプロイします。
これでこのAPIにリクエストが来ると、Lambdaに通知が行くようになりました。
Lambdaのトリガーに設定する(API Keyの設定)
最後に、API Gatewayから通知が来たらLambdaにを実行するようにLambda側を設定しなければいけません。
先ほど作成したLambdaの関数画面を再び開き、「関数の概要」と書かれているの図で「トリガーを追加」のボタンを押します。
するとトリガー設定画面が出てくるので、トリガー種類に「API Gateway」を選択し、「既存のAPIを使う(Use existing API)」を選んで先ほど作成したAP名Iおよびステージ名を設定します。
また、API Keyありの問い合わせをしたい場合はここでSecurityの項目に「API Key」を選択します。
(不要な人はOpenを選択します。)
設定できたら「追加」を押してください。
これAPIのエンドポイントにリクエストが来たら、作成したLambdaが実行されるようになりました。
お疲れ様でした。
API Keyの確認
Securityの項目に「API Key」を選択した場合は、すでに自動でAPI Keyが作られているはずなのでそれを確認しましょう。
API Gatewayに戻り、左側メニューの「API Key」を選択します。
するとここに作成されたAPI Keyが表示されているので、この値を使えばAPIを使うことができます。
ちなみに、LambdaとAPI Keyの紐付けの設定は、左側メニューの「使用量プラン」のところから確認できます。
動作確認
curlで動作確認をしてみましょう。
#!/bin/bash
# APIキー
API_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# API GatewayのエンドポイントのURL
API_ENDPOINT="https://xxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod"
# curlコマンドを使用してAPI GatewayにGETリクエストを送信
curl -X POST \
-H "x-api-key: $API_KEY" \
"$API_ENDPOINT"
エンドポイントのURLは先ほどLambdaで設定したトリガーの項目で、「API endpoint」という部分に書かれているのでそれを入力しましょう。
API Keyを使う人はAPI Keyの記述も忘れずに行います。
無事にLambdaが実行されたことが確認できました。
また、実行のログがCloudWatchにも出力されているのが見て取れました。
これで自分の開発を進めていけますね。
めでたしめでたし。
おわりに
APIからLambdaを実行できるようになりましたが、開発としてはここからが始まりです。
結構手間がかかる上に色々な知識が必要になりますが、幸いにも今日紹介した仕組みは全て簡単に削除できるので、何かミスしたりうまくいかなかったりしたらゼロからやり直すというのもありかもしれません。
このチュートリアルをもとにして何かしらのwebアプリケーションを開発し、また戻って来たらめちゃくちゃ分かるようになってたりもすると思うので、その時はまた会いましょう。
以上です。