The A-Z of AWS Lambda: Unwinding Execution Environment, Configurations, Layers & Function URLs
Table of contents
In this blog, we will embark on a journey to explore the intricacies of AWS Lambda, diving deep into its execution environment, configuration options, the power of Lambda Layers, and the significance of Lambda Function URLs with practical implementation and this guide aims to demystify the core concepts and empower you to harness the full potential of AWS Lambda.
Please refer to my previous detailed blog - Mastering Serverless with AWS Lambda which covers serverless architectures and AWS provides an offering to manage serverless architectures. That blog contains details regarding serverless computing in AWS, understanding AWS Lambda's invocation models, permissions, creating and authoring a lambda function with python boto3 and seamless integrations with native services culminated with a detailed breakdown of a serverless architecture diagram, showcasing the interconnected components that power modern, event-driven applications.
AWS Lambda Execution Environment
Understanding the AWS Lambda execution environment is crucial for optimizing the performance of your serverless functions, especially when dealing with the concepts of cold starts and warm starts.
When a Lambda function is invoked, AWS creates an execution environment for that function. The execution environment includes the runtime, dependencies, and function code.
Key aspects in Lambda Execution Environment:
Containerization:
AWS Lambda uses containerization to manage the execution environment. Your function code runs in a lightweight, stateless container.
The container provides an isolated environment for your code, ensuring that it doesn't interfere with other functions.
Runtimes:
Lambda supports multiple runtimes like Node.js, Python, Java, Go, and more. The runtime you choose dictates the environment your code runs in.
AWS maintains and updates runtimes to patch security vulnerabilities and provide new features.
File System:
- Each Lambda function receives 512 MB of /tmp space in the execution environment. This space is ephemeral, meaning it is discarded after the function execution completes.
Initialization and Configuration:
AWS Lambda initializes the execution environment when a function is invoked or a new container needs to be created.
Initialization involves setting up the runtime, loading dependencies, and preparing the environment for your function code.
Warm Starts (Reuse of Execution Environment):
To optimize performance and reduce startup latency, AWS Lambda attempts to reuse execution environments. Warm starts happen when AWS reuses an existing execution environment for a function that has been invoked recently.
If the same function is invoked again shortly after the previous invocation, AWS may reuse the existing container (warm start) instead of creating a new one (cold start), and these are faster than cold starts since the container is already initialized.
Cold Starts:
Cold starts occur when a function is invoked and AWS needs to create a new execution environment.
Factors influencing cold starts include the runtime, size of the deployment package, and the initialization logic of your function.
Cold starts typically result in higher latency for the first invocation of a function.
Phases of Cold and Warm Start while Lambda Function Execution
Cold Start:
Phases:
Extension Init: Initialize extensions (external modules) if present, which can augment the behavior of lambda runtime.
Runtime Init: Set up the Lambda runtime environment which involves preparing the runtime environment, loading language-specific libraries, and setting up the execution context.
Function Init: Execute the function's initialization code which includes loading dependencies, establishing connections, or performing any setup required for the function's execution.
Invoke (Cold Start): If the function code is invoked for the first time or if the existing container is deemed unsuitable for reuse, then a new container is created for the function execution which leads to a cold start.
Runtime Shutdown: Shutdown the runtime environment after the function execution is completed and resources allocated during function execution are released.
Extension Shutdown: If extensions (external modules) are present, they go through shutdown to perform cleanup operations before the execution environment is completely shutdown.
Warm Start:
Phases:
Extension Init: Initialize extensions (external modules) if present and this initialization might be faster than during the cold start as some state might be cached or reused.
Runtime Init: If the container is being reused (warm start), this phase might be faster than during a cold start as the runtime environment is already set up.
Function Init: Execute the function's initialization code. Since the container is being reused, this phase might be faster than during a cold start.
Invoke (Warm Start): The function code is invoked again within a short period after the previous invocation. AWS Lambda attempts to reuse the existing container, leading to a faster warm start compared to a cold start.
Runtime Shutdown: Shutdown the runtime environment and any resources allocated for the runtime are released.
Extension Shutdown: If extensions (external modules) are present, they go through shutdown to perform cleanup operations before the execution environment is completely shutdown.
How Cold and Warm Starts Impact Performance:
Cold Start Latency:
Cold starts can introduce higher latency for the first invocation of a function.
Factors influencing cold start latency include the choice of runtime and the time it takes to initialize the environment.
Warm Start Performance:
Subsequent invocations of a function within a short period benefit from the reuse of warm execution environments.
Warm starts offer lower latency compared to cold starts.
Strategies to Mitigate Cold Starts:
Keep Functions Warm:
Periodically invoke your functions to keep the execution environments warm.
Use scheduled CloudWatch Events or external tools to ping your functions.
Optimize Initialization:
Minimize initialization logic and optimize the function code to reduce cold start times.
Opt for lightweight runtimes when applicable.
Use Provisioned Concurrency:
AWS Lambda allows you to provision concurrency to keep a specific number of execution environments warm.
Provisioned concurrency helps ensure consistent performance.
Lambda Function Configurations
If you want to know more on Lambda Function, Please refer Mastering Serverless with AWS Lambda, which explains all component associated with Lambda Function in detail.
There are several things that we need to be aware of while creating or authoring your lambda function as per requirement.
General configuration –
Memory - Lambda allocates CPU power in proportion to the amount of memory configured.
Timeout - Lambda runs your code for a set amount of time before timing out. Timeout is the maximum amount of time in seconds that a Lambda function can run.
Ephemeral storage - By default, Lambda allocates 512 MB for a function’s /tmp directory. You can increase or decrease this amount using the Ephemeral storage (MB) setting. To configure the size of a function’s /tmp directory, set a whole number value between 512 MB and 10,240 MB, in 1-MB increments.
SnapStart - Lambda SnapStart is a performance optimization that helps reduce startup latency at no additional cost.
Triggers - These are AWS services or resources that invoke the function. Most services invoke your function directly with an event structure that is specific per service. For some services, AWS Lambda reads service data and invokes the function with a resource called an event source mapping. An event source mapping is a Lambda resource that reads from an event source and invokes a Lambda function.
Destinations - This is a powerful feature introduced by AWS to route the results of asynchronous Lambda function invocations to various AWS services. Essentially, it allows you to say "When my Lambda finishes its job, I want it to send the results to these specific places." This opens up a new level of flexibility and simplifies event-driven architectures.
Permissions – Configure the execution role and resource-based policies (if required).
Environment variables – Key-value pairs that Lambda sets in the execution environment.
Function URLs – These are unique, HTTPS-based endpoints that provide direct access to your Lambda functions from the internet. They act as gateways, enabling you to invoke your functions without relying on other AWS services like API Gateway, etc. You can configure a function URL on the
$LATEST
unpublished function version, or any function alias.Tags – Key-value pairs that Lambda attaches to your function resource. we can use tags to organize Lambda functions into groups for cost reporting and filtering in the Lambda console. Tags apply to the entire function, including all versions and aliases.
Virtual Private Cloud (VPC) – If your function needs network access to resources that are not available over the internet.
Monitoring and operational tools –
Logging Configurations - Lambda integrates with Amazon CloudWatch and CloudWatch Logs to help you monitor, trace, and debug your Lambda functions.
Additional monitoring tools - Lambda integrates with other AWS services to help you monitor, trace, and debug your Lambda functions like X-Ray, CloudWatch Lambda Insights, and Amazon CodeGuru Profiler.
Concurrency – This refers to the maximum number of Lambda functions allowed to execute simultaneously for your account or specific region. It acts as a guardrail to prevent overwhelming resources and ensures fair resource allocation across users.
Think of it like having a limited number of lanes on a highway. Each lane represents a running Lambda function, and concurrency defines how many lanes you have access to. Exceeding your concurrency limit results in throttling, meaning your new function invocations wait in line until another finish.
Asynchronous Invocation - In AWS Lambda, this refers to the process where you invoke a Lambda function and immediately receive a response without waiting for the function to complete its execution.
When you invoke your function asynchronously, AWS Lambda handles retries. Incoming events are placed in a queue before being sent to the function. If the function returns an error, Lambda retries up to 2 times. If the function is throttled, or Lambda returns an error, the event is kept in the queue for up to 6 hours. To change the default retry behavior, adjust the number of retry attempts and the maximum amount of time an item can be kept in the queue.
When an event fails all attempts or stays in the asynchronous invocation queue for too long, Lambda discards it. Configure a Dead-Letter Queue (DLQ) to send discarded events to an Amazon SQS queue or Amazon SNS topic. Your function's execution role requires permission to write to the queue or topic.
This is useful when you want to decouple the components of your application, making them more resilient and scalable.
Code Signing Configurations - This helps to ensure that only trusted code runs in your Lambda functions. When you enable code signing for a function, Lambda checks every code deployment and verifies that the code package is signed by a trusted source.
RDS Databases - You can connect a Lambda function to an Amazon Relational Database Service (Amazon RDS) database directly and through an Amazon RDS Proxy. Direct connections are useful in simple scenarios, and proxies are recommended for production. check AWS Lambda with Amazon RDS for more information.
File Systems - You can configure a function to mount an Amazon Elastic File System (Amazon EFS) file system to a local directory. With Amazon EFS, your function code can access and modify shared resources safely and at high concurrency. check Configuring file system access for Lambda functions for more details.
State Machines - This lists the state machines with at least one workflow step that invokes the current Lambda function.
Lambda Layers
AWS Lambda layers allow the lambda functions to import additional code or data without including that additional code in the deployment package. AWS Lambda Layers provide a way to manage and share common code and libraries across multiple Lambda functions.
A layer is a zip file that contains all the additional code. A layer can contain some third-party libraries, custom runtimes, or data, and you can refer to that layer from any lambda function.
This can be better understood using the below diagram provided by AWS in their AWS documentation.
Let's create and add a Lambda Layer to the lambda function with proper implementation.
Here, we are creating a raw lambda function and importing request modules within it.
import json import requests def lambda_handler(event, context): return { 'statusCode': 200, 'body': json.dumps('Hello World') }
When running this lambda function, we are getting an import module error as this module is not in an AWS execution environment like JSON rather it is an external module that we need to add in our configurations using Lambda Layers.
Let's start creating a lambda layer process, firstly in our local system, we need to install the requests module using the below command and then later zip that folder as we need to upload that while creating a layer in the next step.
pip3 install requests -t .
Now, let's create a Layer and this process includes uploading the zip archive which contains the files generated as per the request module which can be seen in the above step.
We have created a lambda layer in the above step, now we will add a respective layer to our lambda function.
Let's run the lambda function again, and this time we should not see the import error that we have encountered in the second step while running the lambda the first time because we now have the layer included in our lambda function.
Lambda Function URLs
A function URL is a dedicated HTTP(S) endpoint for your Lambda function. You can create and configure a function URL through the Lambda console or the Lambda API. When you create a function URL, Lambda automatically generates a unique URL endpoint for you. Once you create a function URL, its URL endpoint never changes.
Lambda function URLs use resource-based policies for security and access control. Function URLs also support cross-origin resource sharing (CORS) configuration options.
You can apply function URLs to any function alias, or the $LATEST
unpublished function version.
Function URL endpoints have the following format:
https://<url-id>.lambda-url.<region>.on.aws
Let's configure the Lambda Function URL with proper implementation.
Here, we are creating a basic Lambda Function and this can be based on the requirement.
import json def lambda_handler(event, context): # TODO implement return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
Now, let's configure a Lambda Function URL and we can find this option in Lambda function configurations sections.
In Auth Type, we have 2 options to choose from - AWS_IAM or NONE.
AWS_IAM
- Lambda uses AWS Identity and Access Management (IAM) to authenticate and authorize requests based on the IAM principal's identity policy and the function's resource-based policy.NONE
- Here, Lambda doesn't perform any authentication before invoking your function and this option allows public, unauthenticated access to your function URL, and that's why we are going with this option for now.We have successfully created the Lambda Function URL as seen below.
Now after hitting the Lambda Function URL in the browser, we will get the same response that we have returned from your function and this is dynamic and works in real-time, which means as soon as we update the lambda function code, we will get the updated response in the browser as well.
References:
AWS Lambda Execution Environment
AWS Lambda Function Configurations
Conclusion
As we conclude our exploration, With Lambda, serverless computing is no longer a futuristic fantasy. It's tangible, powerful, and readily accessible. we have delved into the heart of AWS Lambda, unraveling the layers that define its execution environment, understanding the flexibility granted by various configurations, leveraging the reusability of Lambda Layers, and appreciating the accessibility provided by Lambda Function URLs. Remember, serverless isn't just a trend – it's a paradigm shift, and Lambda is its pioneering champion. Embrace the future, embrace Lambda!
Thank you so much for reading my blog! 😊 I hope you found it helpful and informative. If you did, please 👍 give it a like and 💌 subscribe to my newsletter for more of this type of content. 💌
I'm always looking for ways to improve my blog, so please feel free to leave me a comment or suggestion. 💬
Thanks again for your support!
Connect with me -
#aws #awscommunity #cloudcomputing #cloud