4

I'm creating a Lambda function via CloudFormation (AWS' SAM: Serverless Application Model) and have defined an API endpoint via the Lambda-function's Events property.

  ...
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Description: Do amazing things
      CodeUri: my_function/
      Events:
        Trigger:
          Type: Api
          Properties:
            Path: /p1/{v1}
            Method: post
      Handler: app.run
  ...

I'd now like to use the URL of the endpoint that's been created in another part of the CloudFormation YAML file. I've tried to use the SAM documentation for Lambda but the only return values have to do with the Function's ARN and resource name.

Specifically, thought I think unrelated to the exact question, I want to use the API endpoint as a subscription for an SNS Topic.

¿How can I get the URL of the API Endpoint?

Matt
  • 907
  • 1
  • 8
  • 17
  • Can you provide an example of an endpoint URL that corresponds to the resource being created? – Rodrigo Murillo Jan 18 '20 at 05:41
  • This would end up being [the template for] the URL endpoint generated by the above: https://{{uuid}}.execute-api.{{aws-region}}.amazonaws.com/Prod/p1/v1=abc – Matt Jan 18 '20 at 05:43
  • Got it. I have used the Fn:Join function to generate various Urls that are not directly returned by a resource or by Fn:GetAtt. Do you have a way to get the uuid? – Rodrigo Murillo Jan 18 '20 at 05:53

2 Answers2

2

I think I found the answer across a couple of places.

This Stack Overflow post shows that there is an implicit reference created that you can use as follows

!Ref ServerlessRestApi

This was supported in practice, by a SAM Respository App

And then I re-read, more closely, the SAM API documentation which shows the RestApiId Property. It says

...Typically, this is set to reference an AWS::Serverless::Api resource defined in this template. If not defined, a default AWS::Serverless::Api resource is created..."

So it looks like you can reference it as !Ref ServerlessRestApi without any modification to the YAML in the original question, or you could add the following Property, RestApiId: MyAPI, and reference it as !Ref MyAPI.

However, to get the actual URL, it looks like you have to use a Fn::Sub to glue together a couple of parts. Pahud Hsieh does it in his SAM Repository app above

Outputs:
  APIUrlPrefix:
    Value:
      Fn::Sub:
      - https://${ServerlessRestApi}.execute-api.${Region}.amazonaws.com/Prod/incomingwebhooks/
      - Region:
          Ref: AWS::Region
        ServerlessRestApi:
          Ref: ServerlessRestApi
...
Matt
  • 907
  • 1
  • 8
  • 17
  • 1
    You have a trailing ' too much in the URL. Otherwise it works perfectly! Was just looking around for this answer yesterday, so thanks a lot!! – Incinerator Jan 19 '21 at 08:32
2

you can directly reference the RestApi resource like this.

Resources:
  apiGateway:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: !Sub ${AWS::StackName}-my-api
      Description: my-api-edge


Outputs:
  apiGatewayInvokeURL:
    Value: !Sub "https://${apiGateway}.execute-api.${AWS::Region}.amazonaws.com/${apiGatewayStageName}"

  lambdaArn:
    Value: !GetAtt "lambdaFunction.Arn"
Arun Kamalanathan
  • 8,107
  • 4
  • 23
  • 39