From 47ab2e5660a75f0acff33bc29dda02cad09e3726 Mon Sep 17 00:00:00 2001 From: HarshCasper Date: Wed, 10 May 2023 23:41:50 +0530 Subject: [PATCH 1/3] improve the lambda container images tutorial --- .../lambda-ecr-container-images/index.md | 70 +++++++++++-------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/content/en/tutorials/lambda-ecr-container-images/index.md b/content/en/tutorials/lambda-ecr-container-images/index.md index b0dfaa3a61..a632279123 100644 --- a/content/en/tutorials/lambda-ecr-container-images/index.md +++ b/content/en/tutorials/lambda-ecr-container-images/index.md @@ -3,49 +3,54 @@ title: "Deploying Lambda container image locally with Elastic Container Registry linkTitle: "Deploying Lambda container image locally with Elastic Container Registry (ECR) using LocalStack" weight: 2 description: > - You can create & deploy your Lambda functions using Lambda container image by packaging your code and dependencies in a Docker image! Learn how you can create a Lambda container image using a local Elastic Container Registry (ECR) in LocalStack. + Learn how to create and deploy Lambda functions using container images in LocalStack. This tutorial guides you through packaging your code and dependencies into a Docker image, creating a local Elastic Container Registry (ECR) in LocalStack, and deploying the Lambda container image. type: tutorials --- -AWS Lambda is a serverless compute system that allows you to break down your application into many independent functions and deploy them as singular units that can run on the AWS ecosystem. Lambda is tightly integrated with other AWS services and allows you to write your serverless functions in different programming languages suited for various supported runtimes. You can deploy Lambda functions programmatically by uploading a ZIP file containing your code and dependencies or packaging your code in a container image and deploying it via Elastic Container Registry (ECR). +[Lambda](https://aws.amazon.com/lambda/) is a powerful serverless compute system that enables you to break down your application into smaller, independent functions. These functions can be deployed as individual units within the AWS ecosystem. Lambda offers seamless integration with various AWS services and supports multiple programming languages for different runtime environments. To deploy Lambda functions programmatically, you have two options: [uploading a ZIP file containing your code and dependencies](https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-zip.html) or [packaging your code in a container image](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-images.html) and deploying it through Elastic Container Registry (ECR). -ECR allows users to push their software packaged inside containers into an AWS-managed registry. Using ECR, you can version, tag, and manage your image lifecycles independently of your application. ECR is tightly integrated with other AWS services, such as ECS, EKS, and Lambda, and allows you to deploy your container image to these services. You can create container images using Docker and your Lambda functions by implementing the Lambda Runtime API and following the Open Container Initiative (OCI) specifications. +[ECR](https://aws.amazon.com/ecr/) is an AWS-managed registry that facilitates the storage and distribution of containerized software. With ECR, you can effectively manage your image lifecycles, versioning, and tagging, separate from your application. It seamlessly integrates with other AWS services like ECS, EKS, and Lambda, enabling you to deploy your container images effortlessly. Creating container images for your Lambda functions involves using Docker and implementing the Lambda Runtime API according to the Open Container Initiative (OCI) specifications. -[LocalStack Pro](https://localstack.cloud) supports the creation of Lambda functions using container images via ECR and allows you to deploy your Lambda functions locally using LocalStack. In this tutorial, we will learn how to create a Lambda function using a container image and deploy it locally using LocalStack. +[LocalStack Pro](https://localstack.cloud) extends support for Lambda functions using container images through ECR. It enables you to deploy your Lambda functions locally using LocalStack. In this tutorial, we will explore creating a Lambda function using a container image and deploying it locally with the help of LocalStack. ## Prerequisites -For this tutorial you will need: +Before diving into this tutorial, make sure you have the following prerequisites: -- [LocalStack Pro](https://localstack.cloud/pricing/) to emulate Amazon ECS and AWS Lambda locally - - Don't worry, if you don't have a subscription yet, you can just get a trial license for free. -- [awslocal](https://docs.localstack.cloud/integrations/aws-cli/#localstack-aws-cli-awslocal) +- LocalStack Pro +- [`awslocal` CLI](https://docs.localstack.cloud/integrations/aws-cli/#localstack-aws-cli-awslocal) +- [Python](https://www.python.org/downloads/) - [Docker](https://docker.io/) ## Creating a Lambda function -To package & deploy a Lambda as a container image, we'll first create a Lambda function containing our code and a Dockerfile. Create a new directory and initialize it with two files: `handler.py`, to save our Python-based Lambda function, and `Dockerfile`, to package our code and dependencies into a container image. +To package and deploy a Lambda function as a container image, we'll create a Lambda function containing our code and a Dockerfile. Create a new directory for your lambda function and navigate to it: {{< command >}} $ mkdir -p lambda-container-image $ cd lambda-container-image +{{< / command >}} + +Initialize the directory by creating two files: `handler.py` and `Dockerfile`. Use the following commands to create the files: + +{{< command >}} $ touch handler.py Dockerfile {{< / command >}} -Let us use the following Python code, in `handler.py`, to create a Lambda function that returns a simple `'Hello from LocalStack Lambda container image!'` message. +Open the `handler.py` file and add the following Python code, which represents a simple Lambda function that returns the message `'Hello from LocalStack Lambda container image!'`: ```python def handler(event, context): print('Hello from LocalStack Lambda container image!') ``` -In the above example, the `handler` function is executed by the Lambda service every time a trigger event occurs. The above function serves as an entrypoint for the Lambda function inside a runtime environment and accepts `event` and `context`, to receive information about the event and the invocation properties. +In the code above, the `handler` function is executed by the Lambda service whenever a trigger event occurs. It serves as the entry point for the Lambda function within the runtime environment and accepts `event` and `context` as parameters, providing information about the event and invocation properties, respectively. -## Building the image +Following these steps, you have created the foundation for your Lambda function and defined its behaviour using Python code. In the following sections, we will package this code and its dependencies into a container image using the `Dockerfile`. -To package our Lambda function as a container image, we need to create a `Dockerfile` that contains the instructions to build our image. The image should be able to execute a read-only file system with access to a `/tmp` directory. We would be using [AWS base images for Lambda](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-images.html#runtimes-images-lp) to preload the runtimes and dependencies that are required to create Lambda images. +## Building the image -To build the container image for Python, we would use a `python:3.8 base image`. Open the `Dockerfile` and specify the function handler to ensure that the Lambda runtime can locate it where the Lambda handler is available: +To package our Lambda function as a container image, we must create a Dockerfile containing the necessary instructions for building the image. Open the Dockerfile and add the following content. This Dockerfile uses the `python:3.8` base image provided by AWS for Lambda and copies the `handler.py` file into the image. It also specifies the function handler as `handler.handler` to ensure the Lambda runtime can locate it where the Lambda handler is available. ```Dockerfile FROM public.ecr.aws/lambda/python:3.8 @@ -56,24 +61,26 @@ CMD [ "handler.handler" ] ``` {{< alert title="Note" color="primary">}} -If you have additional dependencies specificed, create a file named `requirements.txt` and list the libraries in the file. Install the dependencies in the Dockerfile under the `${LAMBDA_TASK_ROOT}` directory. +If your Lambda function has additional dependencies, create a file named `requirements.txt` in the same directory as the Dockerfile. List the required libraries in this file. You can install these dependencies in the `Dockerfile` under the `${LAMBDA_TASK_ROOT}` directory. {{< /alert >}} -Use Docker to build an image using this function code: +With the Dockerfile prepared, you can now build the container image using the following command: {{< command >}} $ docker build -t localstack-lambda-container-image . {{< / command >}} +By executing these steps, you have defined the Dockerfile that instructs Docker on how to build the container image for your Lambda function. The resulting image will contain your function code and any specified dependencies. + ## Publishing the image to ECR -Now that the initial setup is done, we can give LocalStack's AWS emulation a try by pushing our image to ECR and deploying the Lambda container image. Let's start LocalStack: +Now that the initial setup is complete let's explore how to leverage LocalStack's AWS emulation by pushing our image to ECR and deploying the Lambda container image. Start LocalStack by executing the following command. Make sure to replace `` with your actual API key: {{< command >}} $ LOCALSTACK_API_KEY= localstack start -d {{< / command >}} -Once LocalStack is started, we can create a new ECR repository to store our container image. We will use the `awslocal` CLI to create a new ECR repository using the `create-repository` command. We will pass the repository name using the `repository-name` flag. +Once the LocalStack container is running, we can create a new ECR repository to store our container image. Use the `awslocal` CLI to achieve this. Run the following command to create the repository, replacing `localstack-lambda-container-image` with the desired name for your repository: {{< command >}} $ awslocal ecr create-repository --repository-name localstack-lambda-container-image @@ -96,17 +103,17 @@ $ awslocal ecr create-repository --repository-name localstack-lambda-container-i {{< / command >}} {{< alert title="Note" color="primary">}} -To further customize the repository, you can pass additional flags to the `create-repository` command. For more information, refer to the [AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/reference/ecr/create-repository.html). +To further customize the ECR repository, you can pass additional flags to the `create-repository` command. For more details on the available options, refer to the [AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/reference/ecr/create-repository.html). {{< /alert >}} -Let us now build the image and push it to the ECR repository: +Next, build the image and push it to the ECR repository. Execute the following commands: {{< command >}} $ docker build -t localhost:4510/localstack-lambda-container-image . $ docker push localhost:4510/localstack-lambda-container-image {{< / command >}} -In the above commands, we have specified the `repositoryUri` as the image name to push the image to the ECR repository. We can now verify that the image is pushed to the repository by using the `describe-images` command: +In the above commands, we specify the `repositoryUri` as the image name to push the image to the ECR repository. After executing these commands, you can verify that the image is successfully pushed to the repository by using the `describe-images` command: {{< command >}} $ awslocal ecr describe-images --repository-name localstack-lambda-container-image @@ -128,11 +135,11 @@ $ awslocal ecr describe-images --repository-name localstack-lambda-container-ima } {{< / command >}} -Now that we have pushed the image to the ECR repository, we can deploy the Lambda function using the container image. +By running this command, you can confirm that the image is now in the ECR repository. It ensures it is ready for deployment as a Lambda function using LocalStack's AWS emulation capabilities. ## Deploying the Lambda function -To deploy the container image as a Lambda function, we need to create a new Lambda function using the `create-function` command. We will pass the `ImageUri` flag to specify the image URI of the container image that we have pushed to the ECR repository. +To deploy the container image as a Lambda function, we'll create a new Lambda function using the `create-function` command. Run the following command to create the function: {{< command >}} $ awslocal lambda create-function \ @@ -165,20 +172,25 @@ $ awslocal lambda create-function \ } {{< / command >}} -The above command has taken various flags to create the Lambda function. We have specified the `ImageUri` flag to specify the image URI of the container image that we have pushed to the ECR repository. We have also specified the `package-type` flag to specify the package type as `Image`. For the role, we have specified a mock role ARN. To create an actual role, please refer to the [IAM documentation]({{< ref "iam" >}}). +The command provided includes several flags to create the Lambda function. Here's an explanation of each flag: + +- `ImageUri`: Specifies the image URI of the container image you pushed to the ECR repository (`localstack-lambda-container-image` in this case). +- `package-type`: Sets the package type to Image to indicate that the Lambda function will be created using a container image. +- `function-name`: Specifies the name of the Lambda function you want to create. +- `runtime`: Defines the runtime environment for the Lambda function. In this case, it's specified as provided, indicating that the container image will provide the runtime. +- `role`: Sets the IAM role ARN that the Lambda function should assume. In the example, a mock role ARN is used. For an actual role, please refer to the [IAM documentation]({{< ref "iam" >}}). -Let us now invoke the Lambda function using the `invoke` command: +To invoke the Lambda function, you can use the `invoke` command: {{< command >}} $ awslocal lambda invoke --function-name localstack-lambda-container-image /tmp/lambda.out { "StatusCode": 200, - "LogResult": "", "ExecutedVersion": "$LATEST" } {{< / command >}} -The logs of the Lambda invocation should be visible in the LocalStack container output (with `DEBUG=1` enabled): +The command above will execute the Lambda function locally within the LocalStack environment. The response will include the StatusCode, LogResult, and ExecutedVersion. You can find the logs of the Lambda invocation in the LocalStack container output, precisely when `DEBUG=1` is enabled. {{< command >}} Starting XRay server loop on UDP port 2000 @@ -189,6 +201,6 @@ Hello from LocalStack Lambda container image! ## Conclusion -With the Lambda container image support, you can use Docker to package your custom code and dependencies for Lambda functions. LocalStack allows you to package, deploy, and invoke Lambda functions locally. Using LocalStack, you can develop, debug, and test your Lambda functions in conjunction with a wide range of AWS services. Check out [Lambda Hot Reloading]({{< ref "hot-reloading" >}}) and [Lambda Hot Reloading]({{< ref "debugging" >}}) for advanced usage patterns. +In conclusion, the Lambda container image support enables you to use Docker to package your custom code and dependencies for Lambda functions. With the help of LocalStack, you can seamlessly package, deploy, and invoke Lambda functions locally. It empowers you to develop, debug, and test your Lambda functions with a wide range of AWS services. For more advanced usage patterns, you can explore features like [Lambda Hot Reloading]({{< ref "hot-reloading" >}}) and [Lambda Debugging]({{< ref "debugging" >}}). -The code for this tutorial (including a `Makefile` to execute it step-by-step) can be found in our [LocalStack Pro samples over GitHub](https://github.com/localstack/localstack-pro-samples/tree/master/lambda-container-image). +To further explore and experiment with the concepts covered in this tutorial, you can access the code and accompanying `Makefile` on our [LocalStack Pro samples over GitHub](https://github.com/localstack/localstack-pro-samples/tree/master/lambda-container-image). From 11de16d351485e3b309138d611a6275764fec846 Mon Sep 17 00:00:00 2001 From: HarshCasper Date: Thu, 11 May 2023 11:40:25 +0530 Subject: [PATCH 2/3] few more fixes --- .../lambda-ecr-container-images/index.md | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/content/en/tutorials/lambda-ecr-container-images/index.md b/content/en/tutorials/lambda-ecr-container-images/index.md index a632279123..3f252c3695 100644 --- a/content/en/tutorials/lambda-ecr-container-images/index.md +++ b/content/en/tutorials/lambda-ecr-container-images/index.md @@ -146,29 +146,38 @@ $ awslocal lambda create-function \ --function-name localstack-lambda-container-image \ --package-type Image \ --code ImageUri="localstack-lambda-container-image" \ - --role arn:aws:iam::000000000:role/lambda-role \ + --role arn:aws:iam::000000000000:role/lambda-role \ --handler handler.handler { "FunctionName": "localstack-lambda-container-image", - "FunctionArn": "arn:aws:lambda::000000000000:function:localstack-lambda-container-image", - "Role": "arn:aws:iam::000000000:role/lambda-role", + "FunctionArn": "arn:aws:lambda:us-east-1:000000000000:function:localstack-lambda-container-image", + "Role": "arn:aws:iam::000000000000:role/lambda-role", "Handler": "handler.handler", + "CodeSize": 0, "Description": "", "Timeout": 3, - "LastModified": "", + "MemorySize": 128, + "LastModified": "2023-05-11T06:06:37.372826+0000", + "CodeSha256": "9be73524cd5aa70fbcee3fc8d7aac4eb7e2a644e9ef2b13031719077a65c0031", "Version": "$LATEST", - "VpcConfig": {}, "TracingConfig": { "Mode": "PassThrough" }, - "RevisionId": "", - "Layers": [], - "State": "Active", - "LastUpdateStatus": "Successful", + "RevisionId": "f953a7ea-4d92-4458-a46c-821c056fd33c", + "State": "Pending", + "StateReason": "The function is being created.", + "StateReasonCode": "Creating", "PackageType": "Image", "Architectures": [ "x86_64" - ] + ], + "EphemeralStorage": { + "Size": 512 + }, + "SnapStart": { + "ApplyOn": "None", + "OptimizationStatus": "Off" + } } {{< / command >}} @@ -193,9 +202,6 @@ $ awslocal lambda invoke --function-name localstack-lambda-container-image /tmp/ The command above will execute the Lambda function locally within the LocalStack environment. The response will include the StatusCode, LogResult, and ExecutedVersion. You can find the logs of the Lambda invocation in the LocalStack container output, precisely when `DEBUG=1` is enabled. {{< command >}} -Starting XRay server loop on UDP port 2000 -Starting DNS server loop on UDP port 53 ------ Hello from LocalStack Lambda container image! {{< / command >}} From 4b430b208e454a462009b2d85a33628b3608e695 Mon Sep 17 00:00:00 2001 From: HarshCasper Date: Tue, 23 May 2023 12:11:41 +0530 Subject: [PATCH 3/3] fix nits --- .../lambda-ecr-container-images/index.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/content/en/tutorials/lambda-ecr-container-images/index.md b/content/en/tutorials/lambda-ecr-container-images/index.md index 3f252c3695..bf04334a1a 100644 --- a/content/en/tutorials/lambda-ecr-container-images/index.md +++ b/content/en/tutorials/lambda-ecr-container-images/index.md @@ -77,7 +77,7 @@ By executing these steps, you have defined the Dockerfile that instructs Docker Now that the initial setup is complete let's explore how to leverage LocalStack's AWS emulation by pushing our image to ECR and deploying the Lambda container image. Start LocalStack by executing the following command. Make sure to replace `` with your actual API key: {{< command >}} -$ LOCALSTACK_API_KEY= localstack start -d +$ LOCALSTACK_API_KEY= DEBUG=1 localstack start -d {{< / command >}} Once the LocalStack container is running, we can create a new ECR repository to store our container image. Use the `awslocal` CLI to achieve this. Run the following command to create the repository, replacing `localstack-lambda-container-image` with the desired name for your repository: @@ -89,8 +89,8 @@ $ awslocal ecr create-repository --repository-name localstack-lambda-container-i "repositoryArn": "arn:aws:ecr:us-east-1:000000000000:repository/localstack-lambda-container-image", "registryId": "000000000000", "repositoryName": "localstack-lambda-container-image", - "repositoryUri": "localhost:4510/localstack-lambda-container-image", - "createdAt": "", + "repositoryUri": "localhost.localstack.cloud:4510/localstack-lambda-container-image", + "createdAt": , "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": false @@ -122,12 +122,12 @@ $ awslocal ecr describe-images --repository-name localstack-lambda-container-ima { "registryId": "000000000000", "repositoryName": "localstack-lambda-container-image", - "imageDigest": "sha256:", + "imageDigest": "sha256:459fce12258ff1048925e0f4e7fb039d8b54111a8e3cca5db4acb434a9e8af37", "imageTags": [ "latest" ], - "imageSizeInBytes": 181885144, - "imagePushedAt": "", + "imageSizeInBytes": 184217147, + "imagePushedAt": , "imageManifestMediaType": "application/vnd.docker.distribution.manifest.v2+json", "artifactMediaType": "application/vnd.docker.container.image.v1+json" } @@ -139,7 +139,7 @@ By running this command, you can confirm that the image is now in the ECR reposi ## Deploying the Lambda function -To deploy the container image as a Lambda function, we'll create a new Lambda function using the `create-function` command. Run the following command to create the function: +To deploy the container image as a Lambda function, we will create a new Lambda function using the `create-function` command. Run the following command to create the function: {{< command >}} $ awslocal lambda create-function \ @@ -157,13 +157,13 @@ $ awslocal lambda create-function \ "Description": "", "Timeout": 3, "MemorySize": 128, - "LastModified": "2023-05-11T06:06:37.372826+0000", + "LastModified": , "CodeSha256": "9be73524cd5aa70fbcee3fc8d7aac4eb7e2a644e9ef2b13031719077a65c0031", "Version": "$LATEST", "TracingConfig": { "Mode": "PassThrough" }, - "RevisionId": "f953a7ea-4d92-4458-a46c-821c056fd33c", + "RevisionId": "cab4268c-2d56-4591-821a-9154e157b984", "State": "Pending", "StateReason": "The function is being created.", "StateReasonCode": "Creating", @@ -199,7 +199,7 @@ $ awslocal lambda invoke --function-name localstack-lambda-container-image /tmp/ } {{< / command >}} -The command above will execute the Lambda function locally within the LocalStack environment. The response will include the StatusCode, LogResult, and ExecutedVersion. You can find the logs of the Lambda invocation in the LocalStack container output, precisely when `DEBUG=1` is enabled. +The command above will execute the Lambda function locally within the LocalStack environment. The response will include the StatusCode and ExecutedVersion. You can find the logs of the Lambda invocation in the Lambda container output: {{< command >}} Hello from LocalStack Lambda container image!