2
votes

I have a AWS SAM template that I'm trying to test locally and then deploy. The local test runs (sam local start-api) but the payload is not validated. This means that I have a RequestValidator in place, but it does not validate a thing.

Then, I try to deploy the YAML file to AWS to test there, and I get an error that reads:

"Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [BoilerPlateFunction] is invalid. Event with id [ApiEvent] is invalid. RestApiId property of Api event must reference a valid resource in the same template."

This is my yaml file, so first I want to be able to make the RequestValidator work in my local and once that is done, to know what I'm doing wrong and why I can't deploy:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

Globals:
  Function:
    Timeout: 20
Parameters:
  operationName:
    Type: String
    Default: testoperationName
  restApiName:
    Type: String
    Default: testrestApiName
  validatorName:
    Type: String
    Default: testvalidatorName
  validateRequestBody:
    Type: String
    Default: testvalidateRequestBody
  validateRequestParameters:
    Type: String
    Default: true
Resources:
  BoilerPlateApi:
    Type: AWS::ApiGateway::Api
    Properties:
      Name: !Ref restApiName
  BoilerPlateFunctionMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: ANY
      RestApiId: !Ref BoilerPlateApi
      RequestValidatorId: !Ref RequestValidator
      RequestParameters:
        method.request.querystring.test: true
  RequestValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: !Ref validatorName
      RestApiId: !Ref BoilerPlateApi
      ValidateRequestParameters: !Ref validateRequestParameters
  BoilerPlateFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: boilerplate/apiName
      Handler: index.handler
      Runtime: nodejs8.10
      Events:
        ApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref BoilerPlateApi
            Path: /hello
            Method: GET

So again, that runs using sam local start-api, I can hit the endpoint and the Lambda is executed. But I expect the API gateway to throw an error if I don't include the "test" parameter in the query string, but it does not, it let it go through.

Thanks guys!

1

1 Answers

0
votes

The function has been created before the API Gateway. You can use DependsOn parameter to create the API before the method

So, just change the following in the BoilerPlateFunction resource to:

  BoilerPlateFunction:
    DependsOn:
      - BoilerPlateApi
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: boilerplate/apiName
      Handler: index.handler
      Runtime: nodejs8.10
      Events:
        ApiEvent:
          Type: Api
          Properties:
            RestApiId: !Ref BoilerPlateApi
            Path: /hello
            Method: GET