概要
SAM形式でAPIKeyを発行しようとした時にハマったので、備忘録として残します
結論
DependOnで以下の設定が必要
<APIの論理ID>Stage
対象者
- CloudFormationでテンプレートがかける
- SAM形式で書いてみたい
- APIKeyを発行したい
失敗するテンプレート
デプロイに失敗するAPIKeyのテンプレートを載せます
※他に色々と定義が必要なリソースはありますが、割愛
ApiKey:
Type: AWS::ApiGateway::ApiKey
DependsOn:
- ApiGateway
Properties:
Enabled: true
Name: !Sub ${ApplicationName}-API-Key-${EnvNameLower}
StageKeys:
- RestApiId: !Ref ApiGateway
StageName: !Ref EnvNameLower
ApiUsagePlan:
Type: AWS::ApiGateway::UsagePlan
DependsOn:
- ApiKey
Properties:
UsagePlanName: !Sub ${ApplicationName}-API-Usage-Plan-${EnvNameLower}
ApiStages:
- ApiId: !Ref ApiGateway
Stage: !Ref EnvNameLower
Throttle:
BurstLimit: 100 #TODO: 正式に決定する必要あり
RateLimit: 50 #TODO: 正式に決定する必要あり
上記のテンプレートを実行すると以下のようなエラーがでます
Resource handler returned message: "Invalid stage identifier specified (Service: ApiGateway, Status Code: 404, Request ID....
stageが定義されてないよ! 的な内容で怒られます
そもそもstageなんて定義していないよ
自分の書いたテンプレートを見てもstageなんてリソースは書いていません。
では、なぜ発生するのか?
きちんと解析はできていませんが、SAMでは定義していなくもStageリソースが作られているような感じです
時系列にまとめると
- APIGatewayのリソース作成が始まる
- Stageリソースが背後で始まる
- APIKeyリソースの作成が始まる
- Stageリソースが完成していないので、APIKeyのリソース作成で失敗する
問題を解決するテンプレート
割愛した部分も含めて今回の問題を解決するテンプレートです
ApiGateway:
Type: AWS::Serverless::Api
Properties:
Name: !Sub ${ApplicationName}-${EnvNameLower}
Description: API
StageName: !Ref EnvNameLower
ApiKeySourceType: HEADER
Auth:
ApiKeyRequired: true
ApiKey:
Type: AWS::ApiGateway::ApiKey
DependsOn:
- ApiGateway
- ApiGatewayStage # これを追加
Properties:
Enabled: true
Name: !Sub ${ApplicationName}-API-Key-${EnvNameLower}
StageKeys:
- RestApiId: !Ref ApiGateway
StageName: !Ref EnvNameLower
ApiUsagePlan:
Type: AWS::ApiGateway::UsagePlan
DependsOn:
- ApiKey
- ApiGatewayStage # これを追加
Properties:
UsagePlanName: !Sub ${ApplicationName}-API-Usage-Plan-${EnvNameLower}
ApiStages:
- ApiId: !Ref ApiGateway
Stage: !Ref EnvNameLower
Throttle:
BurstLimit: 100
RateLimit: 50
ApiUsagePlanKey:
Type: AWS::ApiGateway::UsagePlanKey
DependsOn:
- ApiUsagePlan
Properties:
KeyId: !Ref ApiKey
KeyType: API_KEY
UsagePlanId: !Ref ApiUsagePlan
まとめ
SAMを使うと記載量が減るなどのメリットはありますが、その分リソース全体の繋がりが見えづらくなるなどの功罪もありますね