17

I have three lambda functions: boss, worker1, worker2. When using boto3.client.invoke I am able to call worker1 from boss. These two are in the same region.
worker2 is in a separate region. When attempting to call worker2 from boss the following error returns:
"An error occurred (ResourceNotFoundException) when calling the Invoke operation: Functions from 'us-east-1' are not reachable in this region ('us-west-2')" . boss has an execution role with the following permission:

{
"Version": "2012-10-17",
"Statement": [
    {
        "Action": [
            "lambda:InvokeFunction"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:lambda:*:*:*"
    }
]
}

Please help clarify how permissions need to be conveyed for this to work. Thanks

Edit: master and worker1 are in us-west-2 and worker1 is in us-east-1.
Here is the code used to invoke worker from master:

def lambda_handler(event, context):
function_name = "arn:aws:lambda:us-east-1-...:function:worker_2"
lambda_client = boto3.client('lambda')
payload = json.dumps({"body-json": "payload string")
response = lambda_client.invoke(
    FunctionName = function_name,
    Payload = payload
)
response_payload = response['Payload'].read()
response_arr = json.loads(response_payload)
return response_arr['answer']
John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Sawyer Merchant
  • 1,243
  • 2
  • 12
  • 21
  • 1
    Please share the code you use to invoke the functions as well. – Dunedan Jan 14 '18 at 16:11
  • Please clarify: boss and worker1 are in us-west-2 and worker2 is in us-east-1. Is that correct? – Michael - sqlbot Jan 14 '18 at 16:48
  • @Dunedan I have shred the code. – Sawyer Merchant Jan 14 '18 at 21:28
  • @Michael-sqlbot you are correct on the regions. – Sawyer Merchant Jan 14 '18 at 21:28
  • @SawyerMerchant I'm not a python person but in the Lambda environment, your AWS client library will default to sending requests to the service endpoint in the local region, with credentials scoped to the local region, and your error message indicates that you are trying to invoke a function in us-east-1 by sending the request to the service endpoint in us-west-2. It's not a permissions problem -- the request is being sent to the wrong place. You need to supply an region and/or endpoint to your client. – Michael - sqlbot Jan 14 '18 at 21:58
  • @Michael-sqlbot you're right, however, he will need to grant permissions to the caller lambda (master) to be able to invoke a cross-region lambda function (worker2). – Ele Jan 14 '18 at 22:03

3 Answers3

22

Thank you everyone for the input. @Michael-sqlbot's comment about the AWS client library defaulting to sending requests to the local region is what helped me find the solution. For Python, the library is boto3. Having read the docs it was not clear how to set the region. It was this blog post that provided the (simple) answer:

client = boto3.client('lambda', region_name='us-west-2')

You are right Michael that the use case for one lambda to another between regions is convoluted. I'll leave this answer here in case any others who are new to boto3 encounter the same error when trying to get other resources (lambda to ec2, lambda to s3, etc) to work across regions.
Thanks

Run_Script
  • 2,487
  • 2
  • 15
  • 30
Sawyer Merchant
  • 1,243
  • 2
  • 12
  • 21
  • 1
    This is super helpful on your part and very painfully unhelpful on boto's part. The local region is used even when the full ARN including region is supplied, like `client.invoke(FunctionName='arn:aws:lambda:us-east-1:123455555555:function:worker')`. That seems bizarre. – Joe Atzberger Jul 27 '21 at 16:27
  • Extremely helpful. I was experiencing same exact issue with the AWS JavaScript Lambda SDK. I wasn't setting the region in the Lambda client when invoking a 'use-east-1' Lambda from a Lambda@Edge. All I had to do was tell the client to use 'us-east-1', and voila! Thanks: "const lambdaClient = new Lambda({ region: 'use-east-1', apiVersion: '2015-03-31' })" – Jose Quijada Dec 06 '22 at 18:18
2

let lambda = new AWS.Lambda({region: region}) and after this you should do lambda.invoke which will do the trick!

creyD
  • 1,972
  • 3
  • 26
  • 55
-1

You need to set the region of worker2 lambda function as follow:

arn:aws:lambda:us-east-1-...:function:worker_2

So, the code would look:

function_name = "arn:aws:lambda:us-east-1-...:function:worker_2"
lambda_client = boto3.client('lambda')
payload = json.dumps({"body-json": "payload string")
response = lambda_client.invoke(
    FunctionName = function_name,
    Payload = payload
)

Great, now you need to grant permissions to your Lambda master through the IAM role of master lambda function.

+ suggestion

You could create an API Gateway endpoint who executes a lambda function in region us-east-1. This endpoint could be executed only with a specific API Key to provide a layer of security.

And from master lambda function execute a request to that endpoint.

Resource

Ele
  • 33,468
  • 7
  • 37
  • 75
  • 1
    The point of the question seems to be that worker2, for whatever reason but presumably intentionally, is in us-east-1, a different region from the others. All that's needed is to tell boto3 to send the request to the Lambda service API in us-east-1 and use us-east-1 in the Sig V4 credential. The permissions are already present, as shown. Adding API Gateway to solve a simple problem seems like an unnecessary convolution. – Michael - sqlbot Jan 15 '18 at 05:19