AWS SAM を使用して、API Gateway のステージを環境ごとに分けてデプロイしたい

0

問題点

Dev ステージが期待通りに作成されず、毎回 Prod やStage ステージが自動的に作成されてしまう。

やりたいこと

AWS SAM を使用して、API Gateway のステージとLamda関数をProd、Dev環境ごとに分けてデプロイする設定をしたい。

具体的には、template.yaml でパラメータとして Stage を定義し、デプロイ時に Dev ステージを指定して、そのステージが正しくデプロイしたい。

これまで試したこと

template.yaml の設定

Parameters:
  Stage:
    Type: String
    Default: "dev"

Resources:
  ServerlessRestApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref Stage  # Stageパラメータを適用
      Name: !Sub "${Stage}-Api"  # API Gatewayの名前を設定
  
  GenerateCsrfTokenFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/generateCsrfToken.handler
      Runtime: nodejs18.x
      Events:
        ApiGenerateCsrfToken:
          Type: Api
          Properties:
            Path: /csrf-token
            Method: get
            RestApiId: !Ref ServerlessRestApi # stageを接頭辞に着ける

Outputs:
  CsrfTokenApiUrl:
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/${Stage}/csrf-token" # stageを動的に変更

Stage パラメータを Default: "dev" として定義し、ServerlessRestApi の StageName に !Ref Stage を設定。 API Gateway の Name にも !Sub "${Stage}-Api" を使用し、動的にステージ名を適用しようとした。 Outputs セクションでは、URL に ${Stage} を適用して、各環境ごとに異なるURLが生成されることを期待。

sam deploy コマンド

sam deploy --profile ****-**** parameter_overrides = Stage=dev --stack-name dev_stack_name --s3-bucket 
dev-deploy-bucket --capabilities CAPABILITY_IAM

samconfig.toml の設定

[development.deploy.parameters]
stack_name = "dev_stack_name "
resolve_s3 = true
s3_prefix = "dev_stack_name"
region = "ap-northeast-1"
profile = "****-****"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
disable_rollback = true
parameter_overrides = "Stage=\"dev\""
image_repositories = []

デプロイ結果

CloudFormation:

スタックの詳細、パラメータータブ内にStage パラメータがキーと値として反映されている事を確認できる

API gatway:

  1. Stage パラメータ付のAPIが作成される
  2. 期待する Dev ステージが作成されず、 prod と stage のステージがエンドポイント共に自動的に作成される問題が発生。
  3. prod と stage のステージのエンドポイントではLamda関数のレスポンスがある

Lamda関数:

  1. Stage パラメータ付のアプリケーションが作成される
  2. Stage パラメータ付の関数がデプロイされている
hnksh1
質問済み 1ヶ月前105ビュー
2回答
0

以下のissueにあるようにAWS SAMのバグのようです。
「OpenApiVersion: 3.0.2」をAWS::Serverless::Apiで指定すればStageは作成されなくなります。
https://github.com/aws/serverless-application-model/issues/191

以下のドキュメントにも記載されていました。
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-api.html#sam-api-openapiversion

AWS SAM は、Stageデフォルトで というステージを作成します。このプロパティに有効な値を設定すると、ステージ Stage が作成されなくなります。

私の環境で試してみましたが確かに作成されなくなることを確認しました。
ただし、StageNameはdevにならずProdになるためどこかしらがおかしいような気がしています。
代替案にはなるのですが、以下のように環境ごとにsamconfig.tomlを分割してAPI Gatewayを分けてみるのはいかがでしょうか?

version=0.1

[development.deploy.parameters]
stack_name = "dev-api-stack"
resolve_s3 = true
s3_prefix = "dev-api-stack"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
disable_rollback = true
parameter_overrides = [
    "Stage=dev"
]
image_repositories = []

[production.deploy.parameters]
stack_name = "prod-api-stack"
resolve_s3 = true
s3_prefix = "prod-api-stack"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"
disable_rollback = true
parameter_overrides = [
    "Stage=prod"
]
image_repositories = []

LambdaはjavascriptではなくPythonですが、基本的には同じような動きになるはずです。
コードなどは以下のブログを参考にしました。
https://qiita.com/fkooo/items/e08cdea0f73f60dabd3d

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Globals:
  Api:
    OpenApiVersion: 3.0.2

Parameters:
  Stage:
    Type: String
    Default: dev

Resources:
  ServerlessRestApi:
    Type: AWS::Serverless::Api
    Properties:
      OpenApiVersion: 3.0.2
      StageName: !Ref Stage
      Name: !Sub "${Stage}-Api"

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
            RestApiId: !Ref ServerlessRestApi

Outputs:
  CsrfTokenApiUrl:
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/${Stage}/hello"

デプロイはCloudShellで行いました。

sam build
sam deploy --config-env development
profile picture
エキスパート
回答済み 1ヶ月前
0

ご回答有難うございます! 再現いただき事象の確認と、参考情報ありがとうございます

私の記法や知識不足が原因と考え、バグの線はまったく考慮しておらなかったので解決の糸口となりました。 後程試してみます

hnksh1
回答済み 1ヶ月前

ログインしていません。 ログイン 回答を投稿する。

優れた回答とは、質問に明確に答え、建設的なフィードバックを提供し、質問者の専門分野におけるスキルの向上を促すものです。

質問に答えるためのガイドライン

関連するコンテンツ