3
votes

I'm able to define and deploy my API Gateway + Lambda stack using Cloudformation / Serverless Application Model, an want to add a model to my API.

I've created the model in YAML, but it appears to be unable to reference the API defined in the Outputs section of my file.

The error I see is

Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED.

Reason: Template format error: Unresolved resource dependencies [MyApi] in the Resources block of the template

Is it possible to reference the Output object, or is it not considered a Resource in this context? i.e. do I need to explicitly define an AWS::Serverless::Api instead of using the Output?

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  PutItemFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: put_item
      Handler: handlers.put_item
      Runtime: python3.6
      Events:
        PutResource:
          Type: Api
          Properties:
            Path: /
            Method: put    
  ModelResource:
    Type: AWS::ApiGateway::Model
    Properties:
      RestApiId:
        Ref: MyApi
      ContentType: "application/json"
      Name: MyModel
      Schema:
        "$schema": "http://json-schema.org/draft-04/schema#"
        type: object
        properties:
          id:
            type: string    
Outputs:
  MyApi:
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/s/"
1

1 Answers

1
votes

First of all, the "outputs" section of the template is for displaying the information after the template has been executed. You can't get a reference to anything in that section while resources are being created.

The documentation for the Api type of the Events property in a serverless function is at: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-api.html

There's a property called RequestModel which could be added below your Path and Method properties to reference your ModelResource model. So your events section might look like:

      Events:
        PutResource:
          Type: Api
          Properties:
            Path: /
            Method: put  
            RequestModel: MyModel  

... and take out the RestApiId property.

I haven't tested this, so I don't know if it'll work, but give it a shot. And, since I'm answering this 2 years after you asked the question, you've probably already figured it out.