0

I can't seem to get this to work. I create 2 lambdas via C9. I'm using boto3 to invoke one lambda from another. Everything seems to work just fine via C9 but when I publish and try to access via API Gateway I keep getting "Endpoint request timed out" errors.

I know it can't be a timeout issue because I've set up my yaml files to have enough time to execute and the lambda right now are really simple (only returning a string)

here are my current yaml file. I'm wondering if maybe there are some sort of permissions I need to include for API Gateway in the second yaml

Lambda1

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
    api:
        Type: 'AWS::Serverless::Function'
        Properties:
        Description: ''
        Handler: api/lambda_function.lambda_handler
        MemorySize: 256
        Role: 'arn:aws:iam::820788395625:role/service-role/api_int-role'
        Runtime: python3.6
        Timeout: 30
        VpcConfig:
            SecurityGroupIds:
                - ...
            SubnetIds:
                - ...
        Policies: AWSLambdaFullAccess

Lambda2

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
    api:
        Type: 'AWS::Serverless::Function'
        Properties:
            Description: ''
            Handler: api/lambda_function.lambda_handler
            MemorySize: 512
            Role: 'arn:aws:iam::820788395625:role/service-role/api_int-role'
            Runtime: python3.6
            Timeout: 15
            VpcConfig:
                SecurityGroupIds:
                    - ...
                SubnetIds:
                    - ...

I just set up an API Gateway endpoint directly to Lambda2 and it returned no problem. So...

API Gateway -> Lambda 2 (works) API Gateway -> Lambda 1 -> Lambda 2 (does not work)

So for some reason when I want to call Lambda 2 via Lambda 1 over API Gateway it doesn't work.

Here is the code that is calling the 2nd Lambda

import json
import boto3

def lambda_handler(event, context):
    print('call boto3 client')
    lambda_client = boto3.client('lambda', region_name='us-east-1')
    print('boto3 client called')

    print('invoke lambda')
    env_response = lambda_client.invoke(
        FunctionName='cloud9-apiAlpha-api-TBSOYXLVBCLX',
        InvocationType='RequestResponse',
        Payload=json.dumps(event)
    )
    print('lambda invoked')

    print('env_response')
    print(env_response)
    print(env_response['Payload'])
    print(env_response['Payload'].read())

    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json', 
            'Access-Control-Allow-Methods': 'POST,GET,OPTIONS,PUT,DELETE',
            'Access-Control-Allow-Origin': '*'
        },
        'body': 'HELLO WORLD!',
        'isBase64Encoded': False
    }

Now when I look at the logs it gets to print('invoke lambda') but then stops and timesout

6
  • does your role have the proper permission to execute another lambda ? api_int-role Commented Sep 7, 2018 at 17:57
  • Can you show us the actual code of how are you calling the lambda? Commented Sep 7, 2018 at 18:06
  • @AminAhmedKhan I've been told that role has permissions to execute another lambda Commented Sep 11, 2018 at 16:46
  • @yorodm I've shared the code calling the 2nd Lambda Commented Sep 11, 2018 at 16:49
  • If you're having timeout issues then you either call the lambda asynchronously or increase the timeout threshold of your calling lambda Commented Sep 11, 2018 at 16:54

2 Answers 2

1

1.Invoking a Lambda from another Lambda can't be done without some configuration. In your .yml file, permission must be specified in order to invoke another Lambda. This can be accomplished by adding an iamRoleStatements section under the provider property or by add the simple policy AWSLambdaRole to the existing role attached to the lambda function_1.

provider:  
    name: aws
    runtime: <runtime goes here> # e.g. python3.6 or nodejs6.10
    iamRoleStatements:
      - Effect: Allow
        Action:
          - lambda:InvokeFunction
        Resource: "*" 

or do this add/attach this policy to your existing role attached to your lambda function_1 AWSLambdaRole

2.Invoking lambda function_1 code attached.

global LAMBDA_CLIENT
if not LAMBDA_CLIENT:
    LAMBDA_CLIENT = boto3.client('lambda')
try:
    encoded_payload = json.dumps({'message': 'this is an invokcation call form lambda_1'}).encode(UTF_8)

    invoke_resp = lambda_client.invoke(
        FunctionName='function_2',
        InvocationType='RequestResponse',
        Payload=encoded_payload)

    status_code = invoke_resp['StatusCode']
    if status_code != 200:
        LOGGER.error('error ')
    paylaod = invoke_resp['Payload'].read()
    resp = json.loads(payload)
    print(resp)
except Exception:

IF you are using InvocationType=RequestResponse then you can return some response form function_2.

Sign up to request clarification or add additional context in comments.

9 Comments

I created this in C9 and there is a template.yml do I need a serverless.yml also then?
I think you have a existing role attached to your lambda then its worth attaching this policy AWSLambdaRole to it. So you don't need any changes to .yml file in your case, apologies if i am not able to explain stuff properly
There has to be a permissions thing somewhere because in the logs it gets to the invoke_resp = lambda_client.invoke and then hangs and eventually times out
Ok so it looks like doing this made it work Payload=bytes(encoded_payload)
nice one json.loads() should do it then
|
1

Finally found the solution. The answer to my particular problem was Lambda 1 & Lambda 2 were operating over VPC thus no internet connection. Once I removed VPC from Lambda 1 the invocation of Lambda 2 worked without any problems.

Just wanted to share in case I can save anyone else a weeks worth of debugging LOL

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.