Help us understand the problem. What is going on with this article?

AWS SAMでAPIキーと使用量プランのリソース作成に失敗する場合の対処方法

More than 1 year has passed since last update.

エラーの内容

AWS SAM で AWS::Serverless::Api リソースと AWS::ApiGateway::ApiKey および AWS::ApiGateway::UsagePlan
リソースを同じテンプレート内で指定し、デプロイすると以下のエラーで作成に失敗しました。
以下はCloudFormationのコンソールに出力されるエラーメッセージです。

Invalid stage identifier specified              # API キーの CREATE_FAILED
API Stage not found: <APIの物理ID>:<ステージ名>   # 使用量プランの CREATE_FAILED

原因としては、AWS::Serverless::Api リソースで APIステージのデプロイが行われる前に
AWS::ApiGateway::ApiKey および AWS::ApiGateway::UsagePlan リソースによる使用量プランの
作成がはじまってしまい、ステージの指定に問題があるというエラーになっているようです。

どう対処したか

ワークアラウンドとして、DependsOn プロパティに デプロイメントステージの論理IPを追記したところ
CloudFormation のデプロイが正常終了しました。
この論理IDは テンプレート内で明示的に作成していませんが、AWS::Serverless::Api リソースによって
作成されるため、

  • <APIの論理ID>Stage

という形式で指定します。

エラーがでるテンプレート例

CFn_sample_NG.yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Sample API

Parameters:
  EnvType:
    Description: Type of API Gateway stage.
    Default: dev
    Type: String
    AllowedValues:
      - dev
      - stg
      - prd
    ConstraintDescription: must specify dev or stg or prd.

  ProjectName:
    Description: Project name.
    Default: samplepj
    Type: String
    MinLength: "3"
    MaxLength: "10"
    AllowedPattern: "[a-zA-Z0-9]*"
    ConstraintDescription: must specify Project name.

Resources:
# Create API Gateway from swagger
  Api:
    Type: AWS::Serverless::Api
    Properties:
      DefinitionUri: ./templates/swagger-apigateway.yaml
      StageName: !Ref EnvType

# Create API Key
  ApiKey:
    Type: AWS::ApiGateway::ApiKey
    DependsOn: 
      - Api
    Properties:
      Enabled: "true"
      StageKeys:
        - RestApiId: !Ref Api
          StageName: !Ref EnvType
      Name: !Join
        - '-'
        - - !Ref EnvType
          - !Ref ProjectName
          - 'apikey'

# Create API Usage Plan
  ApiUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn: 
      - Api
    Properties:
      ApiStages:
        - ApiId: !Ref Api
          Stage: !Ref EnvType
      UsagePlanName: !Join
        - '-'
        - - !Ref EnvType
          - !Ref ProjectName
          - 'usageplan'

# Link API Key and Usage Plan
  ApiUsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    DependsOn:
      - ApiKey
      - ApiUsagePlan
    Properties : 
      KeyId: !Ref ApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref ApiUsagePlan

上記のテンプレートを package 後、deploy すると ApiUsagePlan と ApiKey の作成に失敗します。

image.png

正常終了するテンプレート例

CFn_sample_OK.yaml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Sample API

Parameters:
  EnvType:
    Description: Type of API Gateway stage.
    Default: dev
    Type: String
    AllowedValues:
      - dev
      - stg
      - prd
    ConstraintDescription: must specify dev or stg or prd.

  ProjectName:
    Description: Project name.
    Default: samplepj
    Type: String
    MinLength: "3"
    MaxLength: "10"
    AllowedPattern: "[a-zA-Z0-9]*"
    ConstraintDescription: must specify Project name.

Resources:
# Create API Gateway from swagger
  Api:
    Type: AWS::Serverless::Api
    Properties:
      DefinitionUri: ./templates/swagger-apigateway.yaml
      StageName: !Ref EnvType

# Create API Key
  ApiKey:
    Type: AWS::ApiGateway::ApiKey
    DependsOn: 
      - Api
      - ApiStage # ★追記
    Properties:
      Enabled: "true"
      StageKeys:
        - RestApiId: !Ref Api
          StageName: !Ref EnvType
      Name: !Join
        - '-'
        - - !Ref EnvType
          - !Ref ProjectName
          - 'apikey'

# Create API Usage Plan
  ApiUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn: 
      - Api
      - ApiStage # ★追記
    Properties:
      ApiStages:
        - ApiId: !Ref Api
          Stage: !Ref EnvType
      UsagePlanName: !Join
        - '-'
        - - !Ref EnvType
          - !Ref ProjectName
          - 'usageplan'

# Link API Key and Usage Plan
  ApiUsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    DependsOn:
      - ApiKey
      - ApiUsagePlan
    Properties : 
      KeyId: !Ref ApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref ApiUsagePlan

ApiUsagePlan と ApiKey の DependsOn プロパティに <APIの論理ID>Stage を追記します。
今回 API の論理ID をそのまま Api としているので、ステージの論理IDは ApiStage です。
ステージのデプロイメントが先に行われ、使用量プランとAPIキーの作成にも成功しました。

image.png

補足

AWS SAM 1.4.0 の リリースノート によれば 以下のように Refなどの組み込み関数でAPI Gateway Stage
とAPI Gateway Deployment の論理IDを取得できます。

!Ref MyApi.Stage #SAMによって生成されたステージを参照
!Ref MyApi.Deployment #SAMによって生成されたデプロイメントリソースを参照

しかし DepedsOn プロパティは文字列のみ指定可能であるため、今回の対応では直接記述しました。
特にデプロイメントリソースについては、API のデプロイ毎に論理IDが変化するので組み込み関数による
参照は重要ですね。

以上です。
参考になれば幸いです。

hayao_k
インフラ大好きです。2019 & 2020 APN AWS Top Engineers に選出いただきました。 掲載内容は個人の見解であり、所属する企業を代表するものではありません。
saison_information_systems
モード1(守りのIT)・モード2(攻めのIT)を兼ね備えたバイモーダル・インテグレーターとしてデータ連携プラットフォームのHULFTシリーズ, リンケージサービス, 流通ITサービス, フィナンシャルITサービスを提供します。
https://home.saison.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした