How to pass api endpoint parameter to lambda function in serverless

Viewed 452

I created a lambda function behind an API gateway, and I am trying to implement a healthcheck for it as well, but right now I need to do this in 2 steps:

  1. run serverless deploy so it spits out the endpoint for the api gateway.
  2. manually insert the endpoint into the healthcheck.environment.api_endpoint param, and run serverless deploy a second time

functions:
  app:
    handler: wsgi_handler.handler
    events:
      - http:
          method: ANY
          path: /
      - http:
          method: ANY
          path: '{proxy+}'

  healthcheck:
    environment:
      api_endpoint: '<how to reference the api endpoint?>'
    handler: healthcheck.handler
    events:
        - schedule: rate(1 minute)

custom:
  wsgi:
    app: app.app
    pythonBin: python3
    packRequirements: false
  pythonRequirements:
    dockerizePip: non-linux

Is there a way to get the reference to the api gateway on creation time, so it can be passed as an environment variable to the healthcheck app? the alternative I can think of, is to basically create a specific serverless.yaml just for the healthcheck purpose.

3 Answers

I noticed I can reconstruct the endpoint in the lambda, and grab the id like so:

  healthcheck:
    environment:
      api_endpoint: !Ref ApiGatewayRestApi
      region: ${env:region}
    handler: healthcheck.handler
    events:
        - schedule: rate(1 minute)

and then reconstruct:

def handler(event, context):
    api_id = os.environ['api_endpoint']
    region = os.environ['region']
    endpoint = f"https://{api_id}.execute-api.{region}.amazonaws.com/dev"

With a bit of cloudformation you can inject it directly! That way you don't need to compute it everytime in your lambda handler.

      api_endpoint: {
        'Fn::Join': [
          '',
          [
            { Ref: 'WebsocketsApi' },
            '.execute-api.',
            { Ref: 'AWS::Region' },
            '.',
            { Ref: 'AWS::URLSuffix' },
            "/${opt:stage, self:provider.stage, 'dev'}",
          ],
        ],
      },

(this is an example for a websocket API)

Is your API created through the same/another Cloudformation Stack? If so, you can reference is directly (same stack) or through a CloudFormation variable export.

https://carova.io/snippets/serverless-aws-cloudformation-output-stack-variables

https://carova.io/snippets/serverless-aws-reference-other-cloudformation-stack-variables

If you created it outside of CloudFormation, ie. in the aws console, then you'll need to add the ids into the template. Most likely by creating different environment variables based on the stage.

Related