AWS SAM template - trouble referencing my API inside lambda function - circular dependency.

0

I have an AWS SAM app template as follows...

Basically the app has 2 lambdas and an API.

Let's say lambda1 has a get, post, put and delete function for path /hello in the api. And lambda2 has a get, post, put and delete function for path /world in the api.

For POST /world in the API, I want to first call GET /hello, then do something with that data and the payload from POST /world.

I am trying to achieve this by defining an API_ROUTE environment variable for my lambdas in the template file. I can find lots of examples of how to get the API base url as an output from the app. But if I try to reference this output as an environment variable it doesn't work, and if i try to build it with the !Sub function, there's a circular dependency.

How can I achieve this or should I be going about this in a different way?

---
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Globals:
  Function:
    Runtime: python3.9
    Handler: app.lambda_handler
    Timeout: 180
    Environment:
      Variables:
        API_ROUTE: !Ref MyAPI # - doesn't work
        API_ROUTE: !Sub "https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com/prod/" # - produces circular dependency error

Outputs:
  APIEndpoint:
    Description: "API Prod stage endpoint"
    Value: !Sub "https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com/prod/"
  
Resources:
  ##### Functions
  Lambda1:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: lambda1/
  Lambda2:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: lambda2/
      Policies:
        - AmazonAPIGatewayInvokeFullAccess # in reality i'd make this be more specific
        - Version: '2012-10-17'
  ##### API
  MyAPI:
    Type: AWS::Serverless::Api
    Properties:
      Auth:
        DefaultAuthorizer: None 
      StageName: prod
      DefinitionBody:
        path_to_definition_body
  MyApiInvokeRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "apigateway.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Policies:
        - PolicyName: InvokeLambda
          PolicyDocument:
            Statement:
              - Effect: "Allow"
                Action:
                  - lambda:InvokeFunction
                Resource: "*" # in reality i'd make this be more specific
  
1 Answer
1

As I understand your explanation above, the call to POST /world (lambda1) depends on the data returned from Get /hello (lambda2). Since Lambda1 and Lambda 2 use the same API Gateway endpoint, I assume they part of the same service backend (i.e. not a a different microservice). If this is true then there is no need to get the result of lambda2 via the same API gateway endpoint. You can use Step Functions to orchestrate these two lambda functions. Calling the Lambda2 from Lambda1 is also possible but not recommended. See the following documentation https://docs.aws.amazon.com/lambda/latest/dg/lambda-stepfunctions.html.

AWS
Asif_H
answered 7 months ago
profile picture
EXPERT
reviewed 7 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions