Michael Durrant
Michael Durrant

Reputation: 96454

aws - how to get one lambda to call another

The 2nd lambda works and inserts a record into dynamoDB when I test it alone.

I then have another lambda which is trying to call it but nothing seems to happen.

Cloudwatch logs show no issues and show puts statements after call.
But dynamodb table doesn't get any records inserted.

Both lambdas have full lambda acccess

Lambda 2 - LamdaLamdaDynamodb

2nd lambda that works on its own:

# lambda 'two'
require 'aws-sdk-lambda'
require 'aws-sdk-dynamodb'
require 'time'
require 'json'

def handler(event:, context:)
  p "index2"
  dynamodb = Aws::DynamoDB::Client.new(region: 'us-east-2')
  item = {
      "name": "#{Time.now.to_s[0..19]} #{event['Records'][0]['eventSource']} #{event['Records'][0]['eventName']}",
      "eventTime": "#{Time.now.to_s[0..19]}",
      "eventSource": "lambda",
      "description": "from lambda event",
      "eventID": "#{event['Records'][0]['eventID']}",
      "eventName": "#{event['Records'][0]['eventName']}", 
      "eventSource":"#{event['Records'][0]['eventSource']}",
      "awsRegion":"#{event['Records'][0]['awsRegion']}"
  }
  params = {
      table_name: 'any_event',
      item: item
  }
  begin
    dynamodb.put_item(params)
    puts 'Added item'
  rescue  Aws::DynamoDB::Errors::ServiceError => error
    puts 'Unable to add item:'
    puts error.message
  end
end

Lambda 1 - triggerLamdaLamda

First Lambda that is trying to call it:

require 'aws-sdk-lambda'
require 'time'
require 'json'
def lambda_handler(event:, context:)
  client = Aws::Lambda::Client.new(region: 'us-east-2')
  payload = '{"name": "thing"}' 
  the_payload = JSON.generate(payload)
  resp = client.invoke({
    function_name: 'LamdaLamdaDynamodb',
    invocation_type: 'RequestResponse',
    log_type: 'None',
    payload: the_payload
  })
end

Upvotes: 1

Views: 204

Answers (2)

amittn
amittn

Reputation: 2355

  • You can call a lambda form another lambda. github python & terraform implementation
  • The calling lambda should have a role with attached policy having lambda:InvokeFunction action.
  • The calling lambda assuming its calling the other 2 lambda synchronously should have invocationType=RequestResponse(its the default type).AWSJavaScriptSDK
invoke_resp = LAMBDA_CLIENT.invoke(
        FunctionName='second_lambda',
        InvocationType='RequestResponse',
        Payload=encoded_payload)
  • Different invocationType are as follows RequestResponse (default), Event and DryRun.aws docs Depending upon your synchronous invocation or asynchronous invocation.
  • In your case the only thing missing which i can think of is, This operation requires permission for the lambda:InvokeFunction action.

Upvotes: 2

Simon
Simon

Reputation: 915

  1. Using time as a key is not a good idea. See: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-uniform-load.html
  2. You can use Step Functions to chain Lambda functions in a workflow fashion.
  3. The first lambda can emit a CloudWatch event that the second Lambda can listen for as a trigger. The event would contain the payload.

IMO: [3] is the easiest way to do this. You can also try setting the function_name parameter to the ARN of the Lambda function.

Upvotes: 1

Related Questions