Building Serverless Web Applications
上QQ阅读APP看书,第一时间看更新

Creating a Lambda function

In this book, we will use the Serverless Framework extensively to make the deployment of Lambda functions easier; however, to see how useful the framework is, in this chapter, we will use the AWS Management Console for comparison.

We will now create a Lambda function to process log files. This function will be triggered when a new log file is added to an S3 bucket and the result of the Lambda function is to create an SNS notification if there is an error in the file.

Let's take a look at the following steps, which are necessary to execute:

  1. Browse the following link: https://console.aws.amazon.com/lambda. Select Get Started Now to start creating a new function:
  1. AWS offers many templates with sample configuration and code. For example, you could use a template of a Lambda function that processes bounced e-mails. This option is interesting for marketing campaigns to remove e-mail addresses that don't exist. However, in this example, we will select a Blank Function template:
  1. A Lambda function can be triggered by many different sources. In the next screen, you will see a list of all available options. Select S3:
  • On a side note, take a look at some use cases of the available triggers:
    • Amazon S3: You can select a bucket name with Event type as Object Created (All) and Prefix images/. In this setting, when you upload an image to this bucket within the images folder, you will trigger a Lambda function for post-processing and image optimization.
    • SNS: You can use this service to handle notifications. For example, you could create an SNS topic named Process Order that would be activated by your application when a new order is received. SNS could be configured to send an e-mail for a specific list of employees and trigger a Lambda function to execute some logic.
    • CloudWatch Logs: This service helps you to monitor your AWS resources and take automated actions. You could trigger Lambda functions to handle alert messages and execute specific actions according to its content.
  1. After selecting S3, you will be presented with some configuration options. Select the bucket that we have created previously with the CLI. For the Event type, select Object Created (All) to trigger the function whenever a new file is created. For Prefix, type logs/ to consider only files in the logs folder and in the Suffix, type txt to consider only text files. Finally, check the Enable trigger option and click on Next:
  2. Type a name for your Lambda function, for example, processLog, and select the Node.js 6.10 option for Runtime:
  3. Now we need to implement the code that will be executed by the Lambda function using the Edit code inline option. In this example, we are using S3.getObject to retrieve the file created and SNS.publish to create a notification if there is the error word in this file. For the SNS topic ARN, you can use the same that was previously created with the CLI:
        const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const sns = new AWS.SNS();

exports.handler = (event, context, callback) => {
const bucketName = event.Records[0].s3.bucket.name;
const objectKey = event.Records[0].s3.object.key;
const s3Params = {
Bucket: bucketName,
Key: objectKey
};

s3.getObject(s3Params, (err, data) => {
if (err) throw err;

// check if file have errors to report
const fileContent = data.Body.toString();
if (fileContent.indexOf('error') !== -1) {
const msg = `file ${objectKey} has errors`;
const snsParams = {
Message: msg,
TopicArn: 'my-topic-arn'
};
sns.publish(snsParams, callback);
}
});
};
The aws-sdk module is available for all Lambda functions. If you want to add another dependency that is not the aws-sdk module or a core module of Node, you need to upload a ZIP file to AWS containing your function and the module.
  1. As we have used the inline option to write the code instead of uploading a ZIP file, the code will be placed inside an index.js file. Also, the module that we have created exports a function named handler. In this case, we need to configure the Lambda handler with the index.handler name. For the Role box, we need to create a new one because a Lambda function can't execute without proper access. Even if you create a Lambda using an administrator account, you must give explicit permissions for which kind of services and resources the Lambda will be able to access:
  1. Type a role name for this role and click on Edit to modify the default policy document. Add the following JSON object and finish by clicking on Allow:
You will need to replace the S3 and SNS ARNs to your respective ARNs.

Use the following JSON object:

        {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-bucket-name/*"
},
{
"Effect": "Allow",
"Action": ["sns:Publish"],
"Resource": "arn:aws:sns:us-east-1:1234567890:email-alerts"
}
]
}

 

  1. The last step is to configure the Advanced settings. Set the amount of RAM memory that should be allocated for this function and the timeout value that AWS must wait for this function to finish its execution. You may need to increase the timeout value depending on the size of the log files that you are going to use for testing:
  1. Click on Next and you will be redirected to a Review page where you need to confirm the function creation.
  2. To test this function, we can use the Management Console, which lets us create custom input events, but, in this case, we can use the CLI to upload a new file and trigger the Lambda function. If the file has the word “error”, you should receive an e-mail message with the file name.

Take a look at the following CLI command to trigger this Lambda function:

        aws s3 cp log1.txt s3://my-bucket-name/logs/
  1. If you have any issues, you can try using the Management Console to see the error message that appears. In this case, use the following JSON object as the event trigger, replacing the bucket name:
        {
"Records": [
{
"s3": {
"bucket": {
"name": "my-bucket-name"
},
"object": {
"key": "logs/log1.txt"
}
}
}
]
}