方針
- 参考にさせて頂いた記事によると、1ソース(1つのtemplate.ymlなど)から複数環境にdeployしたい場合次の通りとしたほうが良いと判断
- 環境ごとのAPI Gateway
- 環境ごとのLambda Application & Function
- (初めは1つのAPI Gatewayで複数ステージを作れば良いと思ってたがSAMがそのやり方に対応していないらしい)
参考
AWS SAMにおける環境管理のベストプラクティス | 株式会社CyberOwl
作業後のイメージ
- devとprodの2つの環境でdeployする想定
API Gateway
- dev-XXXとprod-XXXの2つが作成される
ステージ
- devの場合、ステージ名を”dev”とする
- prodの場合も同様にステージ名は”prod”となる
Lambda
- dev-XXXとprod-XXXの2つが作成される
やったこと
環境を定義するパラメータを作成
- 今回は
ENV
というパラメータに設定された値によって環境ごとのdeployを実現する
受け取り側
- deploy時に
-config-env
をつけない場合はデフォルトで”dev”を入れている- production環境にdeployするには明示的に環境を指定するオペレーションとするため
Parameters:
ENV:
Type: String
Default: dev
定義側
- deploy時に
-config-env prod
とすることで ENVパラメータに”prod”が設定される
[prod.deploy.parameters]
parameter_overrides = "ENV=\"prod\""
API Gatewayを(明示的に)定義
- 環境によって明示的に「API Gatewayの名前」を変更するため
- ついでにステージ名も変えておく
- 元々AWS::Serverless::Apiが未定義だったため、API Gatewayは自動作成されていた
Resources:
++ RestApi:
++ Type: AWS::Serverless::Api
++ Properties:
++ Name: !Sub ${ENV}-sample-api-gateway
++ StageName: !Ref ENV
各LambdaFunctionを定義したAPI Gatewayに紐付け
ExampleFunction:
Type: AWS::Serverless::Function
Properties:
Events:
Api:
Properties:
++ RestApiId: !Ref RestApi
- (不要なプロパティは省略して記載している
(おまけ)API Gateway IDの出力用の表現を変更
- ${ServerlessRestApi} ⇒ ${RestApi}
-
ServerlessRestApi
はAPI Gatewayが自動で作成される場合のリソース名なので上記で定義したRestApi
(任意に設定可) に変更している
-
- endpoint末尾の “Prod” ⇒ ${ENV}
- endpoint末尾はステージ名が適用されるため
Outputs:
WebEndpoint:
Description: "API Gateway endpoint URL for Prod stage"
Value: !Sub "https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/${ENV}/"
# Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
動作確認
- エンドポイントの一部は修正している
- devとprodそれぞれのエンドポイントが叩けていて、想定通りの値が返ってくることを確認できればOK!
$ curl https://xxxxxxxxx.execute-api.region-name.amazonaws.com/dev/
{"message":"Hello world!"}%
$ curl https://yyyyyyyyy.execute-api.region-name-1.amazonaws.com/prod/
{"message":"Hello world!"}%