Creating an AWS Serverless C# DotNet Application (S3, DynamoDB, API Gateway, Lambdas(C-Sharp) and CDK)
Often it can be daunting to create your first AWS Serverless application. This article will go through the basics of creating a serverless application with fundamental AWS services such as API Gateway, Lambdas, S3 Buckets, and DynamoDB. These will all be deployed using Cloud Development Kit(CDK) in C#. This will combine the power of AWS and Microsoft’s C# language. With this approach you can get Microsoft Workloads running easily in the AWS Cloud Infrastructure. This article has been to quickly show you how to create Lambdas and have them interact with cloud resources such as S3 Buckets and a DynamoDB. At Xerris, we help organizations with their digital transformation efforts often involving moving Microsoft Workloads to the cloud.
Objective: Create a Serverless AWS Application with C# Lambdas that interact with DynamoDB and S3.
- Prerequisites:
- You will have to have your AWS account and Visual Studio configured(See
https://medium.com/@collin.smith/getting-started-with-a-aws-and-visual-studio-dc64ac8d33ed if you have any concerns with this) - NodeJS https://nodejs.org/en/download/
- Cloud Development Kit(CDK) https://docs.aws.amazon.com/cdk/latest/guide/cli.html
npm install -g aws-cdk
cdk --version
2. Create your CDK Project
Go to your projects folder, I am using C:\projects on my machine.
Open a new command prompt and do the following
cd c:\projects
mkdir CDKApp
cd CDKApp
cdk init --language csharp
You should then be able to open the solution file located in C:\projects\CDKApp\src\CdkApp.sln with Visual Studio
The 2 files to examine are:
Program.cs: The entry point for your CdkApp application
CdkAppStack.cs: This class will define your CdKApp stack to determine which AWS Infrastructure resources get generated. It is currently empty.
Go to the Solution Explorer and right click to “Build Solution” you should get a successful build.
If you have any issues with the build you might need to Right click in the Solution Explorer and select “Manage Nuget Packages for Solution…”
Click on Browse and find the Amazon.CDK package and install this.
If no issues, proceed to the cdk command line commands.
Go to the command line and execute the following commands to verify that the cdk project is working fine.
cd c:\projects\CDKApp
cdk bootstrap
cdk synth
cdk deploy
If this runs without error, then it looks like you have a good setup to continue with.
3. Create the Lambda project
Install DotNet CLI : https://dotnet.microsoft.com/download
Verify the version that you have with the command:
dotnet --version
Install the Lambda templates
dotnet new -i Amazon.Lambda.Templates
Go to your current solution folder and create a Lambda template project.
cd c:\projects\CDKApp
dotnet new -i Amazon.Lambda.Templates
dotnet new lambda.EmptyFunction --name Lambdas
You should now see a Lambdas project that has been created for your Lambdas.
You can now add this to your CdkApp Solution in Visual Studio.
Open Visual Studio, go to the Solution Explorer, right click , select Add, Existing Project…
Navigate to the newly created Lambdas project file
In my case it is located at C:\projects\CDKApp\Lambdas\src\Lambdas\Lambdas.csproj
We can now rebuild the solution and we will have both the CdkApp project and the Lambdas project successfully building.
cd c:\projects\CDKApp
cdk bootstrap
cdk synth
cdk deploy
4. Update the CdkAppStack.cs
To save time, we will copy the following code into our CdkApp.cs file in the CdkApp project. The actual code for CdkAppStack.cs can be retrieved rom https://github.com/xerris/CDKApp or found in the Appendix of this article. This will determine the infrastructure for our C# Serverless project including the generation of an S3 Bucket, DynamoDB Table, and API Gateway API and 4 Lambdas.
Do not worry about any missing references for now, we will deal with them once we update the next file.
5. Update your Function.cs class
The next class is our Lambda Handler and will contain code for our 4 lambdas and some other code to interact with our S3 Bucket and our DynamoDB Table. The actual code for Function.cs can be retrieved rom https://github.com/xerris/CDKApp or found in the Appendix of this article.
6. Resolve the missing references by managing the nuget packages
Right click in the Solution Explorer and select “Manage Nuget Packages for Solution…”. Follow the same process as you did for the Amazon.CDK package above.
Required packages include
AWSSDK.S3
Amazon.CDK.AWS.S3
Amazon.CDK.AWS.DynamoDB
Amazon.Lambda.APIGatewayEvents
AWSSDK.DynamoDBv2
Amazon.CDK.AWS.APIGateway
Amazon.Lambda.Core
Right click in Solution Explorer, Rebuild Solution
Now when you rebuild the Solution, it should build successfully.
7. Using Cloud Development Kit (CDK) to deploy your CDK App to your AWS Cloud Environment
Open an command shell (CMD)
cd c:\projects\CDKApp
cdk bootstrap
cdk synth
cdk deploy
You might be prompted to deploy these changes, just type Y and hit return
A successful deploy will look like the following:
Note the the outputs in blue will tell you key information about what you have deployed. There will be an S3 Bucket and a DynamoDB created. Along with this are 4 C# Lambdas that can be tested.
You should also be able to go into your AWS Console and verify the existence of all of these resources by going to the AWS Service sections for S3, DynamoDB, Lambdas and APIGateway.
8. Verifying the successful deployment
To test out your newly created Application(Lambdas), it is suggested that you get a tool like Postman to make calls to your Lambdas to test out the functionality.
(a) simple Lambda
This simple lambda just shows a simple lambda that will take a POST request and it will return a response.
Open Postman up, Create a new Request. This request should be POST.
Copy the url in your console window for your SimpleLambda into your Postman request. Select the Body tab and select the raw option.
You will also note that in the Function.cs class in visual studio, there are sample JSON bodies provided to test each of these four lambdas. For this, lambda we can use the following json body:
{
"anyjson":"somevalue"
}
It should then look something like the following
You should then be able to press Send.
It should then send you back a response like the following:
The response is in JSON Format for client applications to use. This confirms that your simple Lambda is working. The next lambdas integrate with S3 or DynamoDB. Remember all the code is given to you in the CdkApp.cs class and the Function.cs class for further study.
(b)s3 Lambda
The S3 Lambda is designed to query the contents of the S3 Bucket that should have been created in the code. **Note** that sometimes when you want to remove your cdk with a “cdk destroy” command, there can be problems as you are not allowed to delete an S3 bucket with objects in it. You will have to remove these files manually. If you look in your console window you can see the bucketName of the bucket created in your CdkApp.
Copy the S3Lambda url from your console window and set up a request like you did for the previous Lambda. You can set up the request body as follows:
{
"anyjson":"somevalue"
}
The request body does not matter much here as we are just going to query the contents of the S3 Bucket.
The likely initial response from the Lambda will look like the following
{ "request":{"anyjson":"somevalue"},"response":"S3Lambda CDK Lambda call at Monday, 01 February 2021 14:09:04 Region:us-west-2S3 Bucket location:prd-mys3bucket96315# Files in the bucket=0**S3 Report Log= S3ReportService ReportLog region=us-west-2 bucketName=prd-mys3bucket96315 ","s3Objects":[],"success":"True","message":""}
If you now log into your AWS Console and add a couple of images to your S3 Bucket. Then you should see a different responses that list out details on your S3 bucket contents. Something like
{ "request":{"anyjson":"somevalue"},"response":"S3Lambda CDK Lambda call at Monday, 01 February 2021 14:14:33 Region:us-west-2S3 Bucket location:prd-mys3bucket96315# Files in the bucket=2**S3 Report Log= S3ReportService ReportLog region=us-west-2 bucketName=prd-mys3bucket96315 ","s3Objects":[{"key": "Bill.jpg","bucketname": "prd-mys3bucket96315","region": "us-west-2","size": "188821","lastmodified": "2/1/2021 2:14:25 PM"},{"key": "monalisa.jpg","bucketname": "prd-mys3bucket96315","region": "us-west-2","size": "124780","lastmodified": "2/1/2021 2:14:26 PM"}],"success":"True","message":""}
(c )writedynamodb Lambda
The Write DynamoDB Lambda is designed to input a User into the created DynamoDB Table. You will make a similar POST request to this Lambda like you did for the previous Lambdas. Get your writeDynamoDB Lambda url from your console window.
The initial request Body should look as follows
{"email":"jeff.bezos@amazon.com","firstName":"Jeff","lastName":"Bezos"}
Note that there is a Timeout of 20 seconds enabled for this call as when you first call it, it takes some time to generate a AmazonDynamoDBClient object. You will then get a response like the following in your Postman request call:
{ "request":{"email":"jeff.bezos@amazon.com","firstName":"Jeff","lastName":"Bezos"},"response":"WriteDynamoDB CDK Lambda Monday, 01 February 2021 14:18:54 DynamoDB Table:PRD-User Successfully saved User(jeff.bezos@amazon.com,Jeff,Bezos) to our DynamoDB table PRD-User","user":{"email":"jeff.bezos@amazon.com","firstName":"Jeff","lastName":"Bezos"},"success":"True","message":""}
You can actually go to your AWS Console and look in the DynamoDB Service and review the contents of your DynamoDB Table created. The DynamoDB table name is also provided to you in the console window.
(d)readdynamodb Lambda
The readdynamodb Lambda can be demonstrated by making a Postman request to the url presented in the console window. We will try to query the DynamoDB database for the user we created earlier. You can use the following as a request Body:
{
"email":"jeff.bezos@amazon.com"
}
The Lambda response should indicate that the user is indeed in our DynamoDB database:
{ "request":{"email":"jeff.bezos@amazon.com"},"response":"Searching for user(jeff.bezos@amazon.com)DynamoDBUserService Log:Looking for user(jeff.bezos@amazon.com) within dynamodb table PRD-User.*** Found that user ***. Found the User:jeff.bezos@amazon.com,Jeff,Bezos","user":{"email":"jeff.bezos@amazon.com","firstName":"Jeff","lastName":"Bezos"},"success":"True","message":""}
If you change the email address and resubmit, it should indicate that this user is not in the database.
Caching Objects to improve Lambda Performance:
Examples of caching objects in the Lambda context:
S3LambdaHandler(see S3ReportService): a static instance of the AmazonS3Client
ReadDynamoDBLambdaHandler(see DynamoDBUserService): a static instance of AmazonDBClient
Note that the AmazonDBClient is not cached in the WriteDynamoDBLambdaHandler as the AmazonDBClient is regenerated with each call
Caching of these types of objects in your Lambda context can definitely improve performance of your Lambdas. You can look at the response times for these Lambdas for evidence of this.
9. Cleanup with CDK
When trying to cleanup a CDK Application you can use the following command:
cdk destroy
This should remove all of the infrastructure you have deployed in your application. Note however, if you have added files to the S3 bucket, you will have to remove them first or clean that S3 bucket up in the AWS Console.
10. Further research and exploration
It is suggested that you explore the code in Function.cs and CdkAppStack.cs to see how the CDK infrastructure is deployed. It is all there for you to explore. This has provided you with a C# Serverless Application with an S3 Bucket, DynamoDB, and Lambdas that interact with this infrastructure.
This type of infrastructure makes a great back end for a front end application that would utilize this. Front ends could include web applications, desktop applications or others as well.
If you want to learn more about this, I would suggest that you play around with the CdkApp code and try to create new Lambdas and integrate them with AWS resources. Additionally, you can think about adding your own .NET projects and code to this type of setup to enable your existing Microsoft Workloads into the cloud. If you have any questions/concerns feel free to reach out to myself.
Appendix (2 Files)
Both files available at https://github.com/xerris/CDKApp
(A) CdkAppStack.cs
(B) Function.cs