Localstack unable to locate a lambda function within any region other than us-east-1 when using AmazonLambdaClient

Viewed 539

Using LocalStack pro 0.14.3, I created a simple Lambda function which takes in a string input and returns a string. I used the below to create a function in localstack.

awslocal lambda create-function `
--function-name "simple-lambda1" `
--zip-file fileb://C:\SimpleLambda\SimpleLambda\SimpleLambda1.zip `
--handler SimpleLambda::SimpleLambda.Function::FunctionHandler `
--runtime dotnetcore3.1 `
--role arn:aws:iam::000000000000:role/lambda-dotnet-ex

Here is my unit test.

[Test]
        public void Lambda_Function_Call_Succeeds()
        {
            var _lambdaClient = new AmazonLambdaClient(new BasicAWSCredentials("temp", "temp"), new AmazonLambdaConfig()
            {
                ServiceURL = "http://localhost:4566"
            });

            var input = "test";
           
            var lambdaInvokeRequest = new InvokeRequest
            {
                FunctionName = "simple-lambda1",
                InvocationType = InvocationType.RequestResponse,
                Payload = JsonConvert.SerializeObject(input),
            };

            var lambdaInvocationResponse = _lambdaClient.Invoke(lambdaInvokeRequest);

            var js = new JsonSerializer();
            var result = js.Deserialize<string>(lambdaInvocationResponse.Payload);
            Assert.AreEqual("WELCOME TEST", result);
        }

The above works fine but when I specify the region to be eu-west-1 when creating the function and then trying out the same unit test, I get the below exception which is correct.

Amazon.Lambda.Model.ResourceNotFoundException: 'Function not found: arn:aws:lambda:us-east-1:000000000000:function:simple-lambda1'

I tried adding the region to the lambdaclient.

[Test]
        public void Lambda_Function_Call_Succeeds()
        {
            var _lambdaClient = new AmazonLambdaClient(new BasicAWSCredentials("temp", "temp"), new AmazonLambdaConfig()
            {
                ServiceURL = "http://localhost:4566", RegionEndpoint = RegionEndpoint.EUWest1
            });

            var input = "test";
           
            var lambdaInvokeRequest = new InvokeRequest
            {
                FunctionName = "simple-lambda1",
                InvocationType = InvocationType.RequestResponse,
                Payload = JsonConvert.SerializeObject(input),
            };

            var lambdaInvocationResponse = _lambdaClient.Invoke(lambdaInvokeRequest);

            var js = new JsonSerializer();
            var result = js.Deserialize<string>(lambdaInvocationResponse.Payload);
            Assert.AreEqual("WELCOME TEST", result);
        }

But the above code gives me a Amazon.Lambda.AmazonLambdaException: 'The security token included in the request is invalid.' WebException: The remote server returned an error: (403) Forbidden. Is there anything obvious that I'm doing wrong ?

Here is my docker compose file

version: "3.8" 
services: 
   localstack: 
        image: localstack/localstack:latest
        container_name: localstack_test         
        privileged: true 
        ports: 
            - 53:53
            - 4510-4599:4510-4599            
            - 8000:8080
        environment: 
           - LOCALSTACK_API_KEY=XXX
           - SERVICES=s3,sqs,dynamodb,lambda,cloudformation,ssm,iam,cloudwatch,sts,kinesis,events,xray,ecr           
           - DATA_DIR=/tmp/localstack/data     
           - LEGACY_PERSISTENCE=false
           - EDGE_PORT=4566 
           - PORT_WEB_UI=8081 
           - START_WEB=1
           - DEBUG=1 
           - LAMBDA_EXECUTOR=local
           - HOSTNAME_EXTERNAL=localhost
           - LOCALSTACK_HOSTNAME=localhost
           - REQUIRE_PRO=0               
        volumes: 
           - c:/localstack:/tmp/localstack 
           - '/var/run/docker.sock:/var/run/docker.sock'  
        networks: 
            - localstack-ent 
networks: 
    localstack-ent: 
        external: false 
        driver: bridge 
2 Answers

Using the below in the docker compose file, fixed the problem for me

- USE_SINGLE_REGION=1
- DEFAULT_REGION=eu-west-1

If you do not wish to disable LocalStacks multi-region capability (which your snippet does), please create your client by setting the AuthenticationRegion instead of the RegionEndpoint. The RegionEndpoint will override ServiceURL, which results in your request being made to AWS itself, not LocalStack. Here a small snippet of the Lambda client creation:

var lambdaClient = new AmazonLambdaClient(new BasicAWSCredentials("temp", "temp"), new AmazonLambdaConfig()
    {
        ServiceURL = "http://localhost:4566",
        AuthenticationRegion = "eu-west-1"
    });
Related