更新したリソースがステージにデプロイされない問題
Serverless Framework でAPI GatewayのREST API をデプロイすると、リソースは更新されるが、ステージへのデプロイは自動で行われない。リソースに更新が入るたびに手動で行うのは不便がすぎるので、少し手を加えて自動でできるようにしたい。
※ 初回デプロイ時は自動でステージにリソースが反映される。更新時はされない。
解決方法
serverless-plugin-scripts というServerless Frameworkのプラグインを利用する。
下記の機能がある。
- カスタムコマンドの作成
- deployなどServerless Frameworkのイベントに紐づけて、コマンドを実行
今回は2つ目の機能を使って、deployに終了後に、AWS CLI でAPI Gatewayのリソースをデプロイする。
1. serverless-plugin-scripts をインストール
下記コマンドを実行
npm install --save serverless-plugin-scripts
2. deployに紐付けるスクリプトを用意
対象のAPI IDとデプロイ先のstageを引数として渡し、create-deployment
を実行するコマンドを用意。
# !/bin/bash
# 引数の確認
if [ $# -ne 2 ]; then
echo "Usage: $1 <STAGE>"
echo "Usage: $2 <REST_API_ID>"
exit 1
fi
STAGE=$1
REST_API_ID=$2
echo "Deploying to AWS API Gateway..."
# AWS CLIを使用してAPI Gatewayにデプロイ
aws apigateway create-deployment \
--rest-api-id $REST_API_ID \
--stage-name $STAGE \
echo "Deployment finished."
3. serverless.yml を編集
custom に下記のような記述を追加。
hooksを使うとServerless Frameworkのイベントにコマンドを紐づけることができる。
どのようなイベントがあるのかは下記をリンクを参照
https://gist.github.com/HyperBrain/50d38027a8f57778d5b0f135d80ea406
scripts:
hooks:
'<紐付けるイベント>': <紐付けるコマンド>
service: apigw-sample
frameworkVersion: '3'
plugins:
- serverless-plugin-scripts # プラグインを追加
custom:
defaultStage: dev
scripts:
hooks: # deploy に紐付けるため、hooksを使用
# deploy終了時に引数を設定し、ステージへのデプロイを実行
'deploy:finalize': bash deploy_api.sh ${self:provider.stage} ${cf:apigw-sample-dev.restApiId}
provider:
name: aws
runtime: python3.9
stage: ${opt:stage, self:custom.defaultStage}
region: ap-northeast-1
package:
patterns:
- '!**/**'
- resources/**
resources:
- ${file(./resources/apigateway.yml)}
補足
${cf:apigw-sample-dev.restApiId}
はCloudFormation テンプレートのOutputsをserverless.ymlから参照する時に用いる記法。詳しくは下記の記事を参照
実行
実行前のリソースが↓
ルートのメソッドをGET /
→ PUT /
に変更する。
テンプレートの該当箇所を変更。
ApiGatewayMethodRootGet:
Type: AWS::ApiGateway::Method
Properties:
RestApiId: !Ref ApiGatewayRestApi
ResourceId: !GetAtt ApiGatewayRestApi.RootResourceId
HttpMethod: PUT # ←ここを変更
AuthorizationType: NONE
Integration:
Type: HTTP
IntegrationHttpMethod: PUT
Uri: !Sub 'https://${ApiGatewayRestApi}.execute-api.${AWS::Region}.amazonaws.com/'
sls deploy
を実行。
Deploying to AWS API Gateway...
と表示されているので、deployコマンドに紐づいてスクリプトも実行されている。
$ sls deploy
Deploying apigw-sample to stage dev (ap-northeast-1)
Deploying to AWS API Gateway...
{
"id": "8vlyj4",
"createdDate": "2023-06-01T19:54:56+09:00"
}
Deployment finished.
✔ Service deployed to stack apigw-sample-dev (27s)
Need a faster logging experience than CloudWatch? Try our Dev Mode in Console: run "serverless dev"
ステージを確認すると、ちゃんと更新できている。
参考文献