Package and Upload a Lambda Function with the AWS CLI
The AWS console is great for creating, modifying and visualizing your AWS resources, services and infrastructure. However, if you need automation and repeatability, the AWS CLI is where it’s at.
For this tutorial, we’ll use .NET as the reference technology. Although, most of this tutorial can be used with other languages like, Python, Node.js, Go, etc. When you see references to .NET, feel free to swap in your programming language of choice.
Photo by Bill Fairs on Unsplash
The Solution
In this tutorial, we will package and upload an AWS Lambda function. We’ll also create a Lambda function URL, the Lambda function execution role, and the supporting policies, all using the the AWS CLI.
Remember, for any example solution from AWS with .NET, we focus on the code that exemplifies the problem we are trying to solve. We don’t include logging, input validation, exception handling, etc., and we embed the configuration data within classes instead of using environment variables, configuration files, key/value stores and the like. These items should not be skipped for proper solutions.
Prerequisites
To complete this tutorial, you will need to download the AWS CLI and configure your environment. You will also need to create an IAM user with programmatic access to AWS Lambda and IAM with the appropriate permissions to create and modify Lambda functions, create Lambda function URLs, create IAM roles and IAM policies.
Warning: some AWS services may have fees associated with them.
Our Dev Environment
This tutorial was developed using Ubuntu 20.04 and AWS CLI v2. Some commands/constructs may vary across systems.
Publishing Your Lambda Function
Skip to the next section, “Packaging an AWS Lambda Function” if you are not using .NET.
To publish the .NET app, use the following .NET CLI command. Note the MSBuild GenerateRuntimeConfigurationFiles parameter. Setting GenerateRuntimeConfigurationFiles to true will instruct the .NET CLI to generate the (appname).runtimeconfig.json file that AWS Lambda requires.
$ dotnet publish -c Release -o function /p:GenerateRuntimeConfigurationFiles=true
Packaging an AWS Lambda Function
We’ll need to change the directory to where the code of our Lambda function lives. For some languages, like Node.js, the code could be one file like, index.js. For the .NET Lambda Function, we published the Lambda Function to the “function” directory. Let’s cd into the function directory and zip all the directory’s contents with the following command.
$ zip ../function.zip *
With that complete, the AWS Lambda function is packaged and ready to be uploaded.
Create the Lambda Function Execution Role
With the deployment package ready, we now need to create the execution role.
The execution role has two policies. The trust policy defines the principal that can assume the role. The second policy defines the services and resources that the role has access to.
Let’s create a file named trust-policy.json with the following content.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
We’ll then use the following command to create the execution role, using the trust-policy.json file to create the trust policy.
$ aws iam create-role \
--role-name basic-lambda-execution-role \
--assume-role-policy-document file://trust-policy.json
With the role completed, we then need to define the permissions for the Lambda function. For this tutorial we’ll attach the AWS AWSLambdaBasicExecutionRole managed policy. The AWSLambdaBasicExecutionRole simply grants the Lambda function permission to create logs in Amazon CloudWatch.
Let’s use the following command to attach the AWSLambdaBasicExecutionRole policy to the role named, “basic-lambda-execution-role”.
$ aws iam attach-role-policy \
--role-name basic-lambda-execution-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
That completes the Lambda function execution role.
Create the Lambda Function with the AWS CLI
With the Lambda function execution role completed and the deployment package ready to be uploaded, we can now create the Lambda function using the AWS CLI with the command below.
A couple notes about the parameters:
Runtime: Lambda supports various languages through runtimes. You can get more info on AWS Lambda runtimes here. In this example we are using the dotnet6 runtime (supporting .NET 6)
Handler: The name of the method that acts as the handler for the calls to the Lambda function.
.NET 6 Handler Subtleties
You can skip to the CLI call below if you don’t use .NET 6.
As of the .NET 6 release of the Lambda runtime, you have two options when authoring an AWS Lambda function in .NET: executable assemblies and class library.
Executable assemblies (minimal API/top level statements): the handler mapping is specified as using only the assembly name. In this case, an example handler parameter would be:
BasicLambda
Class Library: the handler mapping is specified as, AssemblyName::Type::Method. In this case, an example handler parameter would be:
BasicLambda::BasicLambda.Handler::Handle.
For this example we’ll use a class library and the “handler” of: BasicLambda::BasicLambda.Handler::Handle
You can get more info on the AWS Lambda Programming Model here.
$ aws lambda create-function --function-name basic-lambda \
--runtime dotnet6 \
--handler BasicLambda::BasicLambda.Handler::Handle \
--description "basic lambda function with a url" \
--zip-file fileb://function.zip \
--role arn:aws:iam::(aws-account-number):role/basic-lambda-execution-role
When completed, you should see output that includes a JSON object with attributes of FunctionName, FunctionArn, Runtime, etc.
Create the Lambda Function URL with AWS CLI
First, we need to create the Lambda URL. We can do so with this command:
$ aws lambda create-function-url-config --function-name basic-lambda --auth-type NONE
When completed, you should see output that includes a JSON object with attributes of FunctionUrl, FunctionArn, AuthType, etc.
Next, we need to set permissions to be able to access the URL. Note: in this tutorial we allow public access and set function-url-auth-type to NONE. Scrutinize your security needs and set the URL permissions accordingly.
$ aws lambda add-permission --function-name basic-lambda \
--statement-id FunctionURLAllowPublicAccess \
--action lambda:InvokeFunctionUrl \
--principal "*" \
--function-url-auth-type NONE \
When completed, you should see output that includes a JSON object with the attribute of Statement.
Summary
We have concluded this tutorial where you have learned how to package and upload a .NET Lambda function. You also learned how to create a Lambda Function URL, an IAM role and attach an IAM policy using the AWS CLI.
Want to know more about the tech in this tutorial? Checkout these resources:
.NET CLI, AWS CLI, Configuring the AWS CLI, AWS Lambda, AWS Lambda CLI