Repository: getmoto/moto

Issue:
lambci/lambda docker images are deprecated
lambci/lambda docker images are deprecated and only support nodejs images until version 12. https://github.com/lambci/docker-lambda

Those base images should be replaced with aws lambda base image. https://github.com/aws/aws-lambda-base-images


Discussion:
Hi @wasserholz! It is possible to configure the Docker-image used by our Lambda mock. [Our documentation](http://docs.getmoto.org/en/latest/docs/services/lambda.html) suggests to use the mLupin-images, as they do have more up-to-date (NodeJS) versions:
```MOTO_DOCKER_LAMBDA_IMAGE=mLupin/docker-lambda```

Does that solve your problem?

Thanks for the quick reply. That indeed solves the node version issue.
Do you think it would make sense to move completely away from lambci/lambda docker images as they are deprecated?
It does make sense to make `mLupin` the default. 

People will still use older versions of AWSLambda though, so we still need to keep `lambci` around. For example, it's no longer possible to create Python2.7 Lambdas in AWS, but existing functions continue to work - so Moto also has to continue to support them as well.

Originally I planned to make the move to `mLupin` a breaking change, and therefore it would have to be part of a major version release. But maybe we can simply check both in our backend - first try if the existing image exists in `mLupin`, and fallback to `lambci` if that doesn't work.
I just noticed `MOTO_DOCKER_LAMBDA_IMAGE=mLupin/docker-lambda` will throw an error.

```error running docker: 400 Client Error for http+docker://localhost/v1.41/images/create?tag=nodejs14.x&fromImage=docker.io%2FmLupin%2Fdocker-lambda: Bad Request ("invalid reference format: repository name must be lowercase")```

The value must be lower case, then it works: `MOTO_DOCKER_LAMBDA_IMAGE=mlupin/docker-lambda`

Resolving patch:
diff --git a/moto/awslambda/models.py b/moto/awslambda/models.py
--- a/moto/awslambda/models.py
+++ b/moto/awslambda/models.py
@@ -765,9 +765,27 @@ def _invoke_lambda(self, event: Optional[str] = None) -> Tuple[str, bool, str]:
                             "host.docker.internal": "host-gateway"
                         }
 
-                    image_repo = settings.moto_lambda_image()
-                    image_ref = f"{image_repo}:{self.run_time}"
-                    self.docker_client.images.pull(":".join(parse_image_ref(image_ref)))
+                    # The requested image can be found in one of a few repos:
+                    # - User-provided repo
+                    # - mlupin/docker-lambda (the repo with up-to-date AWSLambda images
+                    # - lambci/lambda (the repo with older/outdated AWSLambda images
+                    #
+                    # We'll cycle through all of them - when we find the repo that contains our image, we use it
+                    image_repos = set(
+                        [
+                            settings.moto_lambda_image(),
+                            "mlupin/docker-lambda",
+                            "lambci/lambda",
+                        ]
+                    )
+                    for image_repo in image_repos:
+                        image_ref = f"{image_repo}:{self.run_time}"
+                        full_ref = ":".join(parse_image_ref(image_ref))
+                        try:
+                            self.docker_client.images.pull(full_ref)
+                            break
+                        except docker.errors.NotFound:
+                            pass
                     container = self.docker_client.containers.run(
                         image_ref,
                         [self.handler, json.dumps(event)],
@@ -1483,13 +1501,18 @@ def lambda_handler(event, context):
         # Note that this option will be ignored if MOTO_DOCKER_NETWORK_NAME is also set
         MOTO_DOCKER_NETWORK_MODE=host moto_server
 
-    The Docker images used by Moto are taken from the `lambci/lambda`-repo by default. Use the following environment variable to configure a different repo:
+    The Docker images used by Moto are taken from the following repositories:
+
+    - `mlupin/docker-lambda` (for recent versions)
+    - `lambci/lambda` (for older/outdated versions)
+
+    Use the following environment variable to configure Moto to look for images in an additional repository:
 
     .. sourcecode:: bash
 
-        MOTO_DOCKER_LAMBDA_IMAGE=mLupin/docker-lambda
+        MOTO_DOCKER_LAMBDA_IMAGE=mlupin/docker-lambda
 
-    .. note:: When using the decorators, a Docker container cannot reach Moto, as it does not run as a server. Any boto3-invocations used within your Lambda will try to connect to AWS.
+    .. note:: When using the decorators, a Docker container cannot reach Moto, as the Docker-container loses all mock-context. Any boto3-invocations used within your Lambda will try to connect to AWS.
     """
 
     def __init__(self, region_name: str, account_id: str):
diff --git a/moto/settings.py b/moto/settings.py
--- a/moto/settings.py
+++ b/moto/settings.py
@@ -89,7 +89,7 @@ def moto_server_host() -> str:
 
 
 def moto_lambda_image() -> str:
-    return os.environ.get("MOTO_DOCKER_LAMBDA_IMAGE", "lambci/lambda")
+    return os.environ.get("MOTO_DOCKER_LAMBDA_IMAGE", "mlupin/docker-lambda")
 
 
 def moto_network_name() -> str:


Test patch:
diff --git a/tests/test_awslambda/test_lambda_invoke.py b/tests/test_awslambda/test_lambda_invoke.py
--- a/tests/test_awslambda/test_lambda_invoke.py
+++ b/tests/test_awslambda/test_lambda_invoke.py
@@ -123,7 +123,7 @@ def test_invoke_event_function():
     function_name = str(uuid4())[0:6]
     conn.create_function(
         FunctionName=function_name,
-        Runtime="python2.7",
+        Runtime="python3.9",
         Role=get_role_name(),
         Handler="lambda_function.lambda_handler",
         Code={"ZipFile": get_test_zip_file1()},