How to invoke lambda function from local machine

Question:

I’m relatively new to python and lambda, and I have created this lambda function in the AWS console.

import boto3
import json


def lambda_handler(event, context):

    s3 = boto3.resource('s3')
    bucket = s3.Bucket('demo-bucket')

    for file in bucket.objects.all():
        print(file.key, file.last_modified)
     
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
        }

And when I test it via the console, it works just fine. No issues at all.

But then I try to run something similar from the a python file on my laptop, it throws the error
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied

This is what my local python file looks like.

import boto3
import json
import os


def lambda_handler():

    lambda_client = boto3.client('lambda')
    role_response = (lambda_client.get_function_configuration(
        FunctionName = os.environ['LAMBDA_FUNCTION'])
    )

    print(role_response['Role'])
    
    s3 = boto3.resource('s3')
    bucket = s3.Bucket('demo-bucket')

    for file in bucket.objects.all():
        print(file.key, file.last_modified)
     
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
        }

lambda_handler()

FunctionName = os.environ['LAMBDA_FUNCTION'] is the same function I’m calling via the console that works.

Is there a reason why it doesn’t work when I use this local file?

What am I doing wrong please?

Asked By: Metro

||

Answers:

Like @Mark B said, it’s definitely an s3 permissions error.
You can try adding these extra lines to your local script.

account_id = boto3.client('sts').get_caller_identity()
print(account_id['Arn'])

So it looks like this.

import boto3
import json
import os


def lambda_handler():

    lambda_client = boto3.client('lambda')
    role_response = (lambda_client.get_function_configuration(
        FunctionName = os.environ['LAMBDA_FUNCTION'])
    )
    
    account_id = boto3.client('sts').get_caller_identity()
    print(account_id['Arn'])
    
    print(role_response['Role'])
    
    s3 = boto3.resource('s3')
    bucket = s3.Bucket('demo-bucket')

    for file in bucket.objects.all():
        print(file.key, file.last_modified)
     
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
        }

lambda_handler()

While running it in the console, you’re most likely using a role that has access to the bucket, but locally, it’s being executed by a user that doesn’t.

These two new lines should show you the user executing the python script, and you can check the bucket to see if the user has permissions.

Answered By: Hammed