We are in process writing an integration test for lambda.
Here is the situation LambdaA calls LambdaB internally.
Now I am invoking sam lambda A which internally call lmbdaB... ON AWS console this is working but not able to work it from SAM local.
However, if lambaB invocation is removed from LambdaA, both lambda works fine in SAM LOCAL.
Is this supported by SAM local, any workaround to move forward?
code snippets
var AWS = require('aws-sdk');
AWS.config.region = 'eu-west-1';
var lambda = new AWS.Lambda();
exports.handler = function(event, context,callback) {
var params = {
FunctionName: 'lambda-B', // the lambda function we are going to invoke
InvocationType: 'RequestResponse',
LogType: 'Tail',
Payload: JSON.stringify(event,null,null)
};
lambda.invoke(params, function(err, data) {
const dataPayload=data.Payload;
console.log("------dataPayload-----"+dataPayload);
console.log("------Now it should work-----"+JSON.parse(dataPayload).errorType);
if (err) { context.fail(err);
} else {
context.succeed('Lambda_SIGNATURE said '+ JSON.stringify(data));
}
Actually, this exact scenario is being enabled by #508. More details on this soon, but the tl;dr version is, we will provide a new command (possibly, sam local start-lambda) that will setup a local HTTP endpoint where you can send Lambda Invokes to.
This allows you to perform Lambda calling Lambda locally by just setting a different endpoint something like:
var lambda = new AWS.Lambda()
if(process.env.AWS_SAM_LOCAL) {
// only run inside local lambda runner
var ep = new AWS.Endpoint('localhost:3000');
var lambda = new AWS.Lambda({endpoint: ep})
}
Thanks, Sanath for the reply.
That means current SAM Local version 0.4.0 does not support invoking one lambda form another.
Also if we have complex scenerio where LambdaA -->invoke-->LambdaB --> LambdaC then we will have two endpoints for each lambda? Can we have something like register lambda feature in docker image where we could invoke lambda-like lambda.invoke(params, function(err, data) ..
Yes, currently it is not supported, but it will be in the future. When it does, the feature will work similar to what you described. There will be only one endpoint.
Does this work in SAM CLI, version 0.8.1?
I'm starting with:
sam local start-lambda -t sam.yaml
And configure lambda:
var ep = new AWS.Endpoint('127.0.0.1:3001');
this.LAMBDA = new AWS.Lambda({endpoint: ep});
And I sam local shows this error when invoke a lambda function from node on that endpoint:
2019-01-01 12:19:50 127.0.0.1 - - [01/Jan/2019 12:19:50] code 400, message Bad request version ('陇卤\x8e茅\x11C\x03D\x81\x17q=脧垄脡麓q/r9茂脡脰D:\x00"\x1a\x1a\x13\x01\x13\x02\x13\x03脌+脌/脌,脌0脤漏脤篓脌\x13脌\x14\x00\x9c\x00\x9d\x00/\x005\x00')
2019-01-01 12:19:50 127.0.0.1 - - [01/Jan/2019 12:19:50] "眉0驴贸聻聯莽聞O眉脹脿!鹿l脷,職職聯J脮3聸聦~陆O8o 聰脻K茂陇卤聨茅CD聛q=脧垄脡麓q/
Is there something else that needs to be done?
I was able to get this to work on 0.6.0. I am running on mac, so I had to create my lambda with the following endpoint:
new Lambda({ region: 'us-east-1', endpoint: 'http://docker.for.mac.localhost:3001' })
The issue I have now is that it doesn't appear that InvocationType of Event is supported. I wanted to use it as a fire and forget async call from one lambda to another (L1 --(async)-> L2), both running locally. When I update the InvocationType to be Event, I get a response of
invocation-type: Event is not supported. RequestResponse is only supported.
@jadamsdb Event invocation type is part of #749
I have created two lambdas -validateuserpermission and updateuserpermission. Here is the situation updateuserpermission calls validateuserpermission internally.
Now I did sam local start-lamda and then sam local invoke updateuserpermission which internally call validateuserpermission. I am getting below error
"Could not connect to the endpoint URL: "http://127.0.0.1:3001/2015-03-31/functions/validateuserpermission/invocations\""
ON AWS console this is working but not able to work it from SAM local.
However, if validateuserpermission invocation is removed from updateuserpermission , both lambda works fine in SAM LOCAL.
Could you please help me in resolving this issue so that i would be able to test this situation.

@surbhi029 127.0.0.1 in your endpoint_url is the virtual host for sam local, which is not the host as you'd expect. --host command line argument allows start-lambda to bind to a specific hostname or ip. You can try one that is accessible to your sam local virtual host.
@renfeng how can i find a hostname or ip that is accessible to my sam local virtual host.
@surbhi029 If you on mac or windows, use https://host.docker.internal:<port> as the endpoint. If you are on linux, you can attach the container to your host network (and then able to talk to localhost), by adding --docker-network host to the command.
@jfuss Can you please provide me a little more guidance on the proper configuration to get lambda_A to call lambda_B working within sam local start-lambda. In my situation, when lambda-A invokes lambda-B I'm getting an Inaccessible host: 'host.docker.internal'. This service may not be available in the 'us-west-2' region. error. I've tried a variety of endpoint permutations (http vs https, 127.0.0.1, 192.168.99.100 (which is my local docker host ip), etc.)
This is essentially my setup:
const lambda = new AWS.Lambda({
apiVersion: '2015-03-31',
endpoint: 'https://host.docker.internal:3001'
});
lambda.invoke({
FunctionName: 'lambda_B',
InvocationType: 'Event',
Payload: JSON.stringify({"data":"for lambda-b"})
})
I start sam local ... without any extra arguments:
sam local start-lambda
And then invoke with something like this:
aws lambda invoke --function-name lambda_a --endpoint-url "http://127.0.0.1:3001" --no-verify-ssl --payload '{"data":"for lambda-a"}' out.txt
In my lambda_a function if I instantiate my change Lambda connection as such
const lambda = new AWS.Lambda({ apiVersion: '2015-03-31' });
I get no errors but my lambda_b function never gets called (or if it does no output appears in the sam local start-lambda console so it doesn't appear to get called)
OK. I figured out how to make this work. The following is what worked for me for anyone else encountering the same friction.
First and VERY IMPORTANT... if you're using a Mac or Windows make sure you're using Docker Desktop and NOT Docker Toolbox. Docker Toolbox doesn't support host.docker.internal. You could always find your docker host's IP and hard-code but that's extra work and brittle.
Second... below is example code that works. At the time of me writing this, an invocation-type of 'Event' is not supported but hopefully soon (#749). You cannot use SSL so specify sslEnabled: false and make sure your endpoint isn't referencing https.
const lambda = new AWS.Lambda({
apiVersion: '2015-03-31',
endpoint: 'http://host.docker.internal:3001',
sslEnabled: false
})
await lambda.invoke({
FunctionName: funcName,
InvocationType: 'RequestResponse',
Payload: JSON.stringify({"arguments": "for other function"
})
Assuming you've configured any required environment variables correctly you should be in business.
var ep = new AWS.Endpoint('localhost:3000');
@sanathkr this should be
var ep = new AWS.Endpoint('http://localhost:3001');
Hi,
I am very new to working with AWS lambda through Java code. My requirement is the same: calling on lambda from another using sam local.
This is the Java code i have (made changes according to some of the posts above):
```AWSLambda lambdaClient = AWSLambdaClientBuilder.standard()
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("http://host.docker.internal:3001", "")).build();
InvokeRequest request = new InvokeRequest();
JSONObject body = new JSONObject();
body.put("body", payload);
request.withFunctionName(converterLambdaARN)
.withInvocationType(InvocationType.RequestResponse)
.withPayload(body.toString());
InvokeResult result = lambdaClient.invoke(request);```
My template.yml looks like this:
Resources:
ScannerFunction:
# This resource creates a Lambda function.
Type: AWS::Serverless::Function
Properties:
Runtime: java8
Handler: abc.xyz.awslambda.LambdaInputHandler::handleRequest
CodeUri: core
Events:
ScannerEndpoint:
Type: Api
Properties:
Path: /
Method: any
ConversionEndpoint:
Type: Api
Properties:
Path: /conversion
Method: any
The above is not working. Looking forward for some pointers.
Thanks
Even though running start-api in the host network works as a workaround it would be great to have this feature directly in the CLI, is there any update on the subject?
To anyone still having this issue... what solved it for us was that some of our lambdas are exposed through API Gateway whereas others are invoked directly (by other lambdas and not exposed through APIGW). We needed to do both sam local start-api and sam local start-lambda, and then configure the internal lambda call to hit the start-lambda server port.
@pkrisko -- does this require that you change all your "directly-invoked" lambdas back to their ARNs before deploying?
Like you, I have a mixed use of API gateway invocations and direct ARN-based invocations (client.invoke). From what I understand in your post, I have two options currently:
Am I understanding that correctly?
EDIT: Fixed my own understanding. I'm using python3, so I needed to define my Boto3 lambda client to use the localhost endpoint for start-lambda. I didn't catch the example in the documentation here (in light gray text under AWS sdk--duh!): https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-start-lambda.html
With this, I only need to define my boto3/lambda client and in my client.invoke()s I can simply use the FunctionName rather than the ARN. For others that find this be sure to define your region_name correctly.
lambda_client = boto3.client('lambda',
region_name='us-east-1',
endpoint_url='http://docker.for.mac.localhost:3001')
EDIT2:
While I can finally test lambda-to-lambda invocation locally, when I remove the docker/localhost from the boto3 client definition and deploy, AWS is complaining that it cannot find the lambda invocation in my parent function when I use the FunctionName in client.invoke()
response = lambda_client.invoke(
FunctionName = 'FunctionNameHere',
Payload = json.dumps(data_here)
)
If I change the FunctionName back to the functions ARN I am able to deploy and test the api gateway endpoint successfully using the parent > child function.
Most helpful comment
Actually, this exact scenario is being enabled by #508. More details on this soon, but the tl;dr version is, we will provide a new command (possibly,
sam local start-lambda) that will setup a local HTTP endpoint where you can send Lambda Invokes to.This allows you to perform Lambda calling Lambda locally by just setting a different endpoint something like: