If you are new to AWS Lambda and interested in getting started with the C# language, then you are in the right place. This article will give you a clearer picture of what AWS Lambda is, benefits to Lambda and building your first AWS Lambda C# Function.
Not a reader? Watch this related video tutorial!AWS Lambda C# lets you run code without provisioning or managing servers. You will be getting more depth on what an AWS Lambda is while getting hands on to build and enable a simple lambda function with C# and testing your newly built Lambda function in the AWS console.
What is AWS Lambda?
AWS Lambda is known as a serverless technology meaning there is no infrastructure for you to think about. Lambda allows you to build serverless applications. Additionally, there’s no way to change the underlying operating system. In this case, AWS takes care of the infrastructure and its management.
Some of the benefits to using AWS Lambda are that you don’t need to be concerned about:
- OS level patching
- Scaling thresholds
- Network connectivity
- Managing and maintaining virtual machines
Another big plus is that you are only charged for what you use. This means you are only charged for the number of requests of your code to execute, and the duration, or the time it takes your code to execute. This can be a huge saving when compared to a monthly cost of running a virtual machine in the cloud.
Prerequisites
This will be a walk-through article. If you intend to follow along, be sure you have the following prerequisites in place prior to beginning.
- AWS account (free tier for 12 month):
- .NET Core 2.2
- .NET CLI
How does a Lambda function work?
Code uploaded to run on AWS Lambda, is done so as a function. Before you start to create your function, you need to go over what the function needs to operate. Two keywords that you will hear associated with a Lambda Function are “Handler” and “Context”. When Lambda runs your function, it passes a context object to the handler.
The AWS documentation describes each as follows:
Handler Object – The handler is the method in your Lambda function that processes events. When you invoke a function, the runtime runs the handler method.
Context Object – When Lambda runs your function, it passes a context object to the handler. This object provides properties with information about the invocation, function, and execution environment.
Creating a AWS Lambda C# Function
AWS Lambda for .NET uses .NET Core, an open-source and cross platform framework. For clarity, C# is a programming language and .NET is the framework on which the language is built. To learn more about .NET Core, please take a look at the Microsoft documentation. The latest supported version of .NET Core in AWS Lambda is 2.1, which means it doesn’t support the new tooling from .NET Core 3.
In this demonstration you will be using the .NET core command-line. The .NET Core command-line interface (CLI) is a cross-platform toolchain for developing .NET applications. For more information, please take a look at the Microsoft documentation.
You can make use of Visual Studio to create Lambda functions, as well.
Installing the Lambda Template
The first task to do is to install the Amazon.Lambda.Templates NuGet package. A NuGet package is a single zip file with the .nupkg extension that contains compiled code (DLLs), additional files related to that code, and a manifest that details package information. From your preferred command-line terminal (PowerShell, CMD, etc.) type:
> dotnet new -i Amazon.Lambda.Templates
Now that you have installed the Lambda templates, they will show up as part of dotnet new
command. The dotnet
new command creates a new project, configuration file, or solution based on the specified template that’s used along with the command.
Using the below command will show this by matching the word Lambda:
> dotnet new | Select-String -SimpleMatch 'lambda'
You will be using Lambda’s EmptyFunction template for this demo. The EmptyFunction **template is the scaffold to a basic Lambda project. The following options are supported when using the lambda.EmptyFunction template with the dotnet
new command (as shown below):
- –name – The name of the function
- –profile – The name of a profile in your AWS SDK for .NET credentials file
- –-region – The AWS Region in which the function is created
Below you can see an example of creating a Lambda function using the default AWS profile. You do this by running the below command where you can see an example of creating a Lambda function using the default AWS profile:
> dotnet new lambda.EmptyFunction --name MySimpleFunction --profile default --region us-east-1
Running this command will return a successful message, as shown in the screenshot:
By using the tree command, you can display the file and directory structure of a path.
As you can see from the tree output you have two directories, src and test. The src folder is the main project code and test for testing code in your src folder.
Next, you need to run the dotnet
command to install the Amazon global tools. Global tools are a new feature in .NET Core. They provide the ability to distribute command line tools via a NuGet package and install them with the dotnet
command line.
To install the tools, type the following command:
> dotnet tool install -g Amazon.Lambda.Tools
AWS Lambda C# invokes the Function.cs file from the src folder when calling the Lambda function. You are able to create separate CS files to keep your code tidy. A CS file is a source code file written in the C# language.
Your CS files use the namespace keyword which uses the same name throughout each CS file. The purpose of a namespace is to help control the scope of the .NET class and method names in bigger projects.
The Function.cs template provided by the Lambda template you run and created earlier in the article looks like the below screenshot. I have highlighted and number some areas of interest:
- The Lambda package for .NET core. This library provides a static Lambda logger, serialization interfaces, and a context object.
- The handler part of the parameter is the input that comes first. This can be event data or custom input.
- For any Lambda functions that use input or output types will require the need to add a serialization library (except for the Stream object). The Amazon.Lambda.Serialization.Json NuGet package is used to perform serialization.
- If you want to utilize the Lambda context object information, which gives us information on memory limit and execution time remaining to name a few, then you need to define a method parameter of ILambdaContext.
You will be creating a simple class to take a first name and last name, which will display a welcome message. You will also make use of the context object (described in the “How does a Lambda function work?” section), and use the Lambda logger (provided in the Amazon.Lambda.Core library), add the function named called.
Writing First Name and Last Name Welcome Message With C#
Under the directory of .\MySimpleFunction\src\MySimpleFunction, create a new class file, Newuser.cs. This class will be used to capture the first name and last name, or surname.
The class will contain two public strings and the namespace is called MySimpleFunction. This is the same namespace name from the Function.cs file.
using System;
using System.Collections.Generic;
using System.Text;
namespace MySimpleFunction {
public class NewUser {
public string firstName { get; set; }
public string surname { get; set; }
}
}
Save the file and open the Function.cs file.
You are going to change the main public class name to DisplayNewUser. Apart from making the class more specific, it will help show how the handler string tells AWS Lambda C# where to look when invoking the code.
The method, which will invoke our code, will look like this: You’ll call this method in when the Lambda function is invoked.
public string FunctionHandler(NewUser input, ILambdaContext context)
This looks very similar to the default method provided in the Function.cs file, apart from the input type, which is now referencing our Newuser.cs class file.
The main body of the method contains the following two lines:
LambdaLogger.Log($"Calling function name: {context.FunctionName}\n");
return $"Welcome: {input.firstName} {input.surname}";
To write logs, you are using the Log method from the Amazon.Lambda.Core.LambdaLogger class, which is from the Lambda library Amazon.Lambda.Core. I’m using the context information to display the function name. The second line is returning the first name and surname to the screen.
The full function.cs file looks like:
using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Amazon.Lambda.Core;*// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.*[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]namespace MySimpleFunction { public class DisplayNewUser {*// <summary>**// A simple function that takes a string and does a ToUpper**// </summary>**//<param name="input"></param>**// <param name="context"></param>**//<returns></returns>* public string FunctionHandler(NewUser input, ILambdaContext context) { LambdaLogger.Log($"Calling function name: {context.FunctionName}\n"); return $"Welcome: {input.firstName} {input.surname}"; } }}
Before you upload this, you need to edit the aws-lambda-tools-defaults.json file, located in the src folder. The aws-lambda-tools-defaults.json input file is where the command line options are found for deploying your Lambda function. The end of the file contains these values:
"profile":"default",
"region":"us-east-1",
"configuration":"Release",
"framework":"netcoreapp2.1",
"function-runtime":"dotnetcore2.1",
"function-memory-size":256,
"function-timeout":30,
"function-handler":"MySimpleFunction::MySimpleFunction.Function::FunctionHandler"
The line you need to change contains function-handler*.* Currently the line has the details on how AWS Lambda will invoke the code, MySimpleFunction::MySimpleFunction.Function::FunctionHandler. Remember, you changed the main public class to DisplayNewUser in the Function.cs. This will need to be reflected in the function-handler, replacing the word Function to DisplayNewUser, like so:
MySimpleFunction::MySimpleFunction.DisplayNewUser::FunctionHandler
You are going to add an extra line, “function-role” : “myBasicExecutionRole”. The function role as it might suggest, is the role with the required permissions to run the Lambda function. The role of myBasicExecutionRole**,** is the least privileged role to execute a Lambda function, as predefined by AWS.
Adding this line is not required, but when deploying the function, it will save adding to the command line. The dotnet
command line is again used to deploy the function to AWS:
> dotnet lambda deploy-function MySimpleFunction
The output of this command will look similar to this:
Testing the Lambda Function
To view the Lambda function you created, navigate via the AWS Services from within the Lambda console. From the main screen you will see your function listed:
Click on the function name to open the Lambda function. At the top of screen, you have the ability to test our Lambda:
Click on the down arrow next to the Test button:
Input and output in AWS are in the JSON format. You will need to configure your event in the JSON format.
To configure the event in this demo, you just need to pass a firstname and surname:
The JSON you need to write is as follows:
{
"firstName": "Graham",
"surname": "Beer"
}
Give the Event a name in the corresponding box, mine is simply called MyTestEvent, and click create, at the bottom of the template. You will be returned to the main Lambda page for your function. You can now click on the Test button to run your Lambda:
Arrow number 1 shows the name details you passed to the test event information in JSON format, with the welcome message before coming from the Function.cs file.
The second arrow is showing the function name you requested, also from the Function.cs.
You can also call the Lambda function with the AWS command line. You don’t need to configure the test event in this case, as the JSON is passed through as an argument.
Note, in Windows you are required to write the double quotes and single quotes at the end for it to work. The line of code is written like so:
> aws lambda invoke --region us-east-1 --function-name SimpleFunction --payload '"{""firstName"": ""Graham"", ""surname"": ""Beer""}"' output.txt;
Using PowerShell’s Get-Content
cmdlet, you are able to view the contents of the output.txt file created from the AWS command line you just used:
PS51> Get-Content -Path output.txt
The command line returned a StatusCode of 200 (successful) and confirms you have run the latest version of our Lambda function.
The output from the output.txt file displays the Lambda function output, shown in the above screenshot with the arrow.
Summary
Throughout this article I’ve tried to touch on many areas of the AWS Lambda process. I’m a huge fan of serverless, it is great to be able to code and not concern yourself with the underlying infrastructure.
Although the demonstration in this article is pretty insignificant, it gives you a taste and may begin to spark the imagination to come up with other solutions. .NET Core is a major player in Lambda and with the capability to use C#, and even PowerShell, you have great flexibility.