serverless-application-model icon indicating copy to clipboard operation
serverless-application-model copied to clipboard

AWS::Serverless::Api Property "RestApiId" does not support If, Map Functions

Open colinbjohnson opened this issue 4 years ago • 7 comments

Description:

The AWS::Serverless::Api does not support particular functions such as Fn::If and Fn::FindInMap. My use case is that particular AWS::Serverless::Function resources my SAM template may have events coming from different API Gateways depending on a parameter I pass in.

Steps to reproduce the issue:

Given the following template:

AWSTemplateFormatVersion: '2010-09-09'

Transform: AWS::Serverless-2016-10-31

Conditions:

  IsProd:
    Fn::Equals:
      - !Ref Environment
      - prod

Parameters:

    Environment:
      Type: String
      Default: prod
      AllowedValues: 
        - prod

Description: >
  sam-app

  Sample SAM Template for sam-app

Globals:
  Function:
    Timeout: 3

Resources:

  PublicAWSApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      Name: Public AWS Api Gateway
      StageName: Staging

  PrivateAWSApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      Name: Private AWS Api Gateway
      StageName: Staging

  HelloWorldFunctionPrivate:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
            RestApiId: !If [ IsProd, !Ref PublicAWSApiGateway, !Ref PrivateAWSApiGateway ]

Outputs: {}

Run the command:

sam validate --debug

Observed result:

The following result is returned:

Error: [InvalidResourceException('HelloWorldFunctionPrivate', 'Event with id [HelloWorld] is invalid. Api Event must reference an Api in the same template.'), InvalidResourceException('HelloWorldFunctionPublic', 'Event with id [HelloWorld] is invalid. Api Event must reference an Api in the same template.')] ('HelloWorldFunctionPrivate', 'Event with id [HelloWorld] is invalid. Api Event must reference an Api in the same template.') ('HelloWorldFunctionPublic', 'Event with id [HelloWorld] is invalid. Api Event must reference an Api in the same template.')

Expected result:

  1. Expected result is that the given AWS::Serverless::Function would be associated with the given API Gateway returned by the If or FindInMap function.

colinbjohnson avatar Feb 27 '20 01:02 colinbjohnson

Thanks for the feature request! We have passed this along to our product team for possible prioritization. Please +1 on the feature to help with prioritization.

ShreyaGangishetty avatar Feb 28 '20 19:02 ShreyaGangishetty

I was going crazy with this error until found this issue... Thanks for looking into it!

ayozemr avatar Aug 11 '20 16:08 ayozemr

I have the same issue. RestApiId property of Api event must reference a valid resource in the same template. Any update on this issue?

sandun-rezg avatar Sep 13 '20 13:09 sandun-rezg

I am unable to import an exported RestApi from a CFN template to a SAM template (which is CFN under the hood)

Stack A - excerpt

Outputs: SandboxApiOutput: Description: Description of value to be outputted Value: !Ref booksapiE1885304 Export: Name: "BookAPI-Reference-for-lambda-function"

Stack B - excerpt

MyLambda: Type: AWS::Serverless::Function Properties: FunctionName: I-DID-IT-MyLambda Handler: index.Handler # CodeUri: Events: MyLambda: Type: Api Properties: Path: /example Method: post RestApiId: Fn::ImportValue: "BookAPI-Reference-for-lambda-function"

Error Message -> [InvalidResourceException('MyLambda', 'Event with id [MyLambda] is invalid. Api Event must reference an Api in the same template.')] ('MyLambda', 'Event with id [MyLambda] is invalid. Api Event must reference an Api in the same template.')

si3mshady avatar Oct 28 '20 11:10 si3mshady

hi @si3mshady Have you figured it out on how to use a restAPI resource over cross templates?

Kanakala avatar Feb 10 '21 18:02 Kanakala

I could setup an api in yaml and reference it in my lambda using RestApiId as shown below:

  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Name: MyApi
      BinaryMediaTypes:
        - multipart/form-data
  SendFormEmail:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./send-form-email/send-form-email.zip
      FunctionName: send-form-email
      Handler: index.handler
      MemorySize: 128
      Timeout: 60
      Policies:
        - AmazonSESFullAccess
      Environment:
        Variables:
          SOURCE_EMAIL_ADDRESS: '{{resolve:ssm:EMAIL_NOTIFICATION_SOURCE:1}}'
      Events:
        Download:
          Type: Api
          Properties:
            Path: /api/sendForm
            Method: post
            RestApiId: !Ref MyApi

smohadjer avatar Oct 11 '21 07:10 smohadjer

you figured it out on how to use a restAPI resource over cross

Hi any new information about this problem? Is it available to use an api in cross template?

urko-b avatar Apr 07 '22 10:04 urko-b

You might be able to get this to work by adding AWS::LanguageExtensions to Transform as such:

Transform:
  - AWS::LanguageExtensions
  - AWS::Serverless-2016-10-31

AWS::LanguageExtensions resolves intrinsic functions if the value is known when Transforms are run.

See https://github.com/aws/serverless-application-model/issues/2533 for more information.

hoffa avatar Oct 17 '22 21:10 hoffa

Closing in favor of https://github.com/aws/serverless-application-model/issues/2533.

hoffa avatar Nov 03 '22 23:11 hoffa