AWS Lambda

Lambda is somewhat of a  next evolution in abstracting the hardware away from the application. Virtualization such as EC2 took the pain of dealing with hardware away from operations teams; Lambda does the same but to the operating system and scaling. The AWS Lambda lets you create custom code called Lambda functions, which are written in Node.js, Python, Java, and C# that will be triggered automatically in response to events. Those events can be emitted by your own application and a number of managed services. Among the services we previously explored are S3, CodePipeline, CodeCommit, Kinesis, and Aurora, but the list of services that integrate with Lambda is a lot longer than this. You can read more about the different services supported at http://amzn.to/2hrCtYB.

There are a number of ways to take advantage of AWS Lambda. You can use it to scale some features in your applications better. For instance, let's imagine a photo-sharing service. As you do your initial development, you will likely add to your application a feature to upload photos. This feature will likely get the photos and store them on S3 and then generate a thumbnail for better previewing. This feature will work well when executed by your main application, but you will have to pay attention to the number of photos that are being uploaded as you will sometimes run out of computing power if too many thumbnails are being generated at the same time. Instead, with AWS Lambda, you can create a function to generate the thumbnail and trigger it when new objects (in this case photos) are created in your S3 bucket. With that strategy, scaling the thumbnail generation will be a nonissue as each photo uploaded will trigger the execution of your function and AWS will make sure that the execution happens within milliseconds of the trigger.

You can also use AWS Lambda for more general engineering concepts. We saw earlier in the chapter how to add ElastiCache to our data layer easily to take some load off our database. Checking if the data is already cached or caching new data is only half of the work needed when implementing a caching layer and, arguably, that's the easy half. The most difficult part is to handle the cache invalidation. Whenever we update a field in our database, we need to remove the entry from the cache such that the cache doesn't serve the old data whenever it is being queried. If we look back at our phone book application example used in the ElastiCache section, if a business moves to a new location, the address will need to be updated in the database, but also, we will want to remove the current address of that business from ElastiCache.

In complex architectures where multiple services interact with our database, it can be challenging to handle the cache invalidation correctly for each service that makes changes in our database. An easy way to implement the cache invalidation if you use Aurora is to create a Lambda function that will be invoked every time we execute an update query.

In order to get started with AWS Lambda, you can explore a number of blueprints, including the exact function needed to generate photo thumbnails, as mentioned in the previous example. To do so, open the Lambda service console at https://console.aws.amazon.com/lambda.

From a code standpoint, creating a Lambda function is fairly straightforward. You will simply need to implement a handler function as follows:

exports.handler = (event, context, callback) => { 
    // TODO implement 
    callback(null, 'Hello from Lambda'); 
}; 

The code can be implemented directly in the AWS console or uploaded as a ZIP file or imported from S3, but of course, those solutions aren't ideal when you are trying to make a complex application that may have multiple functions and staging and production environments. Instead of this, we are going to use an open source framework called Serverless. The Serverless framework (https://serverless.com) is a simple framework dedicated to managing serverless applications. By using this framework instead of simply CloudFormation, we can easily configure our application to handle many Lambda functions and easily connect them to some of the AWS services across multiple environments. In addition, the framework will make it easy to deploy and test our application.

To comprehend the framework fully, we will first start by installing it as follows:

$ npm install -g serverless  

We can now start using it.

The framework supports developing applications in a number of languages including Python and Java, but in our case, we will use nodejs as this is the language we used previously to create our Hello World application.

We first create a new serverless application using the following command:

$ serverless create --template aws-nodejs --path helloworld  

The command creates a folder helloworld with two files in it, serverless.yml, the configuration file for our application, and handler.js, which will contain our code.

We are going to go in that folder and start editing the files:

$ cd helloworld  

Open the file handler.js with your editor.

We find in it the definition of the exports.handler previously mentioned. By default, the application will return a JSON object. We are going to replace the body of the response simply to return the string 'Hello World'. On Line 6 of the file, you will find something like:

    body: JSON.stringify({ 
      message: 'Go Serverless v1.0! Your function executed successfully!', 
      input: event, 
    }), 

Replace this block with:

body: 'Hello World' 

Then, save the changes. For this example, we don't need to edit the serverless.yml file as, by default, the values set for the service are what we need. The application is called helloworld, the provider is AWS, it will use nodejs at runtime, the stage is set to dev, and the region us-east-1.

We can now deploy the application using the following command:

$ serverless deploy  

By running this command, the serverless framework will create a new CloudFormation stack called helloworld-dev (since our environment is dev), upload it to S3, then package the code and also upload it to S3 and, finally, run the deployment for us. In the end, the command will return something like:

Service Information

service: helloworld

stage: dev

region: us-east-1

api keys:

None

endpoints:

None

functions:

helloworld-dev-hello: arn:aws:lambda:us-east-1:511912822958:function:helloworld-dev-hello

This gives us all the information we need. As we can see, our new function is called helloworld-dev-hello.

We can validate that everything worked by invoking our new function as follows:

$ serverless invoke --function hello
{
    "statusCode": 200,
    "body": "Hello World"
}  

Other services are now able to take advantage of our function. Assuming that generating a "Hello World" string in our original helloworld application was a complicated task worth carving out of our monolith, we could decide to offload that operation to our Lambda function and change our architecture to look like this in order to get the response from the invocation of the Lambda function:

The code would then look something like this:

var aws = require('aws-sdk'); 
var http = require("http"); 
var lambda = new aws.Lambda({ 
  region: 'us-east-1' 
}); 
 
http.createServer(function (request, response) { 
  lambda.invoke({ 
    FunctionName: 'helloworld-dev-hello', 
  }, function(err, data) { 
    if (err) { 
      console.log(err, err.stack);  
    } else {  
      response.writeHead(200, {'Content-Type': 'text/plain'}); 
      response.end(JSON.parse(data.Payload).body); 
    } 
  })    
}).listen(3000) 
console.log('Server running'); 
AWS StepFunctions
One of the difficulties you may face on more complex applications than our Hello World demonstration is the need to invoke multiple Lambda functions either sequentially or in parallel. For those more complex scenarios, AWS created a service called StepFunctions, which let you implement these sophisticated applications by creating a state machine approach. Everything can be created using a visual web interface inside the AWS console. You can read more about this service at http://amzn.to/2hZjZ22.

We now saw how to incorporate some serverless components to our stack, but we can go even further in our serverless transformation and completely remove our EC2 and ELB instances with the help of the API Gateway service.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset