AWSコマンドラインインターフェース(AWS CLI)でAPI Gateway+AWS Lambdaを構築してみる(その2)
下記の記事ではAPI GatewayをHTTPのGETメソッドで作成したが、この記事ではHTTPのPOSTメソッドで作成する。
API Gateway + AWS LambdaをAWS CLIで構築して、POSTメソッドでテストするところまで行う。
以下の順で行う。
- AWS Lambdaの作成
- API Gatewayの作成
- AWS LambdaとAPI Gatewayの連携設定
- 設定したAPI Gateway + AWS Lambdaのテスト
- APIのデプロイ
- APIの確認
以降の作成手順ではいろいろと流出するとマズいID周りは以下のようにマスクしています。
- AWSアカウントID
- [account-id]
- 実行ロール
- [exec-role-name]
- 作成したAPIのID(rest-api-id)
- [rest-api-id]
- 作成したAPIのルートパスのID
- [rest-api-root-path-id]
- APIに追加するパス(cliPathSample)のID
- [rest-api-cliPathSample-path-id]
- デプロイのID
- [deployment-id]
- その他
- xxx
1.AWS Lambdaの作成
AWS LambdaにLambda関数を作成する。
Lambda関数名は「cliLambdaSample」、ランタイムは「java8」で作成する。
実行のロールについてはあらかじめ作成しておいて、「aws iam list-roles」コマンドで表示されたものから選ぶ。
aws lambda create-function^ --function-name cliLambdaSample^ --runtime java8^ --role arn:aws:iam::[account-id]:role/[exec-role-name]^ --handler org.sample.handler.PersonHandler::postPerson^ --zip-file fileb://LambdaSample-1.0-SNAPSHOT.jar
{ "CodeSha256": "xxx", "FunctionName": "cliLambdaSample", "CodeSize": 506959, "MemorySize": 128, "FunctionArn": "arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample", "Version": "$LATEST", "Role": "arn:aws:iam::[account-id]:role/[exec-role-name]", "Timeout": 3, "LastModified": "2016-02-03T11:33:17.027+0000", "Handler": "org.sample.handler.PersonHandler::postPerson", "Runtime": "java8", "Description": "" }
作成したLambda関数の確認。
aws lambda get-function^ --function-name cliLambdaSample
{ "Code": { "RepositoryType": "S3", "Location": "https://awslambda-ap-ne-1-tasks.s3-ap-northeast-1.amazonaws.com/snapshots/[account-id]/cliLambdaSample-xxx" }, "Configuration": { "Version": "$LATEST", "CodeSha256": "xxx", "FunctionName": "cliLambdaSample", "MemorySize": 128, "CodeSize": 506959, "FunctionArn": "arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample", "Handler": "org.sample.handler.PersonHandler::postPerson", "Role": "arn:aws:iam::[account-id]:role/[exec-role-name]", "Timeout": 3, "LastModified": "2016-02-03T11:33:17.027+0000", "Runtime": "java8", "Description": "" } }
2.API Gatewayの作成
2.1.APIの作成
aws apigateway create-rest-api^
--name cliApiSample
{ "name": "cliApiSample", "id": "[rest-api-id]", "createdDate": 1454499448 }
作成したAPIの確認。
aws apigateway get-resources^ --rest-api-id [rest-api-id]
{ "items": [ { "path": "/", "id": "[rest-api-root-path-id]" } ] }
作成したAPIにはルートパスのリソースが作成されていることがわかる。
2.2.リソース(パス)の作成
作成したAPIに対してパスを追加する。
親(parent-id)はAPIのルートパスリソースを指定する。
aws apigateway create-resource^ --rest-api-id [rest-api-id]^ --parent-id [rest-api-root-path-id]^ --path-part cliPathSample
{ "path": "/cliPathSample", "pathPart": "cliPathSample", "id": "[rest-api-cliPathSample-path-id]", "parentId": "[rest-api-root-path-id]" }
作成したリソースを確認コマンド。
aws apigateway get-resource^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]
{ "path": "/cliPathSample", "pathPart": "cliPathSample", "id": "[rest-api-cliPathSample-path-id]", "parentId": "[rest-api-root-path-id]" }
2.3.APIのメソッドを作成
APIの「/cliPathSample」リソースに対してPOSTメソッドを作成する。
aws apigateway put-method^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST^ --authorization-type NONE
{ "apiKeyRequired": false, "httpMethod": "POST", "authorizationType": "NONE" }
作成したメソッドの確認。
aws apigateway get-method^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST
{ "apiKeyRequired": false, "httpMethod": "POST", "authorizationType": "NONE" }
3.AWS LambdaとAPI Gatewayの連携設定
3.1.APIのリソースとLambdaの関連付け
cliPathSampleリソースとLambda関数を作成したHTTPのPOSTメソッドで関連付ける。
ただし、API GatewayからAWS LambdaへはPOSTで連携することに注意。
また、uriは
「arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/[Lambda関数のARN]/invocations」
の形式で指定する。
「2015-03-31」という日付はおそらくAWS CLIに「aws lambda」コマンド実装されたリリース日(Release: AWS CLI 1.8.12)。
aws apigateway put-integration^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST^ --type AWS^ --integration-http-method POST^ --uri arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample/invocations
{ "httpMethod": "POST", "cacheKeyParameters": [], "type": "AWS", "uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample/invocations", "cacheNamespace": "[rest-api-cliPathSample-path-id]" }
作成した連携設定を確認。
aws apigateway get-integration^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST
{ "httpMethod": "POST", "cacheKeyParameters": [], "type": "AWS", "uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample/invocations", "cacheNamespace": "[rest-api-cliPathSample-path-id]" }
3.2.AWS LambdaからAPI Gatewayへのレスポンスを作成
POSTのHTTPレスポンスをステータス200のときはJSONで設定。
aws apigateway put-integration-response^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST^ --status-code 200^ --response-templates {\"application/json\":\"\"}
{ "statusCode": "200", "responseTemplates": { "application/json": null } }
作成したレスポンスを確認。
aws apigateway get-integration-response^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST^ --status-code 200
{ "statusCode": "200", "responseTemplates": { "application/json": null } }
1つ上のレイヤでも確認。
aws apigateway get-integration^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST
{ "httpMethod": "POST", "integrationResponses": { "200": { "responseTemplates": { "application/json": null }, "statusCode": "200" } }, "cacheKeyParameters": [], "type": "AWS", "uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample/invocations", "cacheNamespace": "[rest-api-cliPathSample-path-id]" }
3.3.API GatewayのメソッドにLambda関数の実行権限付与
cliPathSampleリソースのPOSTメソッドに対してLambda関数の実行権限を付与する。
statement-idは32桁で適当に作成。(ここでは、12345678901234567890123456789012)
source-arnは
「arn:aws:execute-api:ap-northeast-1:[account-id]:[rest-api-id]/[ステージ名]/[HTTPメソッド]/[リソース名]」
の形式。
aws lambda add-permission^ --function-name cliLambdaSample^ --statement-id 12345678901234567890123456789012^ --action lambda:InvokeFunction^ --principal apigateway.amazonaws.com^ --source-arn arn:aws:execute-api:ap-northeast-1:[account-id]:[rest-api-id]/test/POST/cliPathSample
{ "Statement": "{ \"Condition\":{ \"ArnLike\":{ \"AWS:SourceArn\":\"arn:aws:execute-api:ap-northeast-1:[account-id]:[rest-api-id]/*/POST/cliPathSample\" } }, \"Action\":[ \"lambda:InvokeFunction\" ], \"Resource\":\"arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample\", \"Effect\":\"Allow\", \"Principal\":{ \"Service\":\"apigateway.amazonaws.com\" }, \"Sid\":\"12345678901234567890123456789012\" }" }
設定した実行権限の確認。
aws lambda get-policy^
--function-name cliLambdaSample
{ "Policy": "{ \"Version\":\"2012-10-17\", \"Statement\":[ { \"Condition\":{ \"ArnLike\":{ \"AWS:SourceArn\":\"arn:aws:execute-api:ap-northeast-1:[account-id]:[rest-api-id]/*/POST/cliPathSample\" } }, \"Action\":\"lambda:InvokeFunction\", \"Resource\":\"arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample\", \"Effect\":\"Allow\", \"Principal\":{ \"Service\":\"apigateway.amazonaws.com\" }, \"Sid\":\"12345678901234567890123456789012\" } ], \"Id\":\"default\" }" }
3.4.API Gatewayのメソッドのレスポンスを作成
aws apigateway put-method-response^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST^ --status-code 200^ --response-models {\"application/json\":\"Empty\"}
{ "responseModels": { "application/json": "Empty" }, "statusCode": "200" }
作成したレスポンスの確認。
aws apigateway get-method^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST
{ "apiKeyRequired": false, "httpMethod": "POST", "methodIntegration": { "integrationResponses": { "200": { "responseTemplates": { "application/json": null }, "statusCode": "200" } }, "cacheKeyParameters": [], "uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample/invocations", "httpMethod": "POST", "cacheNamespace": "[rest-api-cliPathSample-path-id]", "type": "AWS" }, "methodResponses": { "200": { "responseModels": { "application/json": "Empty" }, "statusCode": "200" } }, "authorizationType": "NONE" }
4.設定したAPI Gateway + AWS Lambdaのテスト
aws apigateway test-invoke-method^ --rest-api-id [rest-api-id]^ --resource-id [rest-api-cliPathSample-path-id]^ --http-method POST^ --path-with-query-string ""^ --body {\"name\":\"Jiro\",\"age\":18}
{ "status": 200, "body": "{\"message\":\"Accepted the person post request.\"}", "log": "Execution log for request test-request\n Wed Feb 03 12:35:55 UTC 2016 : Starting execution for request: test-invoke-request\n Wed Feb 03 12:35:55 UTC 2016 : API Key: test-invoke-api-key\n Wed Feb 03 12:35:55 UTC 2016 : Method request path: {}\n Wed Feb 03 12:35:55 UTC 2016 : Method request query string: {}\n Wed Feb 03 12:35:55 UTC 2016 : Method request headers: {}\n Wed Feb 03 12:35:55 UTC 2016 : Method request body before transformations: {\"name\":\"Jiro\",\"age\":18}\n Wed Feb 03 12:35:55 UTC 2016 : Endpoint request URI: https://lambda.ap-northeast-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:[account-id]:function:cliLambdaSample/invocations\n Wed Feb 03 12:35:55 UTC 2016 : Endpoint request headers: {Authorization=xxx, X-Amz-Date=20160203T123555Z, X-Amz-Source-Arn=arn:aws:execute-api:ap-northeast-1:[account-id]:[rest-api-id]/null/POST/cliPathSample, Accept=application/json, User-Agent=AmazonAPIGateway_[rest-api-id], Host=lambda.ap-northeast-1.amazonaws.com, X-Amz-Content-Sha256=xxx, Content-Type=application/json}\n Wed Feb 03 12:35:55 UTC 2016 : Endpoint request body after transformations: {\"name\":\"Jiro\",\"age\":18}\n Wed Feb 03 12:35:57 UTC 2016 : Endpoint response body before transformations: {\"message\":\"Accepted the person post request.\"}\n Wed Feb 03 12:35:57 UTC 2016 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=xxx, Connection=keep-alive, Content-Length=47, Date=Wed, 03 Feb 2016 12:35:56GMT, Content-Type=application/json}\n Wed Feb 03 12:35:57 UTC 2016 : Method response body after transformations: {\"message\":\"Accepted the person post request.\"}\n Wed Feb 03 12:35:57 UTC 2016 : Method response headers: {Content-Type=application/json}\n Wed Feb 03 12:35:57 UTC 2016 : Successfully completed execution\n Wed Feb 03 12:35:57 UTC 2016 : Method completed with status: 200\n", "latency": 1517, "headers": { "Content-Type": "application/json" } }
5.APIのデプロイ
aws apigateway create-deployment^ --rest-api-id [rest-api-id]^ --stage-name test^ --stage-description ""^ --description ""
{ "id": "[deployment-id]", "createdDate": 1454501432 }
デプロイを確認。
ただし、下記のコマンドは1つのAPIに対してすべてのデプロイを表示する。
aws apigateway get-deployments^ --rest-api-id [rest-api-id]
{ "items": [ { "id": "[deployment-id]", "createdDate": 1454501432 } ] }
1つのデプロイを指定して内容を確認。
aws apigateway get-deployment^ --rest-api-id [rest-api-id]^ --deployment-id [deployment-id]
{ "id": "[deployment-id]", "createdDate": 1454501432 }
APIのステージ名を取得する。
ただし、下記のコマンドは1つのAPIに対してすべてのステージを表示する。
aws apigateway get-stages^ --rest-api-id [rest-api-id]
{ "item": [ { "stageName": "test", "cacheClusterEnabled": false, "cacheClusterStatus": "NOT_AVAILABLE", "deploymentId": "[deployment-id]", "lastUpdatedDate": 1454501432, "createdDate": 1454501432, "methodSettings": {} } ] }
1つのステージを指定して内容を確認。
aws apigateway get-stage^ --rest-api-id [rest-api-id]^ --stage-name test
{ "stageName": "test", "cacheClusterEnabled": false, "cacheClusterStatus": "NOT_AVAILABLE", "deploymentId": "[deployment-id]", "lastUpdatedDate": 1454501432, "createdDate": 1454501432, "methodSettings": {} }
6.APIの確認
https://[rest-api-id].execute-api.[リージョン名].amazonaws.com/[ステージ名][リソースのパス]
ここの例では、
https://[rest-api-id].execute-api.ap-northeast-1.amazonaws.com/test/cliPathSample
となる。