Aws Lambda
Aws Lambda
Ausarbeitung
Im Rahmen des Master-Seminars
Distributed Systems
Zum Thema:
Vorgelegt von:
Loay Foda
Betreuer: Dr. Andreas Schönberger
1 Introduction 1
1.4.2 Drawbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3 Development 8
3.1 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4 Testing 13
5 Practical work 14
I
5.2.1 Node.js wrapping C++ program . . . . . . . . . . . . . . . . . . . . 16
6 Conclusion 18
References 19
List of Figures
II
1 Introduction
Traditionally when developing your web applications or API’s against the cloud. Develop-
ers might need to be involved with provisioning and managing the computing resources on
the servers. Serverless refers to a new generation of platform-as-a-service offerings where
the provider takes responsibility for receiving client requests and responding to them,
capacity planning, task scheduling and operational monitoring [4]. It is by no means an
indication that there are no servers, simply that the developer should leave most opera-
tional concerns such as resource provisioning, monitoring, maintenance, scalability, and
fault-tolerance to the cloud provider [5]. One realization of serverless computing is run-
ning services in stateless compute containers that are event-triggered, ephemeral and fully
managed by the provider which was firstly introduced by Amazon Lambda and called
Function-as-a-Service(FaaS) [6]. The other major cloud providers also have serverless
platforms, including Google Cloud Functions and Microsoft Azure Functions.
In the article Serverless Computation with OpenLambda [7] the authors show that we have
reached a new stage in the sharing model with FaaS, which is shown in figure 1. During the
initial phase of sharing evolution, virtualization allowed the sharing of common hardware.
In this scenario, despite the fact that multiple virtual machines could be running on a
single server, each one still runs a complete copy of an operating system. Containerization
developed resource-sharing further via OS-level virtualization. Containers hold the entire
components essential to host a specific software program and a minimal subset of an OS.
At this time management of underlying infrastructural components was still a burden,
despite the efficiencies and increased provisioning speeds introduced by virtualization and
containerization. Finally, Serverless computing offered a model of computing whereby
1
effectively all resources are pooled including hardware, operating systems and runtime
environments [3].
Compared to IaaS platforms, serverless computing has advantages. From the consumer
perspective, a cloud developer no more needs to oversee and deal with servers or VM’s.
Instead the focus is on the business logic, by defining a set of functions whose composition
enables the desired application behavior. The stateless programming model gives the
provider more control over the software stack, permitting them to more transparently
deliver security patches and optimize the platform [5].
There are, however, drawbacks to both customers and suppliers. For customers, the FaaS
model provided by the platform could also be too restrictive for a few applications. For
instance, the platform might not support the newest language version, or certain libraries
might not be out there. Moreover, developers no longer have full control over the OS
(including root access)thus, no ability to customize the execution environment according
to tailored needs[6]. For the supplier, there’s currently a requirement to manage issues
like the life cycle of the user’s functions, scalability and fault tolerance in an application-
agnostic manner. This additionally means that developers need to carefully understand
how the platform behaves and design the application around these capabilities.
2
1.3.3 Serverless computing vs. SaaS
FaaS and SaaS are truly unique things from a developer perspective. With SaaS the whole
application has to be build from the ground up, including infrastructure, error handling
and everything else[8]. While FaaS is much more modular, on the grounds that it just
uses functions that can be utilized independently or as a full back-end. So while SaaS
is more of full stack packages, consisting of back and front-end, FaaS is extra basic, and
may be used for the lower back-end of programs and to simply run functions. FaaS is thus
easier accessible than SaaS, especially when we consider that we do not have to write an
infrastructure for FaaS. We can state that FaaS and SaaS have diverse purposes, which
implies that FaaS won’t replace SaaS [9].
- Reduced operational cost : Only pay for the compute time that you actually use
during the execution of your function.
- Rapidly Scalable
1.4.2 Drawbacks
- Potentially high latency :Lambda automatically decides when to scale the number
of active instances up or down, so a new request might end up creating a completely
fresh instance. Application developers have no control over this process [4].
- Relatively short life-span : The maximum configurable time for a Lambda function
execution is currently five minutes. There is no way for application developers to
extend that limit, so each individual task needs to complete within that time frame
[4].
During the next subsections we will discuss the implementation details of AWS Lambda
with respect to waterfall model for software development cycle from figure 2
3
Figure 2: Waterfall Model Life Cycle.
Before starting designing your Lambda function, we have to make sure that AWS Lambda
will fulfill our application requirements. In order to analyze if AWS Lambda is a good fit
for our application or not, we should know how does it work and its limitations.
AWS Lambda is part of the Amazon Web Services. AWS provides an easy-to-manage
cloud platform to store digital assets, host servers and more. Amazon also has many set-
tings for security controls, including a firewall to block incoming and outgoing traffic, and
different identity and access management (IAM) accounts with varying levels of privileges
[10].
AWS Lambda is a service proposed by the Amazon Web Services platform. As shown in
figure 3, lambda permits you to upload code that will be run on an on-demand container
managed by Amazon. AWS Lambda will manage the provisioning and managing of servers
to run the code, thus all that’s required from the user may be a packaged collection of
code to run and some configuration choices to outline the context during which the server
4
runs [7]. These kinds of managed applications are known as Lambda functions. Those
functions can be invoked directly, via a HTTP call with AWS API gateway sitting at front
or can subscribe to events generated by other resources. An example for the latter option
would be a software agent or physical user, interacts with an AWS service that is able to
invoke a lambda function in response to the user’s action. This action could have involved
uploading an image to S3, making an API request, querying a database or any discrete
action on an AWS resource which can invoke lambda function. The details of the user
action upon the AWS resource is included in a JSON object and handed as a parameter
to a lambda function [11].
AWS Lambda employs the microservices concept at the core of the architecture. Generally,
the microservices architecture does not specify the number of services that may be hosted
within the same container. AWS Lambda can be regarded as a subset of the microservices
architecture because the architecture states there is no more than one service running in
the same container [12]. Hence, any communication between functions occur over a service
pipeline.
Figure 4 gives a more thorough view regarding how a Lambda functions work. Regardless
the invoking way, an event JSON representing the incoming request will be passed to the
function.The function could additionally then have interaction with a number of AWS
based or external services to process and/or respond to the incoming event. Once the
invoked function has finished processing the incoming request a response JSON is returned
to the end user[11].
5
Figure 4: How lambda works.
As shown in figure 5, Lambda function is created from resources deployed through S3. The
Serverless Framework project contains all code elements of the invoked Lambda function.
Cold start up time on a new worker in lambda cluster is somewhere between one and
two seconds[13]. During the initial time a function executes once being created or having
its code or resource configuration updated, the handler is started in a container, which
can only be used by the handler itself. Even though multiple containers run within the
same run-time, communication between containers is not possible.Other functions would
then be able to intercept your functions and gain access to valuable data. As of fall 2017,
containers are provided with 2 hyperthreads backed by the Intel Intel(R) Xeon(R) CPU
E5-2666 v3 @ 2.90GHz [14]. Although it is not stated in the lambda documentation,
experiments have shown that calls targeting the same function within a small period of
time are sent to the same container to avoid sandbox startup latency [13]. It is one way
used to optimize lambda performance, as resuming a paused container is over 100x faster
than starting a new container[13]. Lambda architecture guarantees workers do not over-
provision by expecting that each function will consume the maximum function memory
size[15]. Then, when a worker service receives an execution request for another function,
it reclaims memory if the assigned function requires less than the maximum size. Lambda
reacts to load bursts by starting a Lambda handler on a new worker to service a queued
call without incurring latencies[16]. As there is no guarantee that a subsequent call will
hit the same container instance as the previous one, lambda functions must essentially be
stateless.
6
Figure 5: Detailed view of web application architecture implemented with AWS cloud
events.
There are some Resources and deployment Limits that should be taken into consideration
before deciding to use Lambda or not [17].
- CPU speed is determined by amount of ram chosen : there is no fixed guarantee for
CPU power. AWS Lambda allocates CPU power proportional to the memory.
- Maximum size of uploaded jar or zip file for an AWS Lambda function 50 MB
- Scheduled Events.
- API Endpoints.
7
2.0.5 AWS Programming model
As the first step of designing our lambda function, we have to choose one of the supported
languages by AWS Lambda, which are[18].:
- C#.
- Node js.
- Java.
- Python.
Instantly, AWS Lambda limits the total concurrent executions across all functions within
a given region to 1000.During the design phase we will have to evaluate if that is enough
load or an explicit request to increase that number should be done to the customer support
team.
3 Development
In order to have a running lambda function, we will have to implement the function logic,
deploy it the AWS Lambda and after that decide how to invoke our lambda function.
3.1 Implementation
Regardless of the language you choose, there is a common pattern to writing code for a
Lambda function that includes the following core concepts:
Function Handler is the access point to begin execution of the lambda function. As
indicated by the Lambda programming model, each function unit has a concrete stateless
class with a method handler which is triggered when the function is invoked [19]. It takes
input data as first parameter and lambda context as second parameter.
Upon invocation, handler initializes the invocation credentials, creates an input object to
save the instance state in addition to any method parameters, initializes the Lambda
invoker together with the created input object serialized to JSON, calls the method
(Class.handleRequest(input, output, context)), fetches the end result from the deseri-
alized output object and refreshes the instance state using the outcome object[19].
8
Unless your function input and output parameters are of type System.IO.Stream, you
should serialize them. AWS Lambda presents a default serializer that can be implemented
on the assembly or method level of your application. Otherwise you will outline your own
by implementing the ILambdaSerializer interface provided by the Amazon.Lambda.Core
library.
Context object is passed as second parameter to handler. The context object provides
details about the function itself and ways to terminate its execution, either successfully
or with an error. Besides its properties that provide information about the function and
its current execution, you can also call methods on the context object. These are helpful
for managing the closure of the function’s execution. The following methods deal with
exiting a Lambda function: [20].
- context.succeed() : Indicates that the function has completed successfully. You may
optionally pass an object or string as a parameter which can be used by the calling
event
- context.fail() : Indicates that the function has failed during execution. In some cases,
this is used to requeue the function. For example, if a function fails in response to
an S3 event, AWS will attempt to rerun the Lambda function two more times before
giving up. Again, you can pass an optional parameter to context.fail containing the
reason for the failure
- context.done() : This method simulates both the “succeed” and “fail” methods in
traditional Node.js callback style. You can call context.done(err, data) where err is
an optional error message (or null) and data is an optional success object
A properly designed function ought to have suitable logging system. AWS Lambda com-
poses all logs to Cloud Watch, which could be utilized for further investigation if required.
There are three ways to write logs in AWS function :
After your function executes, its logs will show up in CloudWatch within a couple of
minutes. Each Lambda function creates a separate log group. Within the group, each
execution instance creates a new stream. The actual logs are then added to the streams.
9
Do not confuse a stream with an individual execution of a Lambda function; oftentimes
the same function will execute multiple times on the same underlying instance. Each
underlying instance writes to its own stream, which may result in several executions
being written to the same stream [20].
Lambda has its own error handling mechanism by sending serialized exemption data
as the payload as a JSON object, However developers are able to raise a special case
specifically from your Lambda function and handle it straight forwardly within an AWS
Step Functions State Machine.
Till now we discussed the technical implementation of the lambda function. Now we have
to proceed with some configurations to be able to deploy our function.
Firstly, in order to use Amazon web services, we should have AWS account. Services in
AWS, such as AWS Lambda, requires that you give certifications upon using it, with the
goal that the service can decide if you have authorizations to get to the resources possessed
by that service. it is not recommended that you just access AWS using the credentials for
your AWS account, instead produce a brand new IAM user with permissions required.
Secondly, we have to create an IAM Role to be used within the lambda function. Different
lambda functions can be associated to the same IAM Role, but it is mandatory to relate
each function with a role .You specify the IAM role after you produce your Lambda
function. Permissions you grant to the current role confirm what AWS Lambda will
do once it assumes the role. Permissions are granted through attaching policies to the
execution role giving the lambda function access to other AWS resources.
Figure[4] here shows an execution role with the name lambda execute that have 4 attached
policies. AWSLambdaBasicExecution allows lambda function to access Cloudwatch to
10
write logs, AmazonAPIGatewayInvokeFullAccess allows lambda function to be invoked
through an API gateway and INVOKE which allows the lambda function to be invoked
using the AWS SDK.
After finishing the configurations that will be used by our lambda function, we can deploy
our lambda function to AWS. AWS Lambda demands a deployment artifact to be self-
contained which means all resources and dependencies have to be packaged into a single
zip file, and this file could not be larger than AWS Lambda’s allowable limit [12]. There
are multiple ways to deploy lambda function, but we will talk about only two of them :
AWS web To deploy our function through AWS web, we have to fill in 3 sections [18] .
Basic Information where we specify the lambda function name, a description for our
lambda function for ourselves and the run time(which in our case will be c#)
Lambda function code To create the deployment package, open a command prompt
and navigate to the folder that contains your .csproj file and run the following commands
[18]:
- Dotnet restore : will restore any references or dependencies of the project that may
have changed during the development process.
- Dotnet publish : compiles the application and packages the source code and any
dependencies into a folder. The output of the command window will instruct you
where the folder was created.
Lambda function handler and role where you should specify your handler and ex-
ecution role. The Handler name is the most tricky part because you have to fully specify
the assembly name, the name space and class name and the method name of the lambda
to execute. It takes the following form:
- Assembly::Namespace.ClassName::MethodName.
Optional Configurations there are some optional configurations which can be cus-
tomized according to the application requirements
- Timeout : Maximum interval before you function times out if request is not pro-
cessed yet.
11
- Memory : The allocated memory of your function is how much memory you want to
allow your function to consume. It does not mean that every function execution will
utilize all of the available memory, but it does allow the function to use up to that
amount. Memory is allocated in increments of 128 MB, up to a maximum of 1536
MB. Lambda allocates CPU power and other resources proportional to memory. For
example, reserving 256MB of memory allocates approximately twice as much CPU
power to a Lambda function as requesting 128MB of memory, and half as much
CPU power as choosing 512MB of memory[14].
- VPC : If we want to run the function inside a specific VPC or not.
AWS CLI : This is the easiest way to start your development and deployment of AWS
Lambda. A newly released NuGet package named Amazon.Lambda.Templates that wraps
up all the templates exposed in Visual Studio as project types we can create from the
dotnet CLI.
During Deployment of the function, we can use versions to label each deployment. This
is extra beneficial if a big team of developers is working on the same lambda function.
We can publish multiple versions. Every time we tend to publish a version, AWS Lambda
copies $LATEST version (code and configuration information) to form a replacement
version. When we publish additional versions, AWS Lambda allocates a monotonically
expanding arrangement number for forming, regardless of the possibility that the function
was erased and re-created. Version numbers are by no means reused, even for a function
that has been deleted and re-created, so that the consumer can rely upon the executable
of that version to never alternate.
Moreover, we can create aliases for our Lambda function during the deployment. An AWS
Lambda alias is like a pointer to a specific Lambda function version. Aliases transparent
promotion of new versions of Lambda functions and rolls back when needed.
After Deploying our Function, It is ready to be invoked through the following three options
:
12
Another aspect should be understood before starting invoking lambda functions, is how
functions react to failures.
Asynchronous invocation In this case, the retries are built in and run automatically.
The invocation will be retried twice with delays in the middle. On the off chance that
it fails on both retries the event is discarded. With asynchronous invocations, you are
”
able to set up a Dead Letter Queue which can be used to hold the failed event from being
discarded. The Dead Letter Queue enables you to send unprocessed events to an Amazon
SQS or SNS queue for you to build logic to deal with.
4 Testing
While the Serverless Architecture introduces a lot of simplicity when it comes to serving
business logic, some of its characteristics present challenges for testing. They are:
To get past these difficulties, application business logic must be loosely coupled to the
FaaS provider, in order to make it reusable and more easily testable and more importantly
provider independent. When your business logic is written separately from the FaaS
provider, you can compose unit and Integration tests to guarantee logic operating properly
and integrations with other services are working correctly.
- Invoking Lambda Function Manually : After deploying our function, we will be able
to test it manually using the web UI. Within the console, click on your Lambda
function and then select ”Configure test event” from the ”Actions” drop-down menu.
In this window, you will be able to either work from a template provided by AWS
or configure your own JSON body to send as an event[20]
13
- Event driven invoking using AWS CLI) : Firstly create a S3 sample event data in
a file and save it. After that, use the AWS CLI Invoke command to simulate an s3
event driven call to your lambda function.
- Third party testing libraries : a couple of third libraries were developed to make
testing easier on lambda such as node-lambda and lambda-local
5 Practical work
During this section we will work through practical work to create a new C# lambda
function and how to use this function to wrap a C++ application.
we will use the dotnet CLI for creating a new lambda project with all its dependencies
needed.
Figure 7: Handler function used to take string input and uppercase it.
14
Figure 8: .Csproj of the created project showing dependencies for Lambda.
After creating the project, we have to restore it to download all dependencies specified
in the .csproj. Finally we will use Dotnet CLI to Deploy this function to AWS using our
default profile and pre existing IAM role which enables the lambda function to write logs
to cloudwatch. We will be using the Amazon web to test our application. As shown in
figure 7 the lambda function works fine returning back the input string to upper case.
Moreover, it shows the log output lambda function.
As mentioned before lambda supports only 4 languages, but what if we have a legacy
application written in another language that is not supported by lambda and we still
want to benefit from the advantages of AWS Lambda. In this section, we will focus on
how to wrap a legacy C++ application using Node.js and C# functions.
15
5.2.1 Node.js wrapping C++ program
In the Node.js world, the way we typically integrate C++ with JavaScript is through
addons. Node.js C++ addons are compiled (native) Node.js modules which are directly
callable from JavaScript as any other Node.js module.
The biggest issue is that AWS Lambda isn’t going to invoke node-gyp or any other build
tool you need might need before launching your function - you are responsible for creating
the full binary package.
Let’s move on with a very simple example to wrap C++ code with node.js. We should
go to the AWS web and create a nodeJs 4.3 blank function and paste in this code:
’use strict’;
After the function is created, we can set up a test event that contains:
{
”cmd”: ”ls -al /”
}
As shown in Figure 8, testing this function results in stdout from the ls -al command.
16
5.2.2 C# wrapping C++ program
The previous approach gives only single point of entry to the C++ code. This may lead
to extra overhead reorganizing your C++ program to fit in with that issue.
In this situation, C# comes to the rescue, giving us the option to just wrap the whole
program and use it within our c# code as we wish.
In order to create a working function wrapping the C++ program, there are some require-
ments needed to be achieved at first
exposing desired functions in C++ we have to expose the functions that are needed
to be called from the c# code. It could be done as simply as
The above sample shows an exposed function that takes input two integers and returns
back the sum of these integers.
Compiling the C++ application we have to compile the application against the
same operating system that runs on Lambda. Lambda runs on Amazon Linux. Code
must not be compiled on any other operating system as there is a lot of inconsistency
between shared library versions and locations. This can be achieved by launching a new
instance of EC2, downloading the needed packages and compiling your code on it getting
our desired shared libraries to be included.
Creating our c# lambda function we will start by creating our normal lambda
function, then we will be using P/Invoke which makes it possible to call uninitialized
functions implemented in native Dynamic Link libraries from the CLR in a very simple
way. This can be done as simply as adding the following piece of code in your class.
After that we can use the function as a localfunction declared inside our class.
The last step before deploying our lambda function, is to make sure that the shared library
is available to the lambda runtime environment. So we should pack it in the deployment
package that is uploaded to AWS lambda. It can simply be done by adding the following
couple of lines inside our .csproj
<ItemGroup>
<Content Include=”Shared-library”>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
17
Finally, we are ready to use the dotnet CLI to deploy our lambda function and test it.
6 Conclusion
A study has compared the cost, performance and response time of different implementa-
tion architectures such as monolithic architecture, microservice architecture operated by
the cloud customer and microservice operated by AWS Lambda. With the microservice
architecture a developer will try to develop an application as a suite of small services
[2], which all run their own process. The results of this study show that a microservice
operated by AWS Lambda is up to 77.08 percent cheaper per million requests than the
other two methods, while the response times are faster than the cloud customer operated
microservice architecture and about the same as the monolithic architecture [7].
Of course, not all workloads are well suited to Lambda, which means that an upfront
evaluatory step is required for each new application or application component. AWS
Lambda functions can be used in response to events and automatically manages the
computing resources for you, making it easy to build applications that respond quickly
to new information.AWS Lambda starts running your code within milliseconds. You
can also use AWS Lambda to create new back-end services where compute resources are
automatically triggered based on custom requests.The idea behind lambda comes down
to prevent deploying monolithic applications as Lambda functions, and serve stateless
microservices as a collection of functions instead. On the other hand, a user will have
to recognize some places where performance issues can arise. The readiness latency, the
time it takes to start, restart or unpause a container, can have consequences for the overall
performance [7]. And there are more like the number of containers per memory, which
may lead to extra overhead on the developers to keep on mind on the difference between
cold and hot starts of lambda functions.
Security is one amongst the reasons why you implement backside logic for an application,
and you must always validate the authentication and authorization of end users accessing
your back end. the safety of AWS Lambda lays completely in your own hands. A user
must add policies explicitly to roles like invoking a Lambda function or adding a rule to
”
CloudWatch. For example, a function can read from only a specific path of a file share,
and write in a certain database table. This framework is based on AWS Identity and
Access Management policies and roles. In this way, taking care of the safety needed to
execute the code is less complicated and and turns out to be a piece of the development
procedure itself. You can tailor security permissions specifically for each function.
All in all, AWS Lambda - and the serverless computing model in general - is a game-
changer. This is in terms of both efficiency and scale, both of which eventually equate to
cost, the ability to provision near-infinitely scalable services, on-demand and with sub-
second billing granularity provides the best possible value to consumers.
18
References
[1] D. T. Wagner, “Serverless design patterns with aws lambda,” Tech. Rep., April 11,
2016.
[8] C. Höfer and G. Karagiannis, “Cloud computing services: taxonomy and comparison,”
vol. 2, no. 2, pp. 81–94, 6 2011, open Access.
[10] D. K. Dan Amiga, “Account jumping post infection persistency & lateral movement
in aws.”
19
[14] S. C. L. L. S. P. Wes Lloyd, Shruti Ramesh, “Serverless computing: An investigation
of factors influencing microservice performance,” 2017. [Online]. Available:
http://faculty.washington.edu/wlloyd/papers/ic2e 2018 accepted prerevisions.pdf
[19] J. Spillner and S. Dorodko, “Java code analysis and transformation into
AWS lambda functions,” CoRR, vol. abs/1702.05510, 2017. [Online]. Available:
http://arxiv.org/abs/1702.05510
[20] M. Fuller, aws lambda: a guide to serverless microservices. Matthew Fuller, 2017.
20