rnzoo 0.4.1をリリースしました
去年ふっとgolang 1.7に上げといたrnzooですが、先日v0.4.1をリリースしました。アップデートはhomebrewなら以下で。
brew update brew upgrade rnzoo
内容は、rnzoo ec2list
に、-t, -tsv
オプションを追加しました。rnzoo ec2list
は、ec2のインスタンスリストを出力しますが、区切りがタブではなく、見た目重視のスペースになっていて、シェルスクリプトとの連携具合が良くなかったので、TSVで出すようにするオプションを追加しました。
rnzoo ec2list -tsv | grep "stopped" | cut -f1
とかで必要なカラムを取り出すことができます。
AWS API Gateway+LambdaでSlackにメッセージをPOSTする(後編)
前編、中編にて、AWS API Gateway + Lambdaを使って、post-slack WebAPIを作り、テスト実行まで行いました。後編では、API keyの設定と実際に使えるようにデプロイをしていきます。
Slack Webhook URLは、それを知っていれば誰でも使うことができます。せっかくAPI Gatewayを使うので、API keyを使って制限をかけます。*1Usage PlanとAPI keyを使うと、アクセス自体の制限以外に、使用量の制限、スロットリングをかけることができます。
API GatewayのStageとUsagePlanとAPI key
今回の部分に関して、それぞれ用語とその関連を先に頭に入れると理解しやすいので、先にその説明をします。
Stage
API GatewayのStageは、いわゆる開発(dev)、検証(staging)、本番(prod)といった、動作環境を指します。これらを作ることで、一般的な開発フローと同じく、まず開発環境にデプロイしてーという流れと同じことができます。*2
Usage Plan
Webサービスなどでの、Free PlanやStandard Plan、Unlimited Planみたいなものです。スロットリングや使用量制限を定義します。Usage PlanはStageと紐付ける必要があり、Stageがないと作れません。
API key
対象ごとに発行する認可用のkeyです。API keyは、発行は単体でできますが、Usage Planと紐付けないと、実際にAPIで使うことはできません。
post-slackでの設定
前述の説明で、およそそれぞれの関連性がわかったかと思います。ここからは実際にそれを設定していきます。この部分がAWSコンソール上から作成しようとすると、先に作る必要があるものがあったりなどハマりがちなので、スムーズに行く順番で行っていきます。
API keyの必須設定と、API GatewayのStageの作成(=デプロイ)
まず引っかかりやすいのが、Stageを作成するには、そのWebAPIを1回はデプロイする必要があることです。左メニューから、Stageを選択して、[Create]で進むと、必須項目のDeploymentで選択できるものがなく、「どうやって環境作るんだろう・・・」と感じてしまいます。*3
デプロイするものができるまでStageは不要というのもわかるんですが、API keyで制限をかけるには、Usage Planが必要で、Usage Planの作成にはStageが必要でなので、ハマります。
今回は、API key必須の設定だけしてデプロイすることでAPI keyでの制限を有効にして進めていきます。
post-slack APIのResource -> / POSTを選択します。前回も使ったマス目の並ぶ画面です。Method Requestを選択します。
API Key Requiredをtrueに変更します。これだけです。Authorizationというのもありますが、こちらは今回使いません。
API key必須の設定ができたので、デプロイしてStageを作ります。[Action]-> Deploy APIを選択します。
Deploy APIというダイアログが出てくるので、Deployment Stageで[New Stage]を選びます。そうするとフォームが出てくるので、dev
というStageにします。Deploymentの所は、デプロイ(リリース)の内容を入れます。今回は適当にfirst deploy
にしてます。*4 [Deploy]を押すとデプロイされます。
URLが割り当てられます。これを後で使うので、コピー等で取っておいてください。
WebAPIのURLは以下のフォーマットです。
https://<ランダム>.execute-api.ap-northeast-1.amazonaws.com/<Stage名>
早速curlで試してみます。--dump-header -
は、レスポンスヘッダの出力を標準出力に出すオプションです。
curl -XPOST -H 'Content-Type: application/json' https://<あなたのURL> -d '{"message":"hi"}' --dump-header - HTTP/1.1 403 Forbidden Content-Type: application/json Content-Length: 23 Connection: keep-alive Date: Tue, 07 Feb 2017 13:39:33 GMT ...AWS独自ヘッダーかとか色々... {"message":"Forbidden"}
はい。403の権限がないエラーになります。API keyがないからです。
Usage Planの作成とAPI keyの作成
次にUsagePlanを作ります。左メニューのUsagePlanを選択し、[Create]で作り始めます。
ここではdevという名称で、Planを作ります。スロットリングは適当に10/secぐらい、burstも10にしておきます。使用制限は1,000/dayぐらいにしてみます。この辺の値は適当なので、適宜どうぞ。入れたら[Next]で次へ。
どのAPIのStageに適用するかを設定するので、[Add API Stage]を選択し、
post-slack APIと先ほど作ったdev Stageを指定して、チェックを選択します。
紐付けられたら、[Next]で進みます。
次はAPI keyの設定に進みます。[Create API keyand Add to Usage Plan]を選択し、新しくAPI keyを発行します。
Nameはnotification-program
にします。ここは好きなもので構いません。keyは、Auto Generateでランダムに生成します。入れたら[Save]します。
Usage PlanのAPI key一覧に戻るので、notification-programというkeyがあることを確認して、[Done]で完了します。
作成後、API keyタブから、notification-programを選択すると、API keyの詳細を見ることができます。
API keyのshowを選択すると、値を見ることができます。これをリクエストヘッダに入れて使います。
これでpost-slack APIにdev PlanとAPI keyが出来ました。
API keyを使ってcurlからslackへPOST
さていよいよ完成したので、curlを使ってリクエストしてみます。API keyはx-api-key
というリクエストヘッダで送ります。
curl -XPOST -H 'Content-Type: application/json' -H 'x-api-key: <あなたのAPI key>' https://<あなたのAPI URL> -d '{"message":"post slack message from my machine via API Gateway/Lambda!"}' --dump-header - HTTP/1.1 200 OK Content-Type: application/json Content-Length: 17 Connection: keep-alive Date: Tue, 07 Feb 2017 14:05:37 GMT ...AWS独自ヘッダーかとか色々... "posted to slack"
いやーレスポンスがひどい。でもSlackには表示されました!
これで、HTTPS+API keyでslackへのPOSTができるようになりました。後はスクリプトから叩いたり、他の人に渡す時は別のAPI keyを発行して渡して使うことができます。
参考
AWS API Gateway+LambdaでSlackにメッセージをPOSTする(中編)
前回、Slack Incoming Webhookの作成と、それを使うLambdaを作成したので、続いてAWS API GatewayとLambdaを繋いでいきます。書いていたら思ったより長くなったので、API Gatewayのテスト実行までを中編にして、後編で、API keyの設定とデプロイを行います。
Lambda自体は、サーバレス(正確にはインスタンス管理レス)で動きますが、呼び出しは他のAWSイベントをフックするものが多いです。それはそれでいいんですが、どうしてもAWSよりのコードが入るので、そこをWebAPIという形で、汎用的に扱えるようにします。
しかし、普通にWebAPIを用意しようとすると、サーバを準備して、nginx/apacheやプログラムを作って、Lambdaを呼び出すようにしなければならないため、API Gatewayを使って、サーバの運用なしで使えるWebAPIを作ります。
今回は1機能だけなので、直接/にJSON{"message":"hello world"}
をPOSTしたら、Slackに投稿されるようにします。
AWS API GatewayとLambdaを繋ぐ
まずはAPI Gatewayで、WebAPIを作っていきます。AWS Consoleから、API Gatewayを開きます。
[Create API]を選択するとフォームが出てくるので、名称を入れます。ここでは、post-slack(好きな名称で良いです)としておきます。
[Create API]で作成すると、post-slack APIのメニューが出てきます。Resourceを選び、そこで/を選択し、[Action] -> [create method]を選択し、
POSTを選択します。
そうすると、Integrationを何にするか選択する画面が出てくるので、Lambdaを選択し、リージョンとLambda function名を入れます。入力を始めるとサジェストしてくれます。ap-northeast-1と前回作ったpost-slack-generalを選びます。
[Save]を押すと、API GatewayにLambdaの呼び出しを許可するかと求められるので[OK]にします。
Client->Request->Integration->Responseのフローを表す、左右に縦長長方形、間に2x2 4つのマス目が表示されます。HTTPのリクエストをLambdaに渡す時の設定を行います。[Integration Request]を選択します。
下部のBody Mapping Templatesを開きます。Request body passthroughは、Neverにしておきます。これは定義したContent-Type以外は、HTTP status code 415でfailさせる扱いです。*1
今回は、JSONをPOSTしてくるので、+Add mapping templateを選択し、
application/jsonを入力してチェックマークを選択します。(例として表示されてますが入力が必要です)
application/jsonを選択すると、下部に入力欄が出てでくるので、以下を入力して[save]します。
{ "text": $input.json('$.message') }
POSTされてきたJSONのmessage
というkeyの値を、text
というkeyの値として置き換えるということをやっています。{"message":"hello"}
を{"text":"hello"}
にしています。
Mappingが何に役立つかというと、Lambdaはtext
で受け付けるように作ったけど、key名がいけてないなーと思っても、Lambdaには手を入れたくない(入れられない)という時に、WebAPIではmessage
で受け取って、Lambdaに渡す時に変換できるということです。*2
とりあえずこれで動くので、API GatewayのTest機能を使って動かしてみます。 上部の<- Method Executionで、マス目の並ぶ画面に戻ります。
テスト実行する
左の[Test]雷マークみたいなのを選ぶと、テスト実行の画面になります。
Request Bodyに{"message":"POST from API Gateway + Lambda"}
を入れ*3、
[Test]を実行すると、横にレスポンス *4 やログが出てきます。
特に問題なければ、Slackにメッセージが出てきます。動かない時はログ見てください。
これでとりあえずWebAPIとしての動作はOKです。あとはデプロイすれば、実際に世界中から使えるようになります。
次回、API keyを使ってアクセスを制限して、デプロイして使えるようにします。