In our previous Insight articles we talked about some of the AWS Lambda best practices, hidden challenges, and misconceptions of Serverless development. A key observation is that Serverless is about the code that we don’t create as much as it is about the code that we do create. Leveraging platform services as much as possible to reduce code debt should be a major focus of any Serverless initiative.
However, we are not in a code free world just yet so this article will dive a little deeper into the scenario when custom code is required and it will explore some best practices for using AWS Lambda. There are many development design decisions that go into correctly developing an application that is suitable in terms of general use case, technologies used, and ability for the application to meet the actual business needs set forth. Development and coding decisions and best practices are a large part of successful, effective, and efficient development for ISVs developing applications for various customers and use cases. The right technologies and coding design must be implemented from the outset to ensure the needs of the ISVs customers are met from the outset.
Amazon AWS provides ISVs and others with a tremendous number of platform services and offerings that provide powerful functionality for both infrastructure and application design. Amazon offers platform services in the areas of machine learning, AR & VR, Blockchain, IoT, media services, mobile and many other solutions. One such offering that plays a major role in the way in which architects and developers approach building modern applications is Amazon AWS Lambda.
AWS Lambda is a powerful Serverless offering that allows developers to abstract code away from the underlying infrastructure. In addition to Amazon’s other platform services, Lambda allows developers and ISVs in general the ability to architect robust application solutions quickly and effectively with very agile function code. As with any technology, there are best practices to keep in mind when making use of AWS Lambda. In this post, we will take a look at the top AWS Lambda Serverless coding development best practices and how ISVs developing applications for customers can successfully and effectively make use of AWS Lambda Serverless solutions in code.<.br>
The explosion of new cloud technologies, solutions, and available coding and infrastructure solutions such as AWS Lambda are certainly driving changes in the way we design and develop applications. The use of cloud services represents a paradigm shift in the way application development and infrastructure problems are solved. The numerous AWS development and infrastructure services and offerings have allowed both operations and application developers to harness the power of the cloud in various ways. The shift from simply on-premises requirements and resources to applications that scale, interact, and operate in hybrid environments is apparent in the needs of today’s modern applications. This requires that developers think outside of the traditional boundaries of on-premises environments and make use of cloud-hosted platform services, including such technologies as Amazon AWS Lambda and others.
Serverless solutions such as AWS Lambda allow ISVs and others to make use of coding technology without having to worry about the underlying infrastructure as this is abstracted from the customer by the cloud vendor. Serverless provides many tremendous benefits to today’s modern application development. When making use of AWS Lambda Serverless technology, there are certain AWS Lambda coding development best practices developers need to keep in mind to ensure successful application development involving AWS Lambda Serverless solutions. What AWS Lambda Serverless coding best practices do developers need to consider when developing today’s applications?
As mentioned, coding development best practices are an extremely important part of effectively architecting, designing, and actually coding modern applications for ISVs and others. Making use of cloud services such as Serverless technology requires that developers are aware of how best to use it effectively in application design. Let’s briefly take a look at the following top AWS Serverless coding development best practices.
The first coding best practice related to Serverless technology is to not use Serverless technology if there is another ready-made solution that can solve the application functionality needed. There is no need to “reinvent the wheel” and develop custom code simply for the purpose of running Serverless functions in the cloud if there is no need to do this. The cloud platform services ecosystem is extremely broad with ready-made platform services generally easy to find that solve many development use cases.
As an example, there are many ready-made solutions available in the Amazon ecosystem including available services for machine learning, media transcoding, data transformation, text-to-speech, and many others.
ISVs should first look at solving application development problems with these preexisting ready-made services found in platform services offerings if applicable. Finding solutions in these prebuilt services first, if possible, helps to reduce code debt, and helps to increase operational efficiencies. It also offsets the burden of troubleshooting and tweaking custom code and shifts this operational burden and responsibility to the cloud provider.
What is Serverless cold start time? When a Serverless function is executed for the first time or the AWS inactivity timer of the function code runtime container is reached, the “cold start” behavior is experienced. The inactivity timeout for AWS Lambda function code is 900 seconds (15 minutes). In a technical sense AWS instantiates and provisions the runtime container for the Serverless function, code is downloaded to get ready to run the function, and then the function code is executed. After execution, if the function runtime container stays inactive for the specified period of time, the runtime container is destroyed and the next time the function code is called, the cold start behavior will be seen. As you can imagine, this first instantiation of function code in the Serverless environment will have a considerable impact on performance.
Developers interacting with the AWS Lambda environment need to be aware of this behavior, inactive runtime values, and how this process works. If this cold start behavior cannot be tolerated, there are ways the runtime container can be kept alive to keep from undergoing the cold start time when instantiating the runtime container. This is accomplished explicitly in code to negate the impact of the cold start time. The coding techniques will vary depending on the language utilized, however, it is worth noting this can be achieved. When considering Serverless coding development best practices, this behavior must be kept in mind when using Serverless in modern application design.
Functions-as-a-Service or FaaS running in Serverless architecture are ephemeral in nature. Ephemeral means it is built and destroyed all in the same lifecycle, without persistence. A new run of the FaaS architecture has no knowledge of the previous container runtime environment. Traditional applications are typically developed with state information in mind, meaning there is some persistence to preceding events or user information. However, today’s developers making use of Serverless runtime containers running FaaS code must develop applications with Serverless in mind that are stateless.
Application architecture is vastly different when developing stateless applications. There are ways to get around the limitations of the stateless nature of functions code running inside of Serverless architecture, however, it requires that state information is persistently recorded in some type of persistent storage and accessed in this way. This means developers must take this limitation/change into account when developing applications and either develop fully stateless applications, or handle state differently that with traditional applications.
One of the challenges that developers coming from traditional application development environments face when beginning to interact with Serverless technology is understanding Serverless tools and utilities available to interact with Serverless technologies such as AWS Lambda. Even though Serverless is relatively new, there are various third-party tools as well as native Amazon tools that have been introduced to interact with the AWS Lambda Serverless environment.
One such solution is the AWS Toolkit for Visual Studio. This is an extension for Microsoft Visual Studio running on Microsoft Windows that makes it easier for developers to develop, debug, and deploy .NET applications using AWS platform services and offerings. This allows developers coming from more traditional environments to be able to make use of familiar tooling and at the same time gain powerful IDE capabilities for AWS solutions such as Lambda. Using the AWS Toolkit for Visual Studio, developers are able to create Serverless applications with minimal effort. In addition to tools such as the AWS Toolkit for Visual Studio, there are web-based IDEs, CI/CD pipelines on AWS, custom build solutions using AWS CLI, and others.
Another challenge arises when making use of multiple AWS Lambda functions in application design. Multiple functions called by an application must be coordinated and orchestrated to form an effective workflow. AWS Step Functions is a serverless orchestration service that lets you easily coordinate multiple Lambda functions into flexible workflows that are easy to debug and change. Step Functions helps to streamline code and reduce additional code logic by keeping track of each step of the application and triggering functions automatically. There are other tools available that help to “glue” up Serverless function code and allow developers to much more effectively make use of multiple Lambda functions in Serverless development.
Understanding the available Serverless tooling and being able to effectively use these when interacting with Serverless technologies such as AWS Lambda is an essential AWS Lambda Serverless coding best practice.
When making use of cloud solutions, cost is generally associated with the amount of resources used in a specific period of time. So, cost is linear with usage. When designing and making use of AWS Lambda functions, both the execution time and the memory usage must be considered as these can impact both cost as well as performance. From a cost perspective, you don’t want function code to hang or execute continuously if not needed since this will drive up usage costs considerably. Lambda allows limiting maximum function execution time to prevent runaway or hanging function code from inadvertently driving up costs.
Developers also need to take Serverless function memory sizing into consideration. Function code memory needs to be sized appropriately and efficiently. The maximum memory size configures the maximum memory a function can consume, but also affects the CPU shares that are allocated when the function code is executed. Memory sizing needs to be thought through and configured carefully for function code as developers want to strike a balance between efficiency for cost-effectiveness and right-sizing for performance.
There can be a tendency when beginning to utilize AWS Lambda Serverless functions in application development to use separate function code for each individual action that is called from an application. However, this can lead to a management nightmare from an operations perspective. One of the AWS Lambda coding development best practices is to combine relevant Lambda function code where possible so that individual actions handled by relevant functions are combined. This leads to much simpler workflows which yields many benefits in terms of management, troubleshooting, and efficiency.
As mentioned in the previous point, there are limited toolsets that are currently available for Serverless environments. This includes testing tools. Integration testing is a much different animal when it comes to Serverless infrastructure. Integration testing must depend on external or persistent resources to maintain state information with Serverless applications. Integration testing has to be able take these scenarios into account. ISVs today can take advantage of stub resources which allow hosting external dependency resources locally.
However, using these types of stub resources with integration testing can still present challenges in keeping resources synchronized, which can present challenges. Integration testing is extremely important with FaaS code since function code by its nature relies on all the other resources in the environment to ensure the application runs as expected. Understanding the integration testing challenges and considerations that need to be made are fundamental to deploying Serverless applications that are well tested and perform optimally.
Today’s development environments are moving faster than ever before. New cloud technologies are allowing faster development of more powerful applications that span the boundaries of on-premises and cloud environments. New technologies such as Serverless infrastructure are part of the new wave of application and coding technologies allowing this movement to happen.
With Serverless infrastructure, there are certainly best practices that allow correctly and efficiently utilizing Serverless solutions in application development. These include:
By considering these and other AWS Lambda Serverless and modern development best practices in general, ISVs can develop powerful applications correctly and with the right solutions for customer’s business needs.