Deploying AWS Lambda function from scratch

Deploying AWS Lambda function from scratch

September 11, 2023
Get tips and best practices from Develeap’s experts in your inbox

Serverless computing has transformed the way we build and deploy applications, and AWS Lambda stands at the forefront of this revolution. In this article, we’ll explore the world of AWS Lambda and dive into the fundamentals such as: What Lambda is, How to write Lambda functions, how to package and deploy them, and how to test them.

As a DevOps Engineer and Head of Partnerships at Develeap, I’ll share insights and code examples to demonstrate how to orchestrate serverless functions (AWS Lambda) not just as a best practice but as a necessity in modern application development.

As part of my job, I see a wide range of customers’ case studies that leverage the power of AWS Lambda. I have also managed Develeap’s process of obtaining the AWS Lambda Service Delivery badge, among many others. 

What is AWS Lambda?

Before diving into orchestration, let’s understand the core concept of AWS Lambda.

AWS Lambda is a computing service offered by Amazon Web Services (AWS) that allows you to run code in response to events and triggers without the need to provision or manage servers. It enables you to build serverless applications by executing code in a highly scalable and cost-effective manner. 

Lambda functions are the foundation of serverless computing, offering the following key features:

Event-Driven Trigger: Lambda functions are triggered by various AWS services, such as API Gateway, S3, DynamoDB, and more, in response to events like HTTP requests, file uploads, or even scheduled events (cron jobs).

Event Bridge: AWS Lambda can seamlessly integrate with Amazon EventBridge, a serverless event bus service. EventBridge allows you to connect various AWS services, custom applications, and third-party SaaS applications to Lambda functions. It provides the capability to orchestrate complex workflows and trigger Lambda functions based on events from different sources, enhancing the flexibility of your serverless applications.

Scalability: Lambda automatically scales your code in response to the number of incoming requests or events, ensuring optimal performance and resource utilization.

No Server Management: You don’t need to worry about provisioning servers, patching, or maintenance, as AWS manages the infrastructure for you.
Pay-Per-Use: You are billed only for the compute time consumed by your Lambda functions, making it a cost-efficient solution.\

How to Write a Lambda Function

Writing a Lambda function involves defining your business logic within the lambda_handler function and specifying the event sources that trigger this function.

Now that we understand the basics, let’s explore how to write a Lambda function. 

First, let’s create a lambda_function.py file, below is an example of a simple Lambda function written in Python:

import json


def lambda_handler(event, context):
   # Parse the input event
   body = json.loads(event['body'])


   # Your custom logic here
   result = {
       "message": "Hello, " + body['name'] + "!"
   }


   # Return a response
   response = {
       "statusCode": 200,
       "body": json.dumps(result)
   }


   return response
  • The event parameter contains information about the event that triggered the Lambda function. 
  • The context parameter provides runtime information about the Lambda function execution environment.

In the example Lambda function above, we use the event input to extract data from an incoming HTTP request’s body. We then perform custom logic, in this case, creating a personalized greeting message. Finally, we construct a response object that includes an HTTP status code and a JSON body, which is returned as the function’s output.

Understanding how to work with event and context inputs is crucial when designing Lambda functions, as they provide the necessary context and data to respond effectively to various events and triggers.

Packaging and Deploying a Lambda Function with Terraform

Once you’ve written your Lambda function, packaging it correctly for deployment with Terraform is crucial. 

Here’s an example of how to package and deploy a Lambda function using Terraform:

First, create main.tf file,

1. Provide your AWS credentials:

provider "aws" {
 access_key = "<YOUR_ACCESS_KEY>"
 secret_key = "<YOUR_SECRET_KEY>"
 region     = "us-east-1" # Specify your desired AWS region
}

In this section, you specify your AWS access and secret keys, along with the desired AWS region. These credentials allow Terraform to authenticate and interact with AWS services.

NOTE: This is for testing purposes and should not be uploaded to git, hard-coded credentials are not recommended in any Terraform configuration and risks secret leakage should this file ever be committed to a public version control system.
for more information about provider configuration : https://registry.terraform.io/providers/hashicorp/aws/latest/docs#provider-configuration

2. Define your Lambda parameters:

locals {
 function_name = "hello-world-lambda"
 handler       = "lambda_function.lambda_handler"
 runtime       = "python3.8"
 timeout       = 6
 zip_file      = "hello-world-lambda.zip"
}

Here, you define local variables that store various parameters for your Lambda function. These parameters include the function name, handler, runtime, timeout, and the name of the zip file that will contain your Lambda code.

3. Create a zip file with your Python code

data "archive_file" "zip" {
 source_dir = path.module
 output_path = "${path.module}/${local.zip_file}"
 type        = "zip"


 excludes = [
   ".terraform",
   ".terraform.lock.hcl",
   "terraform.tfstate",
   "terraform.tfstate.backup",
   "main.tf",
   # Add any other files or directories to exclude
 ]
}

This section uses the archive_file data source to create a zip file that contains your Python code. It specifies the source directory, output path, and files/directories to exclude from the zip archive.

4. Defining the IAM policy document for lambda execution:

data "aws_iam_policy_document" "default" {
 version = "2012-10-17"


 statement {
   actions   = ["sts:AssumeRole"]
   effect    = "Allow"
   principals {
     type        = "Service"
     identifiers = ["lambda.amazonaws.com"]
   }
 }
}

In this part, you define an IAM policy document that allows Lambda to assume the required role for execution. This policy document specifies that Lambda is allowed to assume the role.

5. Create an IAM Role for Lambda Execution:

resource "aws_iam_role" "default" {
 name               = "lambda_execution_role"
 assume_role_policy = data.aws_iam_policy_document.default.json
}

Here, you create an IAM role named lambda_execution_role based on the previously defined policy document. This role allows Lambda functions to assume it.

6. Attach an IAM policy for lambda execution:

resource "aws_iam_policy" "lambda_execution_policy" {
 name        = "LambdaExecutionPolicy"
 description = "Custom Lambda execution policy"


 policy = jsonencode({
   Version = "2012-10-17",
   Statement = [
     {
       Action = [
         "lambda:InvokeFunction",
         "lambda:GetFunctionConfiguration",
         // Add any other necessary actions here
       ],
       Effect   = "Allow",
       Resource = "*",
     },
   ],
 })
}

This section attaches the IAM policy (aws_iam_policy.lambda_execution_policy) to the IAM role (aws_iam_role.default) you created earlier. It grants the necessary permissions for Lambda execution.

7. Create the Lambda Function:

resource "aws_lambda_function" "default" {
 function_name    = local.function_name
 handler          = local.handler
 runtime          = local.runtime
 timeout          = local.timeout
 filename         = local.zip_file
 source_code_hash = data.archive_file.zip.output_base64sha256
 role             = aws_iam_role.default.arn
}

Finally, you create the Lambda function using the specified parameters. This includes the function name, handler, runtime, timeout, zip file, source code hash, and role. You can also set optional environmental variables for your Lambda function.

This Terraform code provides a comprehensive example of how to package and deploy a Lambda function with Terraform, ensuring that it’s associated with the necessary IAM roles and policies for execution in AWS.

8. Run terraform init: 

When you run terraform init, Terraform initializes your working directory. This command downloads any necessary providers and modules required for your configuration. It prepares your environment for managing your infrastructure as code. It’s typically the first command you run when working with Terraform in a new directory or after making significant changes that require downloads.

9. Run terraform plan:

After initializing your environment, you execute a terraform plan. This command performs a “dry run” of your Terraform configuration. It analyzes your code and the current state of your infrastructure to determine what changes need to be made to bring your infrastructure in line with your configuration. It provides you with a preview of the changes Terraform intends to apply. This is a crucial step because it helps you understand the impact of your changes before they are applied.

10. Apply Your Terraform Configuration: 

Run terraform apply to deploy your Lambda function and any associated AWS resources. Terraform will handle the deployment process of your lambda function.

Test and Result

1. Log into your AWS account and navigate to the region you chose to create your resources in Terraform (for our example is us-east-1) and navigate to Lambda.

2. Click on hello-world-lambda

3. Navigate to Test:

4. Configure the test, give it a name, and add the event JSON:

{
 "body": "{\"name\":\"John\"}"
}

5. Hit on test!

6. Clean-up:
To delete the AWS resources you’ve provisioned using Terraform, you can use the terraform destroy command. This command will tear down and remove all the resources defined in your Terraform configuration, bringing your AWS infrastructure back to its initial state or as defined in your configuration.

Conclusion

By following these steps, you can seamlessly package and deploy your Lambda function using Terraform, making it an integral part of your infrastructure-as-code workflow.

AWS Lambda is the heart of serverless computing, enabling developers to build scalable and cost-effective applications. Understanding Lambda’s fundamentals, writing Lambda functions, and packaging them correctly are essential steps in the serverless journey.