

# AWS Lambda
<a name="lambda-index"></a>

Develop and deploy your .NET Core-based C\$1 Lambda functions with the AWS Toolkit for Visual Studio. AWS Lambda is a compute service that lets you run code without provisioning or managing servers. The Toolkit for Visual Studio includes AWS Lambda .NET Core project templates for Visual Studio. 

For more information about AWS Lambda, see the [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) Developer Guide.

For more information about .NET Core, see the Microsoft [.NET Core](https://docs.microsoft.com/en-us/dotnet/articles/core/) guide. For .NET Core prerequisites and installation instructions for Windows, macOS, and Linux platforms, see [.NET Core Downloads](https://www.microsoft.com/net/download/core).

The following topics describe how to work with AWS Lambda using the Toolkit for Visual Studio.

**Topics**
+ [Basic AWS Lambda Project](lambda-creating-project-in-visual-studio.md)
+ [Basic AWS Lambda Project Creating Docker Image](lambda-creating-project-docker-image.md)
+ [Tutorial: Build and Test a Serverless Application with AWS Lambda](lambda-build-test-severless-app.md)
+ [Tutorial: Creating an Amazon Rekognition Lambda Application](lambda-rekognition-example.md)
+ [Tutorial: Using Amazon Logging Frameworks with AWS Lambda to Create Application Logs](cw-log-frameworks.md)

# Basic AWS Lambda Project
<a name="lambda-creating-project-in-visual-studio"></a>

You can create a Lambda function using Microsoft .NET Core project templates, in the AWS Toolkit for Visual Studio.

## Create a Visual Studio .NET Core Lambda Project
<a name="create-a-visual-studio-net-core-lam-project"></a>

You can use Lambda-Visual Studio templates and blueprints to help speed up your project initialization. Lambda blueprints contain pre-written functions that simplify the creation of a flexible project foundation.

**Note**  
The Lambda service has data limits on different package types. For detailed information about data limits, see the [Lambda quotas](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html) topic in the *AWS Lambda* User Guide.

**To create a Lambda project in Visual Studio**

1. From Visual Studio expand the **File** menu, expand **New**, then choose **Project**.

1. From the **New Project** dialog box, set the **Language**, **Platform**, and **Project type** drop-down boxes to "All", then type **aws lambda** in the **Search** field. Choose the **AWS Lambda Project (.NET Core - C\$1)** template.

1. In the **Name** field, enter **AWSLambdaSample**, specify your desired file **Location**, then choose **Create** to proceed.

1. From the **Select Blueprint** page, select the **Empty Function** blueprint, then choose **Finish** to create the Visual Studio project.

## Review the Project Files
<a name="review-the-project-files"></a>

There are two project files to review: `aws-lambda-tools-defaults.json` and `Function.cs`.

The following example shows the `aws-lambda-tools-defaults.json` file, which is automatically created as part of your project. You can set build options by using the fields in this file. 

**Note**  
 The project templates in Visual Studio contain many different fields, take note of the following:  
**function-handler**: specifies the method that runs when the Lambda function runs
Specifying a value in the **function-handler** field pre-populates that value in the Publish wizard.
If you rename the function, class, or assembly then you also need to update the corresponding field in the `aws-lambda-tools-defaults.json` file.

```
{
  "Information": [
    "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
    "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
    "dotnet lambda help",
    "All the command line options for the Lambda command can be specified in this file."
  ],
  "profile": "default",
  "region": "us-west-2",
  "configuration": "Release",
  "function-architecture": "x86_64",
  "function-runtime": "dotnet8",
  "function-memory-size": 512,
  "function-timeout": 30,
  "function-handler": "AWSLambdaSample::AWSLambdaSample.Function::FunctionHandler"
}
```

Examine the `Function.cs` file. `Function.cs` defines the c\$1 functions to expose as Lambda functions. This `FunctionHandler` is the Lambda functionality that runs when the Lambda function runs. In this project, there is one function defined: `FunctionHandler`, which calls `ToUpper()` on the input text. 

Your project is now ready to publish to Lambda.

## Publishing to Lambda
<a name="publish-to-lam"></a>

The following procedure and image demonstrate how to upload your function to Lambda using the AWS Toolkit for Visual Studio.

![\[Invoking the test function page\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/uploadnet8.png)


**Publishing your function to Lambda**

1. Navigate to the AWS Explorer by expanding **View** and choosing **AWS Explorer**.

1. In the **Solution Explorer**, open the context menu for (right-click) the project you want to publish, then choose **Publish to AWS Lambda** to open the **Upload Lambda Function** window.

1. From the **Upload Lambda Function** window, complete the following fields:

   1. **Package Type**: Choose **Zip**. A ZIP file will be created as a result of the build process and will be uploaded to Lambda. Alternatively, you can choose **Package Type** **Image**. The [Tutorial: Basic Lambda Project Creating Docker Image](lambda-creating-project-docker-image.md) describes how to publish using **Package Type** **Image**.

   1. **Lambda Runtime**: Choose your Lambda Runtime from the drop-down menu.

   1. **Architecture**: Select the radial for your preferred architecture.

   1. **Function Name**: Select the radial for **Create new function**, then enter a display name for your Lambda instance. This name is referenced by both the AWS Explorer and AWS Management Console displays.

   1. **Handler**: Use this field to specify a function handler. For example: **AWSLambdaSample::AWSLambdaSample.Function::FunctionHandler**.

   1. *(Optional) ***Description**: Enter descriptive text to display with your instance, from within the AWS Management Console.

   1. **Configuration**: Choose your preferred configuration from the drop-down menu.

   1. **Framework**: Choose your preferred framework from the drop-down menu.

   1. **Save settings**: Select this box to save your current settings to `aws-lambda-tools-defaults.json` as the default for future deploments.

   1. Choose **Next** to proceed to the **Advanced Function Details** window.

1. In the **Advanced Function Details** window, complete the following fields:

   1. **Role Name**: Choose a role associated with your account. The role provides temporary credentials for any AWS service calls made by the code in the function. If you do not have a role, scroll to locate **New Role based on AWS Managed Policy** in the drop-down selector, then choose **AWSLambdaBasicExecutionRole**. This role has minimal access permissions. 
**Note**  
Your account must have permission to run the IAM ListPolicies action, or the **Role Name** list will be empty and you will be unable to continue.

   1. *(Optional)* If your Lambda function accesses resources on an Amazon VPC, select the subnets and security groups.

   1. *(Optional)* Set any environment variables that your Lambda function needs. The keys are automatically encrypted by the default service key which is free. Alternatively, you can specify an AWS KMS key, for which there is a charge. [KMS](https://aws.amazon.com/kms/) is a managed service you can use to create and control the encryption keys used to encrypt your data. If you have an AWS KMS key, you can select it from the list.

1. Choose **Upload** to open the **Uploading Function** window and begin the upload process.
**Note**  
The **Uploading Function** page displays while the function is uploading to AWS. To keep the wizard open after uploading so that you can view the report, clear **Automatically close wizard on successful completion** at the bottom of the form before the upload completes.   
After the function uploads, your Lambda function is live. The **Function:** view page opens and displays your new Lambda function’s configuration.

1. From the **Test Function** tab, enter `hello lambda!` in the text-input field and then choose **Invoke** to manually invoke your Lambda function. Your text appears in the **Response** tab, converted to uppercase. 
**Note**  
You can reopen the **Function:** view at any time by double-clicking on your deployed instance located in the **AWS Explorer** under the **AWS Lambda** node.  
![\[Invoking the test function page\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/invokeBasic.PNG)

1. *(Optional)* To confirm that you successfully published your Lambda function, log into the AWS Management Console and then choose Lambda. The console displays all of your published Lambda functions, including the one you just created.

## Clean-up
<a name="cleanup-lam"></a>

If you are not going to continue developing with this example, delete the function you deployed so that you do not get billed for unused resources in your account.

**Note**  
Lambda automatically monitors Lambda functions for you, reporting metrics through Amazon CloudWatch. To monitor and troubleshoot your function, see the [Troubleshooting and Monitoring AWS Lambda Functions with Amazon CloudWatch](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions.html) topic in the AWS Lambda Developer Guide.

**To delete your function**

1. From the **AWS Explorer** expand the **AWS Lambda** node.

1. Right click your deployed instance, then choose **Delete**.

# Basic AWS Lambda Project Creating Docker Image
<a name="lambda-creating-project-docker-image"></a>

You can use the Toolkit for Visual Studio to deploy your AWS Lambda function as a Docker image. Using Docker, you have more control over your runtime. For example, you can choose custom runtimes like .NET 8.0. You deploy your Docker image in the same way as any other container image. This tutorial closely mimics [Tutorial: Basic Lambda Project](lambda-creating-project-in-visual-studio.md), with two differences:
+ A Dockerfile is included in the project.
+ An alternate publishing configuration is chosen.

For information about Lambda container images, see [Lambda Deployment Packages](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-package.html) in the *AWS Lambda Developer Guide*.

For additional information about working with Lambda AWS Toolkit for Visual Studio, see the [Using the AWS Lambda Templates in the AWS Toolkit for Visual Studio](lambda-index.md) topic in this User Guide.

## Create a Visual Studio .NET Core Lambda Project
<a name="create-a-visual-studio-net-core-lam-project"></a>

You can use Lambda Visual Studio templates and blueprints to help speed up your project initialization. Lambda blueprints contain pre-written functions that simplify the creation of a flexible project foundation.

**To create a Visual Studio .NET Core Lambda project**

1. From Visual Studio expand the **File** menu, expand **New**, then choose **Project**.

1. From the **New Project** dialog box, set the **Language**, **Platform**, and **Project type** drop-down boxes to "All", then type **aws lambda** in the **Search** field. Choose the **AWS Lambda Project (.NET Core - C\$1)** template.

1. In the **Project Name** field, enter **AWSLambdaDocker**, specify your file **Location**, then choose **Create**.

1. On the **Select Blueprint** page, choose the **.NET 8 (Container Image)** blueprint, and then choose **Finish** to create the Visual Studio project. You can now review the project's structure and code.

## Reviewing Project Files
<a name="review-the-project-files"></a>

The following sections examine the three project files created by the **.NET 8 (Container Image)** blueprint:

1. `Dockerfile`

1. `aws-lambda-tools-defaults.json`

1. `Function.cs`

### 1. Dockerfile
<a name="dockerfile"></a>

A `Dockerfile` performs three primary actions:
+ `FROM`: Establishes the base image to utilize for this image. This base image provides .NET Runtime, Lambda runtime, and a shell script that provides an entry point for the Lambda .NET process.
+ `WORKDIR`: Establishes the image's internal work directory as `/var/task`.
+ `COPY`: Will copy the files generated from the build process from their local location into the work directory of the image.

The following are optional `Dockerfile` actions that you can specify:
+ `ENTRYPOINT`: The base image already includes an `ENTRYPOINT`, which is the start-up process executed when the image is started. If you wish to specify your own, then you are overriding that base entry point.
+ `CMD`: Instructs AWS which custom code you want executed. It expects a fully-qualified name to your custom method. This line either needs to be included directly in the Dockerfile or can be specified during the publish process. 

  ```
  # Example of alternative way to specify the Lambda target method rather than during the publish process.
  CMD [ "AWSLambdaDocker::AWSLambdaDocker.Function::FunctionHandler"]
  ```

The following is an example of a Dockerfile created by the .NET 8 (Container Image) blueprint.

```
FROM public.ecr.aws/lambda/dotnet:8

WORKDIR /var/task

# This COPY command copies the .NET Lambda project's build artifacts from the host machine into the image. 
# The source of the COPY should match where the .NET Lambda project publishes its build artifacts. If the Lambda function is being built 
# with the AWS .NET Lambda Tooling, the `--docker-host-build-output-dir` switch controls where the .NET Lambda project
# will be built. The .NET Lambda project templates default to having `--docker-host-build-output-dir`
# set in the aws-lambda-tools-defaults.json file to "bin/Release/lambda-publish".
#
# Alternatively Docker multi-stage build could be used to build the .NET Lambda project inside the image.
# For more information on this approach checkout the project's README.md file.
COPY "bin/Release/lambda-publish"  .
```

### 2. aws-lambda-tools-defaults.json
<a name="aws-lambda-tools-defaults"></a>

The `aws-lambda-tools-defaults.json` file is used to specify default values for the Toolkit for Visual Studio deployment wizard and .NET Core CLI. The following list describes fields that you can set in your `aws-lambda-tools-defaults.json` file.
+ `profile`: sets your AWS profile.
+ `region`: sets the AWS region where your resources are stored.
+ `configuration`: sets the configuration used to publish your function.
+ `package-type`: sets the deployment package-type to a container image or .zip file archive.
+ `function-memory-size`: sets the memory allocation for your function in MB.
+ `function-timeout`: Timeout is the maximum amount of time in seconds that a Lambda function can run. You can adjust this in increments of 1 second up to a maximum value of 15 minutes.
+ `docker-host-build-output-dir`: sets the output directory of the build process that correlates with the instructions in the `Dockerfile`.
+ `image-command`: is a fully-qualified name to your method, the code you want the Lambda function to run. The syntax is: `{Assembly}::{Namespace}.{ClassName}::{MethodName}`. For more information, see [Handler signatures](https://docs.aws.amazon.com/lambda/latest/dg/csharp-handler.html#csharp-handler-signatures). Setting `image-command` here pre-populates this value in Visual Studio's Publish wizard later on. 

The following is an example of an aws-lambda-tools-defaults.json created by the .NET 8 (Container Image) blueprint.

```
{
  "Information": [
    "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
    "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
    "dotnet lambda help",
    "All the command line options for the Lambda command can be specified in this file."
  ],
  "profile": "default",
  "region": "us-west-2",
  "configuration": "Release",
  "package-type": "image",
  "function-memory-size": 512,
  "function-timeout": 30,
  "image-command": "AWSLambdaDocker::AWSLambdaDocker.Function::FunctionHandler",
  "docker-host-build-output-dir": "./bin/Release/lambda-publish"
}
```

### 3. Function.cs
<a name="w2aac15c45c16c17c21"></a>

The `Function.cs` file defines the c\$1 functions to be exposed as Lambda functions. The `FunctionHandler` is the Lambda functionality that runs when the Lambda function runs. In this project, `FunctionHandler` calls `ToUpper()` on the input text. 

## Publish to Lambda
<a name="publish-to-lam"></a>

Docker images that are generated by the build process are uploaded to Amazon Elastic Container Registry (Amazon ECR). Amazon ECR is a fully-managed Docker container registry that you use to store, manage, and deploy Docker container images. Amazon ECR hosts the image, which Lambda then references to provide the programmed Lambda functionality when invoked. 

**To publish your function to Lambda**

1. From the **Solution Explorer**, open the context menu for (right-click) the project, then choose **Publish to AWS Lambda** to open the **Upload Lambda Function** window.

1. From the **Upload Lambda Function** page, do the following:  
![\[Upload screen for publishing image-based Lambda function to AWS\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/lambda-upload-docker-03192024.png)

   1.  For **Package Type**, **Image** has been automatically selected as your **Package Type** because the publish wizard detected a `Dockerfile` within your project. 

   1. For **Function Name**, enter a display name for your Lambda instance. This name is the reference name displayed in the both the AWS Explorer in Visual Studio and the AWS Management Console.

   1.  For **Description**, enter text to display with your instance in the AWS Management Console.

   1. For **Image Command**, enter a fully-qualified path to the method you want the Lambda function to run: **AWSLambdaDocker::AWSLambdaDocker.Function::FunctionHandler** 
**Note**  
Any method name entered here will override any CMD instruction within the Dockerfile. Entering **Image Command** is optional only IF your `Dockerfile` includes a `CMD` to instruct how to launch the Lambda function.

   1. For **Image Repo**, enter the name of a new or existing Amazon Elastic Container Registry. The Docker image the build process creates is uploaded to this registry. The Lambda definition that is being published will reference that Amazon ECR image.

   1.  For **Image Tag**, enter a Docker tag to associate with your image in the repository. 

   1. Choose **Next**.

1. On the **Advanced Function Details** page, in **Role Name** choose a role associated with your account. The role is used to provide temporary credentials for any Amazon Web Services calls made by the code in the function. If you do not have a role, choose **New Role based on AWS Managed Policy** and then choose **AWSLambdaBasicExecutionRole**. 
**Note**  
Your account must have permission to run the IAM ListPolicies action, or the **Role Name** list will be empty.

1. Choose **Upload** to start the uploading and publishing processes.
**Note**  
The **Uploading Function** page displays while the function is uploading. The publish process then builds the image based on the configuration parameters, creates the Amazon ECR repository if necessary, uploads the image into the repository, and creates the Lambda referencing that repo with that image.   
After the function is uploaded, the **Function** page opens and displays your new Lambda function’s configuration. 

1. To manually invoke the Lambda function, on the **Test Function** tab, enter `hello image based lambda` into the request free-text input field and then choose **Invoke**. Your text, converted to uppercase, will appear in **Response**.   
![\[The Test Function tab of the published Function view page has button to manually invoke Lambda method.\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/lambda-invoke-docker-03192024.png)

1. To view the repository, in the **AWS Explorer**, under **Amazon Elastic Container Service**, choose **Repositories**.

   You can reopen the **Function:** view at any time by double-clicking on your deployed instance located in the **AWS Explorer** under the **AWS Lambda** node.
**Note**  
If your AWS Explorer window is not open, you can dock it via **View** -> **AWS Explorer**

1. Note additional image-specific configuration options on the **Configuration** tab. This tab provides a way to override the `ENTRYPOINT`, `CMD`, and `WORKDIR` that may have been specified within the Dockerfile. **Description** is the description you entered (if any) during upload/publish.

## Clean-up
<a name="cleanup-lam"></a>

If you are not going to continue developing with this example, remember to delete the function and ECR image that was deployed so that you do not get billed for unused resources in your account. 
+ Functions can be deleted by right-clicking your deployed instance located in the **AWS Explorer** under the **AWS Lambda** node. 
+ Repositories can be deleted in the **AWS Explorer** under the **Amazon Elastic Container Service** -> **Repositories**.

## Next Steps
<a name="next-steps-lam"></a>

For information about creating and testing Lambda images, see [Using Container Images with Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-images.html).

For information about container image deployment, permissions, and overriding configuration settings, see [Configuring Functions](https://docs.aws.amazon.com/lambda/latest/dg/configuration-images.html).

# Tutorial: Build and Test a Serverless Application with AWS Lambda
<a name="lambda-build-test-severless-app"></a>

You can build a serverless Lambda application by using an AWS Toolkit for Visual Studio template. The Lambda project templates include one for an **AWS Serverless Application**, which is the AWS Toolkit for Visual Studio implementation of the [AWS Serverless Application Model (AWS SAM)](https://github.com/awslabs/serverless-application-model). Using this project type you can develop a collection of AWS Lambda functions and deploy them with any necessary AWS resources as a whole application, using AWS CloudFormation to orchestrate the deployment.

For prerequisites and information about setting up the AWS Toolkit for Visual Studio, see [Using the AWS Lambda Templates in the AWS Toolkit for Visual Studio](lambda-index.md).

**Topics**
+ [Create a New AWS Serverless Application Project](#create-a-new-aws-serverless-application-project)
+ [Reviewing the Serverless Application files](#examine-the-files-in-the-serverless-application)
+ [Deploying the Serverless Application](#deploy-the-serverless-application)
+ [Test the Serverless Application](#test-the-serverless-application)

## Create a New AWS Serverless Application Project
<a name="create-a-new-aws-serverless-application-project"></a>

AWS Serverless Application projects create Lambda functions with a serverless CloudFormation template. CloudFormation templates enable you to define additional resources such as databases, add IAM roles, and deploy multiple functions at one time. This differs from AWS Lambda projects, which focus on developing and deploying a single Lambda function.

The following procedure describes how to create a new AWS Serverless Application Project.

1. From Visual Studio expand the **File** menu, expand **New**, then choose **Project**.

1. In the **New Project** dialog box, ensure that the **Language**, **Platform**, and **Project type** drop-down boxes are set to "All ..." and enter **aws lambda** in the **Search** field.

1. Select the **AWS Serverless Application with Tests (.NET Core - C\$1)** template.
**Note**  
It's possible that the **AWS Serverless Application with Tests (.NET Core - C\$1)** template may not populate at the top of the results.

1. Click **Next** to open the **Configure your new project** dialog.

1. From the **Configure your new project** dialog, enter **ServerlessPowertools** for the **Name**, then complete the remaining fields to your preference. Choose the **Create** button to proceed to the **Select Blueprint** dialog.

1. From the **Select Blueprint** dialog choose the **Powertools for AWS Lambda** blueprint, and then choose **Finish** to create the Visual Studio project.

## Reviewing the Serverless Application files
<a name="examine-the-files-in-the-serverless-application"></a>

The following sections provide a detailed look at three Serverless Application files created for your project:

1. serverless.template

1. Functions.cs

1. aws-lambda-tools-defaults.json

### 1. serverless.template
<a name="blogcs"></a>

A `serverless.template` file is an AWS CloudFormation template for declaring your Serverless functions and other AWS resources. The file included with this project contains a declaration for a single Lambda function that will be exposed through the Amazon API Gateway as an `HTTP *Get*` operation. You can edit this template to customize the existing function or add more functions and other resources that are required by your application.

The following is an example of a `serverless.template` file:

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Description": "An AWS Serverless Application.",
  "Resources": {
    "Get": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
         "Architectures": [
            "x86_64"
            ],
         "Handler": "ServerlessPowertools::ServerlessPowertools.Functions::Get",
         "Runtime": "dotnet8",
         "CodeUri": "",
         "MemorySize": 512,
         "Timeout": 30,
         "Role": null,
         "Policies": [
            "AWSLambdaBasicExecutionRole"
            ],
         "Environment": {
            "Variables": {
               "POWERTOOLS_SERVICE_NAME": "ServerlessGreeting",
               "POWERTOOLS_LOG_LEVEL": "Info",
               "POWERTOOLS_LOGGER_CASE": "PascalCase",
               "POWERTOOLS_TRACER_CAPTURE_RESPONSE": true,
               "POWERTOOLS_TRACER_CAPTURE_ERROR": true,
               "POWERTOOLS_METRICS_NAMESPACE": "ServerlessGreeting"
               }
            },
         "Events": {
            "RootGet": {
               "Type": "Api",
               "Properties": {
                  "Path": "/",
                  "Method": "GET"
                  }
               }
            }
         }
      }
   },
  "Outputs": {
    "ApiURL": {
      "Description": "API endpoint URL for Prod environment",
      "Value": {
        "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
      }
    }
  }
}
```

Notice that many of the `...AWS:: Serverless::Function...` declaration fields are similar to the fields of a Lambda project deployment. Powertools Logging, Metrics and Tracing are configured through the following environment variables:
+ POWERTOOLS\$1SERVICE\$1NAME=ServerlessGreeting
+ POWERTOOLS\$1LOG\$1LEVEL=Info
+ POWERTOOLS\$1LOGGER\$1CASE=PascalCase
+ POWERTOOLS\$1TRACER\$1CAPTURE\$1RESPONSE=true
+ POWERTOOLS\$1TRACER\$1CAPTURE\$1ERROR=true
+ POWERTOOLS\$1METRICS\$1NAMESPACE=ServerlessGreeting

For definitions and additional details about the environment variables, see the [Powertools for AWS Lambda references](https://awslabs.github.io/aws-lambda-powertools-dotnet/references/) website.

### 2. Functions.cs
<a name="functionscs"></a>

`Functions.cs` is a class file containing a C\$1 method that's mapped to a single function declared in the template file. The Lambda function responds to `HTTP Get` methods from API Gateway. The following is an example of the `Functions.cs` file:

```
public class Functions
{
    [Logging(LogEvent = true, CorrelationIdPath = CorrelationIdPaths.ApiGatewayRest)]
    [Metrics(CaptureColdStart = true)]
    [Tracing(CaptureMode = TracingCaptureMode.ResponseAndError)]
    public APIGatewayProxyResponse Get(APIGatewayProxyRequest request, ILambdaContext context)
    {
        Logger.LogInformation("Get Request");

        var greeting = GetGreeting();

        var response = new APIGatewayProxyResponse
        {
            StatusCode = (int)HttpStatusCode.OK,
            Body = greeting,
            Headers = new Dictionary (string, string) { { "Content-Type", "text/plain" } }
        };

        return response;
    }

    [Tracing(SegmentName = "GetGreeting Method")]
    private static string GetGreeting()
    {
        Metrics.AddMetric("GetGreeting_Invocations", 1, MetricUnit.Count);

        return "Hello Powertools for AWS Lambda (.NET)";
    }
}
```

### 3. aws-lambda-tools-defaults.json
<a name="functionscs"></a>

`aws-lambda-tools-defaults.json` provides the default values for the AWS deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI. The following is an example of the `aws-lambda-tools-defaults.json` file included with this project:

```
{
  "profile": "Default",
  "region": "us-east-1",
  "configuration": "Release",
  "s3-prefix": "ServerlessPowertools/",
  "template": "serverless.template",
  "template-parameters": ""
}
```

## Deploying the Serverless Application
<a name="deploy-the-serverless-application"></a>

To deploy your serverless application complete the following steps

1. From the **Solution Explorer**, open the context menu for (right click) your project and choose **Publish to AWS Lambda** to open the **Publish AWS Serverless Application** dialog.

1. From the **Publish AWS Serverless Application** dialog, enter a name for the CloudFormation stack container in the **Stack Name** field.

1. In the **S3 Bucket** field, choose an Amazon S3 bucket that your application bundle will upload to or choose the **New...** button and enter the name of a new Amazon S3 bucket. Then choose **Publish** to publish to deploy your application.
**Note**  
Your CloudFormation stack and Amazon S3 Bucket must exist in the same AWS region. The remaining settings for your project are defined in the `serverless.template` file.  
![\[Image of the Publish AWS Serverless Application dialog.\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/lambda-upload-serverless-03192024.png)

1. The **Stack** view window opens during the publishing process, when deployment is complete the **Status** field displays: `CREATE_COMPLETE`.  
![\[Image of the deployment stack view window in visual studio.\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/lambda-upload-stackview-03192024.png)

## Test the Serverless Application
<a name="test-the-serverless-application"></a>

When the stack creation is complete, you can view your application using the **AWS Serverless URL**. If you've completed this tutorial without adding any additional functions or parameters, accessing your AWS serverless URL displays the following phrase in your web browser: `Hello Powertools for AWS Lambda (.NET)`.

# Tutorial: Creating an Amazon Rekognition Lambda Application
<a name="lambda-rekognition-example"></a>

This tutorial shows you how to create an Lambda application that uses Amazon Rekognition to tag Amazon S3 objects with detected labels.

For prerequisites and information about setting up the AWS Toolkit for Visual Studio, see [Using the AWS Lambda Templates in the AWS Toolkit for Visual Studio](lambda-index.md).

## Create a Visual Studio .NET Core Lambda Image Rekognition Project
<a name="create-a-visual-studio-net-core-lam-image-rekognition-project"></a>

The following procedure describes how to create an Amazon Rekognition Lambda application from the AWS Toolkit for Visual Studio.

**Note**  
Upon creation, your application has a solution with two projects: the source project that contains your Lambda function code to deploy to Lambda, and a test project using xUnit for testing your function locally.  
Sometimes Visual Studio can't find all NuGet references for your projects. This is because blueprints require dependencies that must be retrieved from NuGet. When new projects are created, Visual Studio only pulls in local references and not remote references from NuGet. To fix NuGet errors: right-click your references and choose **Restore Packages**.

1. From Visual Studio expand the **File** menu, expand **New**, then choose **Project**.

1. In the **New Project** dialog box, ensure that the **Language**, **Platform**, and **Project type** drop-down boxes are set to "All ..." and enter **aws lambda** in the **Search** field.

1. Select the **AWS Lambda with Tests (.NET Core - C\$1)** template.

1. Click **Next** to open the **Configure your new project** dialog.

1. From the **Configure your new project** dialog, enter "ImageRekognition" for the **Name**, then complete the remaining fields to your preference. Choose the **Create** button to proceed to the **Select Blueprint** dialog.

1. From the **Select Blueprint** dialog, choose the **Detect Image Labels** blueprint, then choose **Finish** to create the Visual Studio project.
**Note**  
This blueprint provides code for listening to Amazon S3 events and uses Amazon Rekognition to detect labels and add them to the S3 object as tags.

## Reviewing Project Files
<a name="examine-the-files"></a>

The following sections examine these project files:

1. `Function.cs`

1. `aws-lambda-tools-defaults.json`

### 1. Function.cs
<a name="functioncs"></a>

Inside the `Function.cs` file, the first segment of code is the assembly attribute, located at the top of the file. By default, Lambda only accepts input parameters and return types of type `System.IO.Stream`. You must register a serializer to use typed classes for input parameters and return types. The assembly attribute registers the Lambda JSON serializer, which uses `Newtonsoft.Json` to convert streams to typed classes. You can set the serializer at the assembly or method level.

The following is an example of the assembly attribute:

```
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
```

The class has two constructors. The first is a default constructor that is used when Lambda invokes your function. This constructor creates the Amazon S3 and Amazon Rekognition service clients. The constructor also retrieves the AWS credentials for these clients from the IAM role you assign to the function when you deploy it. The AWS Region for the clients is set to the region your Lambda function is running in. In this blueprint, you only want to add tags to the Amazon S3 object if the Amazon Rekognition service has a minimum level of confidence about the label. This constructor checks the environment variable `MinConfidence` to determine the acceptable confidence level. You can set this environment variable when you deploy the Lambda function.

The following is an example of the first class constructor in `Function.cs`:

```
public Function()
{
    this.S3Client = new AmazonS3Client();
    this.RekognitionClient = new AmazonRekognitionClient();

    var environmentMinConfidence = System.Environment.GetEnvironmentVariable(MIN_CONFIDENCE_ENVIRONMENT_VARIABLE_NAME);
    if(!string.IsNullOrWhiteSpace(environmentMinConfidence))
    {
        float value;
        if(float.TryParse(environmentMinConfidence, out value))
        {
            this.MinConfidence = value;
            Console.WriteLine($"Setting minimum confidence to {this.MinConfidence}");
        }
        else
        {
            Console.WriteLine($"Failed to parse value {environmentMinConfidence} for minimum confidence. Reverting back to default of {this.MinConfidence}");
        }
    }
    else
    {
        Console.WriteLine($"Using default minimum confidence of {this.MinConfidence}");
    }
}
```

The following example demonstrates how the second constructor can be utilized for testing. The test project configures its own S3 and Rekognition clients and passes them in:

```
public Function(IAmazonS3 s3Client, IAmazonRekognition rekognitionClient, float minConfidence)
{
    this.S3Client = s3Client;
    this.RekognitionClient = rekognitionClient;
    this.MinConfidence = minConfidence;
}
```

The following is an example of the `FunctionHandler` method inside the `Function.cs` file.

```
public async Task FunctionHandler(S3Event input, ILambdaContext context)
{
    foreach(var record in input.Records)
    {
        if(!SupportedImageTypes.Contains(Path.GetExtension(record.S3.Object.Key)))
        {
            Console.WriteLine($"Object {record.S3.Bucket.Name}:{record.S3.Object.Key} is not a supported image type");
            continue;
        }

        Console.WriteLine($"Looking for labels in image {record.S3.Bucket.Name}:{record.S3.Object.Key}");
        var detectResponses = await this.RekognitionClient.DetectLabelsAsync(new DetectLabelsRequest
        {
            MinConfidence = MinConfidence,
            Image = new Image
            {
                S3Object = new Amazon.Rekognition.Model.S3Object
                {
                    Bucket = record.S3.Bucket.Name,
                    Name = record.S3.Object.Key
                }
            }
        });

        var tags = new List();
        foreach(var label in detectResponses.Labels)
        {
            if(tags.Count < 10)
            {
                Console.WriteLine($"\tFound Label {label.Name} with confidence {label.Confidence}");
                tags.Add(new Tag { Key = label.Name, Value = label.Confidence.ToString() });
            }
            else
            {
                Console.WriteLine($"\tSkipped label {label.Name} with confidence {label.Confidence} because maximum number of tags reached");
            }
        }

        await this.S3Client.PutObjectTaggingAsync(new PutObjectTaggingRequest
        {
            BucketName = record.S3.Bucket.Name,
            Key = record.S3.Object.Key,
            Tagging = new Tagging
            {
                TagSet = tags
            }
        });
    }
    return;
}
```

 `FunctionHandler` is the method Lambda calls after it constructs the instance. Notice that the input parameter is of type `S3Event` and not a `Stream`. You can do this because of the registered Lambda JSON serializer. The `S3Event` contains all the information about the event triggered in Amazon S3. The function loops through all the S3 objects that were part of the event and tells Rekognition to detect labels. After the labels are detected, they are added as tags to the S3 object.

**Note**  
The code contains calls to `Console.WriteLine()`. When the function is running in Lambda, all calls to `Console.WriteLine()` redirect to Amazon CloudWatch Logs.

### 2. aws-lambda-tools-defaults.json
<a name="toolsdefaults"></a>

The `aws-lambda-tools-defaults.json` file contains default values that the blueprint has set to prepopulate some of the fields in the deployment wizard. It's also helpful in setting command-line options for integration with the .NET Core CLI.

To access the .NET Core CLI integration, navigate to the function's project directory and type **dotnet lambda help**.

**Note**  
The function handler indicates what method for Lambda to call in response to the invoked function. The format of this field is: `<assembly-name>::<full-type-name>::<method-name>`. The namespace must be included with the type name.

## Deploy the Function
<a name="deploy-the-function"></a>

The following procedure describes how to deploy your Lambda function.

1. From the **Solution Explorer**, right-click the Lambda project and choose **Publish to AWS Lambda** to open the **Upload to AWS Lambda** window.
**Note**  
The preset values are retrieved from the `aws-lambda-tools-defaults.json` file.

1. From the **Upload to AWS Lambda** window, enter a name into the **Function Name** field, then choose the **Next** button to advance to the **Advanced Function Details** window.
**Note**  
This example, uses the **Function Name** **ImageRekognition**.  
![\[AWS Lambda function upload interface with package type, runtime, and configuration options.\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/lambda-upload-imgrek-03192024.png)

1. From the **Advanced Function Details** window, select an IAM role that gives permission for your code to access your Amazon S3 and Amazon Rekognition resources.
**Note**  
If you're following along with this example, select the `AWSLambda_FullAccess` role.

1. Set the environment variable `MinConfidence` to 60, then choose **Upload** to launch the deployment process. The publishing process is complete when the **Function** view displays in the **AWS Explorer**.  
![\[AWS Lambda function configuration interface showing permissions, execution, and environment settings.\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/lambda-upload-imgrek-advanced-03192024.png)

1. Following a successful deployment, configure Amazon S3 to send its events to your new function by navigating to the **Event Sources** tab.

1. From the **Event Sources** tab, choose the **Add** button, then select the Amazon S3 bucket to connect with your Lambda function.
**Note**  
The bucket must be in the same AWS region as your Lambda function.

## Test the Function
<a name="test-the-function"></a>

Now that the function is deployed and an S3 bucket is configured as an event source for it, open the S3 bucket browser from the **AWS Explorer** for the bucket you selected. Then upload some images.

When the upload is complete, you can confirm that your function ran by looking at the logs from your function view. Or, right-click the images in the bucket browser and choose **Properties**. On the **Tags** tab, you can view the tags that were applied to your object.

![\[Properties window showing metadata tags for an image file in a cloud storage bucket.\]](http://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/images/lambda-object-properties.png)


# Tutorial: Using Amazon Logging Frameworks with AWS Lambda to Create Application Logs
<a name="cw-log-frameworks"></a>

You can use Amazon CloudWatch Logs to monitor, store, and access your application’s logs. To get log data into CloudWatch Logs, use an AWS SDK or install the CloudWatch Logs agent to monitor certain log folders. CloudWatch Logs is integrated with several popular .NET logging frameworks, simplifying work flows.

To get started working with CloudWatch Logs and .NET logging frameworks, add the appropriate NuGet package and CloudWatch Logs output source to your application, then use your logging library as you normally would. This enables your application to log messages with your .NET framework, sending them to CloudWatch Logs, displaying your application’s log messages in the CloudWatch Logs console. You can also set up metrics and alarms from the CloudWatch Logs console, based on your application’s log messages.

Supported .NET logging frameworks include:
+ **NLog**: To view, see the [nuget.org NLog package](https://www.nuget.org/packages/AWS.Logger.NLog).
+ **Log4net**: To view, see the [nuget.org Log4net package](https://www.nuget.org/packages/AWS.Logger.NLog).
+ **ASP.NET Core logging Framework**: To view, see the [nuget.org ASP.NET Core logging Framework package](https://www.nuget.org/packages/AWS.Logger.AspNetCore/).

The following is an example of an `NLog.config` file that enables both CloudWatch Logs and the console as output for log messages by adding the `AWS.Logger.NLog` NuGet package, and AWS target into `NLog.config`.

```
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      throwExceptions="true">
  <targets>
    <target name="aws" type="AWSTarget" logGroup="NLog.ConfigExample" region="us-east-1"/>
    <target name="logfile" xsi:type="Console" layout="${callsite} ${message}" />
  </targets>
  <rules>
    <logger name="*" minlevel="Info" writeTo="logfile,aws" />
  </rules>
</nlog>
```



The logging plugins are all built on top of the AWS SDK for .NET and authenticate your AWS credentials in a process similar to the SDK. The following example details permissions required by the logging plugin credentials to access CloudWatch Logs:

**Note**  
The AWS .NET logging plugins are an open source project. For additional information, samples, and instructions, see the [samples](https://github.com/aws/aws-logging-dotnet/tree/master/samples) and [instructions](https://github.com/aws/aws-logging-dotnet/blob/master/README.md) topics in the [AWS Logging .NET GitHub](https://github.com/aws/aws-logging-dotnet) repository.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogGroups"
      ],
      "Resource": [
        "arn:aws:logs:*:*:*"
      ]
    }
  ]
}
```

------