AWSコマンドラインインターフェース(AWS CLI)でAPI Gateway+AWS Lambdaを構築してみる(その3)
下記の記事で紹介したAWS CLIでのAPI Gateway+AWS Lambdaの構築をJenkins等で実行できるようにbash化する。
jqの導入
jqはJSONの内容をsedやawkのようにフィルタ・加工するためのコマンド。
これを使ってAWS CLIのレスポンスのJSONから欲しい値をとる。
公式はここ。
インストール
yumでインストールできる。
yum -y install jq
使い方
JSONの例は以下を使う。
■person.json
{"name":"Taro","age":20,"brother":{"name":"Jiro","age":18}}
■people.json
{"people":[{"name":"Taro","age":20},{"name":"Jiro","age":18}]}
全部は紹介しない。
整形
jq .
$ cat person.json | jq . { "name": "Taro", "age": 20 }
値の取得
jq .[属性名]
$ cat person.json | jq .name "Taro"
$ cat person.json | jq .brother.name "Jiro"
値の取得(配列)
「[]
」をつけると配列の意味になる。
$ cat people.json | jq .people[].name "Taro" "Jiro"
ダブルクォートが邪魔
「-r」をつける。
$ cat people.json | jq -r .people[].name Taro Jiro
フィルタ(というかパイプ)
「jq "なにか | なにか"」の形。
jqの引数をダブルクォートでくくって、中をパイプで区切る。
$ cat people.json | jq -r ".people[] | .name" Taro Jiro
people配列だけを取得して、その配列からnameを抽出している。
結果からJSON作成
パイプの後ろをJSON形式にするだけ。
$ cat people.json | jq ".people[] | { personName: .name }" { "personName": "Taro" } { "personName": "Jiro" }
作成したbash
断っておくが、筆者は普段bashを書かない。
ロジックやエラーハンドリングはアホかもしれないが、とりあえずド正常なら動く。
てかほぼ前記事の手順を貼り付けただけw
#!/bin/bash export account_id="123456789012" # AWSアカウント export lambda_function_name="cliLambdaSample" # Lambda関数の名前 export role_exec_lambda="role_exec_lambda" # Lambdaを実行する権限を持つロール export lambda_handler="org.sample.handler.PersonHandler::getPerson" # ハンドラ export jar_path="LambdaSample-1.0-SNAPSHOT.jar" # Lambdaに登録するプログラム export rest_api_name="cliApiSample" # API Gatewayに作成するAPIの名前 # export rest_api_id # ロジックの途中で使う変数 # export rest_api_root_path_id # ロジックの途中で使う変数 export rest_api_path_name="cliPathSample" # APIに作成するパス export rest_api_method="GET" # API Gatewayに登録するHTTPメソッド export permission_statement_id="12345678901234567890123456789012" # パーミッションのステートメントID export deploy_stage_name="test" # API Gatewayをデプロイするステージ # export deploy_id # ロジックの途中で使う変数 function checkError() { result=$1 if [ $result -ne 0 ] ; then echo "Error occurred ! Exit code is ${result}." exit $result fi } aws lambda create-function \ --function-name ${lambda_function_name} \ --runtime java8 \ --role arn:aws:iam::${account_id}:role/${role_exec_lambda} \ --handler ${lambda_handler} \ --zip-file fileb://${jar_path} \ 1>/dev/null 2>/dev/null checkError $? export rest_api_id=(` \ aws apigateway create-rest-api \ --name ${rest_api_name} \ | jq -r .id \ `) checkError $? export rest_api_root_path_id=(` \ aws apigateway get-resources \ --rest-api-id ${rest_api_id} \ | jq -r .items[].id \ `) checkError $? export rest_api_path_id=(` \ aws apigateway create-resource \ --rest-api-id ${rest_api_id} \ --parent-id ${rest_api_root_path_id} \ --path-part ${rest_api_path_name} \ | jq -r .id `) checkError $? aws apigateway put-method \ --rest-api-id ${rest_api_id} \ --resource-id ${rest_api_path_id} \ --http-method ${rest_api_method} \ --authorization-type NONE \ 1>/dev/null 2>/dev/null checkError $? aws apigateway put-integration \ --rest-api-id ${rest_api_id} \ --resource-id ${rest_api_path_id} \ --http-method ${rest_api_method} \ --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:${lambda_function_name}/invocations \ 1>/dev/null 2>/dev/null checkError $? aws apigateway put-integration-response \ --rest-api-id ${rest_api_id} \ --resource-id ${rest_api_path_id} \ --http-method ${rest_api_method} \ --status-code 200 \ --response-templates '{"application/json":""}' \ 1>/dev/null 2>/dev/null checkError $? aws lambda add-permission \ --function-name ${lambda_function_name} \ --statement-id ${permission_statement_id} \ --action lambda:InvokeFunction \ --principal apigateway.amazonaws.com \ --source-arn arn:aws:execute-api:ap-northeast-1:${account_id}:${rest_api_id}/${deploy_stage_name}/${rest_api_method}/${rest_api_path_name} \ 1>/dev/null 2>/dev/null checkError $? aws apigateway put-method-response \ --rest-api-id ${rest_api_id} \ --resource-id ${rest_api_path_id} \ --http-method ${rest_api_method} \ --status-code 200 \ --response-models '{"application/json":"Empty"}' \ 1>/dev/null 2>/dev/null checkError $? aws apigateway test-invoke-method \ --rest-api-id ${rest_api_id} \ --resource-id ${rest_api_path_id} \ --http-method ${rest_api_method} \ --path-with-query-string "" \ 1>/dev/null 2>/dev/null checkError $? export deploy_id=(` \ aws apigateway create-deployment \ --rest-api-id ${rest_api_id} \ --stage-name ${deploy_stage_name} \ --stage-description "" \ --description "" \ | jq -r .id \ `) checkError $? echo "Process succeeded ! Following is URI." echo "https://${rest_api_id}.execute-api.ap-northeast-1.amazonaws.com/${deploy_stage_name}/${rest_api_path_name}"
AWS Lambdaのコードや設定を更新するだけのシェルは以下。
#!/bin/bash export account_id="123456789012" export lambda_function_name="cliLambdaSample" export role_exec_lambda="role_exec_lambda" export lambda_handler="org.sample.handler.PersonHandler::getPerson" export jar_path="LambdaSample-1.0-SNAPSHOT.jar" function checkError() { result=$1 if [ $result -ne 0 ] ; then echo "Error occurred ! Exit code is ${result}." exit $result fi } aws lambda update-function-code \ --function-name ${lambda_function_name} \ --zip-file fileb://${jar_path} \ 1>/dev/null 2>/dev/null checkError $? aws lambda update-function-configuration \ --function-name ${lambda_function_name} \ --role arn:aws:iam::${account_id}:role/${role_exec_lambda} \ --handler ${lambda_handler} \ 1>/dev/null 2>/dev/null checkError $? echo "Process succeeded !"
API GatewayのAPIとAWS Lambdaの関数を削除するだけのシェルは以下。
#!/bin/bash export rest_api_name="cliApiSample" # 削除するAPI GatewayのAPIの名前 export lambda_function_name="cliLambdaSample" # 削除するLambda関数の名前 export rest_api_id=$( \ aws apigateway get-rest-apis \ --output json \ | jq -r .items[] \ | jq -r "select(.name == \"`echo ${rest_api_name}`\")" \ | jq -r '.id' \ ) aws apigateway delete-rest-api --rest-api-id ${rest_api_id} aws lambda delete-function --function-name ${lambda_function_name}