App Engineerの開発ノート

AWS、Flutterや開発活動に役立つツール作りなど

PowershellでLambda+API Gatewayのコンボを高速配置

f:id:Simoroid:20211202005541p:plain
AWSのサーバレスコンピューティングの定番であるLambda と API Gatewayのセットを簡単に配置する手順です。

AWSの継続的な配置(CD)の観点として、デプロイは「AWS CodeDeploy」等のサービスを使用することが恒久的なやり方だと思いますが、ちょっと試したい、個人の軽いアプリ開発をやりたいといった場合に便利かと思い、PowerShellを利用し、ツールを作成しました。※AWS CLIを使用します。
また、今回はlocalstackを使用し、ローカルにAPIを配置していきます。

■環境情報
※バージョンが異なると動作が上手くいかないことがあります。

対象 バージョン 調べ方や導入方法
AWS CLI 1.20.11 aws --version
Powershell(PSVersion) 1.20.11 $PSVersionTable
localstack - AWSをローカルで動かすやつです。導入はこちらで出来ます。
モジュール 1.20.11 任意のLambdaアプリをjarやzip形式で準備しておく必要があります。「AWS Toolkit for JetBrains」を導入したIntellijを使用して、File -> new -> AWS Serverless Application でサンプルアプリのプロジェクトを作るのが簡単です。インストールはこちらが参考になるかと思います。

■ツール概要

■ツール作成
下記のソースをコピーして任意のps1ファイルを作成します。※例:「deploy-agpig-lambda.ps1」
各コマンドへのパラメータの調整は好みでやりましょう(メソッドの種類やアクセス制限など)。

#####################
# 定数定義 - 環境に応じて変更する必要あり
#####################

# API名
$ApiName = 'MyAPI'

# パス名
$PathName = 'hello'

# Javaバージョン情報
$RuntimeVersion = 'java11'

# Lambdaの関数名
$FunctionName = 'mylambda'

# LambdaのHandler名
$HandlerName = 'helloworld.App::handleRequest'

# Lambdaをビルドして固めたもの
$ZipFilePath = "fileb://C:\aws\SAM\HelloWorldFunction\build\distributions\HelloWorldFunction.zip"

# リージョン名、ローカルに配置するときとかは何でもいい
$RegionName = 'us-west-2'

#####################
# 処理開始
#####################

# API Gateway用のREST APIのセットアップ
echo "create-rest-api"
$rest = aws apigateway create-rest-api --name $ApiName --endpoint-url=http://localhost:4566
$restJson = ($rest | ConvertFrom-Json)

$resource = aws apigateway get-resources --rest-api-id $restJson.id --endpoint-url=http://localhost:4566
$resourceJson = ($resource | ConvertFrom-Json)

# API Gateway用のリソースの識別子(セットアップしたAPIを識別するためのカギ)を取得
# https://docs.microsoft.com/ja-jp/azure/architecture/best-practices/api-design
echo "create-resource"
$methodResource = aws apigateway create-resource --rest-api-id $restJson.id `
--parent-id $resourceJson.items.id --path-part $PathName `
--endpoint-url=http://localhost:4566
$methodResourceJson = ($methodResource | ConvertFrom-Json)

# リソース(前段で作成したAPI)に対して、httpメソッドを割り当てる
# "authorization-type"にNONEにしていると誰でもアクセス出来る状態です、あるユーザーのみのアクセスにしたい場合は下記参照
# https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-control-access-to-api.html
echo "put-method"
aws apigateway put-method `
 --rest-api-id $restJson.id `
 --resource-id $methodResourceJson.id `
 --http-method POST `
 --authorization-type "NONE" `
 --request-parameters method.request.Content-Type=False,method.request.Accept=False `
 --endpoint-url=http://localhost:4566

# Lambda関数の作成準備、既に作成していたら消す
aws lambda delete-function --endpoint-url=http://localhost:4566 `
 --function-name="$FunctionName"

# Lambda関数の作成
# https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/API_CreateFunction.html
echo "create-function"
$myfunction = aws lambda create-function --endpoint-url=http://localhost:4566 `
 --function-name="$FunctionName" --runtime=$RuntimeVersion --handler=$HandlerName `
 --zip-file=$ZipFilePath --role="arn:aws:iam::12345:role/ignoreme"
$myfunctionJson = ($myfunction | ConvertFrom-Json)
echo $myfunctionJson

# Lambda関数とAPI Gatewayを統合
echo "put-integration"
aws apigateway put-integration `
 --passthrough-behavior WHEN_NO_TEMPLATES `
 --rest-api-id $restJson.id `
 --resource-id $methodResourceJson.id `
 --http-method POST `
 --type AWS_PROXY `
 --integration-http-method POST `
 --uri ("arn:aws:apigateway:" + $RegionName + ":lambda:path/2015-03-31/functions/" + $myfunctionJson.FunctionArn + "/invocations") `
 --passthrough-behavior WHEN_NO_TEMPLATES `
 --endpoint-url=http://localhost:4566
echo ("arn:aws:apigateway:" + $RegionName + ":lambda:path/2015-03-31/functions/" + $myfunctionJson.FunctionArn + "/invocations")
echo $methodResourceJson.id
echo $restJson.id

# REST APIをデプロイ
echo "create-deployment"
aws apigateway create-deployment `
--rest-api-id $restJson.id `
--stage-name test `
--endpoint-url=http://localhost:4566

echo ("curl http://localhost:4566/restapis/" + $restJson.id + "/test/_user_request_/" + $PathName + " -Method POST -Body '{""id"":""001""}' ")
pause

■ツール実行
準備ができたら、配置したps1ファイルを右クリック -> "Powershellで実行"をクリック
⇒コンソールにエラーメッセージが表示されていなければ成功です、最下部にAPIのURLが出力されます。※リクエストパラメータとかはとりあえず適当です。
f:id:Simoroid:20211202002111p:plain

■確認(リクエストを実行)

curl http://localhost:4566/restapis/carajuiooa/test/_user_request_/hello -Method POST -Body '{"id":"001"}'

f:id:Simoroid:20211202003734p:plain
POSTに成功しました、これでLambda+API GatewayAPIがお手軽に配置できました。

ここまで 読んで頂きありがとうございました。
よければフォローお願いします!