14
votes

I have written a Lambda function. This function is uploaded in s3Bucket = "my-lambda", which is mapped to the role hello-lambda-role and the regionName = "us-west-2".

Now I wanted to access s3Bucket="some-other" where we have mapped Policy with 'hello-lambda-role' and it is in the region "eu-west-1".

Here is the API class I am using AmazonS3Client. My intention is to get some file from the bucket "some-other". But before that I need to make the connection.

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class LambdaFunctionHandler implements RequestHandler<Request, Response> {

    public Response handleRequest(Request request, Context context) {
        String greetingString = String.format("Hello %s %s.",
                request.firstName, request.lastName);
        return new Response(greetingString);
    }

}

Here is the class which list the bucket.

public class Test{
    private static final Log logger = LogFactory.getLog(InvokeLambda.class);
    private static final String awsAccessKeyId = "XXXXX";
    private static final String awsSecretAccessKey = "XXXXX";
    private static final String regionName = "eu-west-1";
    private static Region region;
    private static AWSCredentials credentials;
    private static AWSLambdaClient lambdaClient;
    private static AmazonS3Client s3Client;

    private static void init() {
        credentials = new BasicAWSCredentials(awsAccessKeyId,
                awsSecretAccessKey);
        s3Client = (credentials == null) ? new AmazonS3Client()
                : new AmazonS3Client(credentials);
        region = Region.getRegion(Regions.fromName(regionName));
        s3Client.setRegion(region);
        lambdaClient = (credentials == null) ? new AWSLambdaClient()
                : new AWSLambdaClient(credentials);

        lambdaClient.setRegion(region);
        // lambdaClient.configureRegion(Regions.US_WEST_2);
    }

    /**
     * The entry point into the AWS lambda function.
     */
    public static void main(String... args) {
        init();
        getExistingBucket();
    }

    private static Bucket getExistingBucket() {
        List<Bucket> buckets = s3Client.listBuckets();
        for (Bucket bucket : buckets) {
            logger.error(bucket.getName());
        }
        return null;
    }
}
1
what is the problem you are having?JD D
Placing the access key and secret key in your code is an anti-pattern. You should place that in a ~/.aws/credentials file when running code outside AWS, and use IAM roles when running on EC2 or Lambda.Mark B

1 Answers

12
votes

Use same code as you would in your test, except you don't need to provide credentials when you create the AmazonS3Client. Note that the role your lambda uses needs the authority to access your S3 bucket. The region of the S3 bucket shouldn't matter; the bucket name uniquely identifies the bucket regardless of region.

Lambdas are typically triggered by an event, but you can call AWSLambdaClient.invoke() to run it manually.

For example:

public Response handleRequest(Request request, Context context) {
    AmazonS3Client s3Client = new AmazonS3Client();
    S3Object = s3Client.getObject("some-other", request.getFilename());
    ....
    return new Response(result);
}

Deploy that to AWS as "mylambda", and then invoke remotely with:

lambdaClient.invoke(new InvokeRequest().withFunctionName("mylambda").withPayload("input"));