AWS Lambda: A Hands-On Beginner's Guide
Tags: aws, lambda, awslambda, serverless
Published: 2023-09-28 07:48:22

In this blog post, I'll begin by providing a brief overview of serverless computing. Then, I'll introduce AWS Lambda, an essential component of serverless architecture. I'll explain how Lambda functions operate and explore their various use cases and benefits, as well as their limitations.

I'll also offer practical examples of Lambda functions, including:

- Creating a basic "Hello World" Lambda function.
- Establishing a connection between Lambda and an RDS database.
- Using Lambda to send messages to a Slack channel.

**What is Serverless Computing**

Before delving into Serverless computing, let's take a moment to understand server-based computing. In server-based computing, you typically set up your infrastructure and then deploy your code across multiple tiers. In the deployment architecture below, we can visualize a 3-tier system where the frontend code resides on a host, often running a web server. The backend code operates on a separate server, usually an application server, and there's a database server as well. In this setup, developers not only focus on writing code but also need to manage the infrastructure.



![Server-based](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/twcamb0pazoppx45kqib.jpg)

Now, in Serverless computing, developers can concentrate solely on their development tasks, leaving AWS to handle the heavy lifting associated with infrastructure management. Using the same examples as before, both frontend and backend codes are deployed as Lambda functions. AWS RDS, a managed database service, is utilized to store data. In this scenario, developers can primarily focus on writing code rather than designing, implementing, and maintaining the infrastructure.

![Serverless](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e47m30hoynma894ruup5.jpg)


**Server-based vs Serverless computing**

Server-based computing involves managing infrastructure tiers, while serverless computing allows developers to focus solely on code without infrastructure concerns.

**Server-based:**

- Requires server provisioning and management.
- More control over infrastructure.
- Continuous server costs, regardless of usage.
- More suited for specific, complex requirements.

**Serverless:**

- Code-focused, no server management.
- Cloud provider handles infrastructure.
- Pay only for resource usage.
- Ideal for solving business problems.

**What is AWS Lambda?**

AWS Lambda, as a serverless compute service, empowers developers to execute code without the hassle of server provisioning. Here are some key aspects of AWS Lambda:

- Streamlined code deployment without the need for infrastructure setup.
- Effortless scalability, accommodating varying workloads from low to high request volumes.
- Cost-efficiency through precise billing based on compute usage down to the millisecond.
- Code performance optimization by adjusting memory allocation.
- Swiftly respond to demand spikes with Provisioned Concurrency.
- Developer-friendly with support for multiple programming languages.
- Seamless integration with other cloud services and event triggers.
- Automatic scaling and load balancing, reducing operational complexities.
- Empowers developers to concentrate on solving business challenges rather than server management.
- Enhances agility and flexibility in application development and deployment.

**Pros and Corns**

Just like anything else in life, AWS Lambda comes with its own set of advantages and disadvantages. Here are a few considerations to keep in mind:

**Pros:**
- Cost-effectiveness: Pay only for actual usage, no idle server costs.
- Scalability: Automatically scale with increased workload.
- Reduced Operational Overhead: No server maintenance.


**Corns:**

- Cold Starts: Slight delay when a function is invoked for the first time.
- Limited Execution Time: Functions have a maximum execution time.
- Vendor Lock-in: Code may become tightly coupled to the chosen serverless provider.

**Use cases**

AWS Lambda presents a multitude of diverse use cases, making it incredibly valuable for anyone looking to explore the world of serverless computing. Here are a few noteworthy ones you wouldn't want to overlook:

- Data Processing: Perform ETL tasks, data validation, and transformation.
- Real-time File Processing: Automatically process files upon upload.
- Backend for Mobile and Web Apps: Create scalable backends for applications.
- IoT Data Processing: Handle data from Internet of Things devices.
- Automation: Execute tasks on schedule or in response to events.


If you're reading this now, I'm sure you're eager to dive into more advanced topics. So, let's roll up our sleeves and delve into a few Lambda examples to get hands-on experience.


**Getting started with AWS Lambda**

To get started with AWS Lambda, log in to your AWS account and access the AWS Lambda dashboard. You'll find two main components:

- **Functions**: These are small, stateless computing units that execute code in response to events, making them perfect for tasks like microservices and automation.
- **Applications**: These enable serverless, event-driven computing, offering scalable and cost-effective solutions.

For today's focus, I'll delve into AWS Lambda functions. Now, let's dive in and explore with some practical examples.

**Creating a basic "Hello World" Lambda function.**

Let's dive into our first example

**Step 1:** Create a Function

Click on "Create Function" in the AWS Lambda dashboard.

**Step 2:** Choose Author From Scratch

You'll be presented with three options:

- Author from Scratch
- Use a Blueprint
- Container Image

Select "Author from Scratch."

**Step 3:** Provide Basic Information

Fill in the following details:

Function Name: Hello-World-Lambda
Runtime: Select "Python 3.11" (AWS Lambda supports multiple runtimes like .NET, Go, Java, Node.js, and Ruby).

Keep the other default values and click on "Create Function."

**Step 4:** Function Created

Congratulations, you've successfully created your first Lambda function!

Step 5: Add Code to the Function

By default, AWS Lambda provides you with a basic code template. You'll see the following Python code:

```
import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

**Step 6:** Test the Function

To test the Lambda function, click on "Test." This will mimic an event to trigger your function. Then, click "Invoke."

**Step 7:** View the Output

Congratulations! You'll see the following output:
Response

```
Response
{
  "statusCode": 200,
  "body": "\"Hello from Lambda!\""
}
```

You've successfully created and tested your "Hello World" AWS Lambda function. This is just the beginning of what you can achieve with AWS Lambda for serverless computing.

**Understanding the lambda_handler Function**

In AWS Lambda, think of the lambda_handler function as the main starting point for your code. When an event triggers your Lambda function, this function is automatically called.

It's somewhat like a detective gathering clues. The event parameter holds information about what caused your Lambda function to activate. It's your way of figuring out what's happening.

The context parameter is like a toolbox with tools for the job. It provides details such as how much memory you can use and how long your function can work.

In essence, lambda_handler is your function's manager, examining incoming events and using the tools from the context to get the job done.


**Establishing a connection between Lambda and an RDS database.**

Let's establish a connection between AWS Lambda and an RDS database, which promises to be an intriguing example. If you don't already have an RDS test database, you can create one to test this out. Now, let's take a look at the Lambda code to make this connection.

**Step 1** : Begin by creating the function.

**Step 2** :Copy the provided code.

```
import sys
import logging
import pymysql

logger = logging.getLogger()
logger.setLevel(logging.INFO)

# RDS settings
db_host = "<Include host name>"
db_user = "<User>"
db_password = "<Password>"
db_name = "<Database Name>"  

try:
    conn = pymysql.connect(
        host=db_host,
        user=db_user,
        password=db_password,
        db=db_name,
        connect_timeout=5
    )
except pymysql.MySQLError as e:
    logger.error("ERROR: Unexpected error: Could not connect to MySQL instance.")
    logger.error(e)
    sys.exit()

logger.info("SUCCESS: Connection to RDS for MySQL instance succeeded")

def lambda_handler(event, context):
    """
    This function executes a SQL query on the RDS database and returns the result.
    """
    try:
        # Define the query to execute
        query = "SELECT name FROM employee LIMIT 1;"

        with conn.cursor() as cursor:
            cursor.execute(query)
            result = cursor.fetchone()

        if result:
            employee_name = result[0]
            return {
                "statusCode": 200,
                "body": f"Hello from Lambda! Employee name: {employee_name}"
            }
        else:
            logger.warning("No records found in the employee table.")
            return {
                "statusCode": 404,
                "body": "No records found in the employee table."
            }
    except Exception as e:
        logger.error(f"Error: {str(e)}")
        return {
            "statusCode": 500,
            "body": f"Error: {str(e)}"
        }

```

**Step 3** :Click the "Deploy" button.

**Step 4** :Now, it's time to test the code. However, you might 

encounter an error:
Error Message:

```
Response
{
  "errorMessage": "Unable to import module 'lambda_function': No module named 'pymysql'",
  "errorType": "Runtime.ImportModuleError",
  "requestId": "afea96b0-3996-4576-95de-477da4d2223c",
  "stackTrace": []
}
```

Let's package this program and configure the runtime correctly to resolve this issue.

Logging in to an EC2 and Ensuring Required Permissions are there.

Before proceeding, make sure you are logged in to your EC2 instance. Ensure you have the necessary permissions to perform tasks. If you encounter any issues, address permission concerns accordingly.

**Step 1:** Create a Directory Named 'Lambda-Connect_RDS'

**Step 2:** Navigate into the created directory and copy your Lambda code, naming the file 'Lambda-Connect_RDS.py'.

**Step 3:** Now, let's install the 'pymysql' Python library. Execute the following command:

```
pip3 install --target . pymysql
```

**Step 4:** Create a Zip File Comprising Your Python Code and Runtime Libraries:

```
zip -r Lambda-Connect_RDS.zip Lambda-Connect_RDS.py pymysql PyMySQL-1.1.0.dist-info
```

**Step 5:** With the zip file ready, you can proceed to upload it to Lambda.

**Step 6:** Create an S3 Bucket and Copy the Zip File to It:

To accomplish this, you can run the following command:

```
aws s3 cp Lambda-Connect_RDS.zip s3://indikacode/
```

**Step 7:** Navigate to the S3 bucket and verify that the zip file has been successfully copied.

**Step 8:** Copy the URL of the 'Lambda-Connect_RDS.zip' file.

**Step 9:** In the Lambda-Connect_RDS Lambda function settings, navigate to the 'Code' section, choose 'Upload from,' and provide the S3 location. Save this configuration to load your code into Lambda.

**Step 10:** Set the Correct Handler Name in the 'Runtime' Section:

Use 'Lambda-Connect_RDS.lambda_handler' as the handler name.

**Step 11:** Grant Lambda Permissions to Access the RDS Database:

Create an RDS role (e.g., AWSLambdaRDSFullAccess).
Navigate to IAM -> Roles -> Create role -> Choose 'AWS Service' as the trusted entity, 'Use case' as 'Lambda,' and add the 'AmazonRDSDataFullAccess' policy.
Next, in the Lambda function settings, navigate to 'Permissions' and edit the existing role to add 'LambdaRDSFullAccess' under 'Existing Role.'

**Step 12:** Configure VPC Settings:

Ensure that you have selected the correct VPC, subnets, and security groups to allow access to the RDS instance.

**Step 13:** Test the Function:

After completing these steps, test the function. You should see the expected output:

```
{
  "statusCode": 200,
  "body": "Hello from Lambda! Employee name: John Doe"
}
```

**Using Lambda to send messages to a Slack channel.**

Now the final exerise for this post.

**Step 1:** Before we proceed, create a Slack channel and obtain the Slack webhook URL, which you will use in the Lambda function. 

It should look something like this:

```
slack_webhook_url = "https://hooks.slack.com/services/<Details>"
```

**Step 2:** Now, let's create the Lambda function.

Name the Lambda function "Connect-Lambda-with-slack."

**Step 3:** We'll need to prepare the necessary files on an EC2 instance. Here's how:

Create a directory.
Inside this directory, create a Python file named "Connect-Lambda-with-slack.py" and add the following code:

```
import json
import requests

print('Loading function')

def lambda_handler(event, context):
    # Define the Slack webhook URL
    slack_webhook_url = "https://hooks.slack.com/services/<Details>"

    # Define the message you want to send to Slack
    message = {"text": "Sending best wishes from Lambda to Slack"}

    # Send the message to Slack
    response = requests.post(slack_webhook_url, data=json.dumps(message), headers={"Content-Type": "application/json"})

    # Check the response status code to confirm if the message was sent successfully
    if response.status_code == 200:
        print("Message sent to Slack successfully")
        return "Message sent to Slack successfully"
    else:
        print("Failed to send message to Slack")
        return "Failed to send message to Slack"
```
**Step 4**: Install the required libraries:

Run the following commands to install the "requests" library:

```
pip3 install --target . requests

```
**Step 5**: Create a zip package that includes your Python code and required libraries:

```
zip -r Connect-Lambda-with-slack.zip Connect-Lambda-with-slack.py urllib3 urllib3-2.0.5.dist-info idna idna-3.4.dist-info charset_normalizer charset_normalizer-3.2.0.dist-info bin certifi-2023.7.22.dist-info certifi requests requests-2.31.0.dist-info
```

**Step 6**: Copy the resulting zip file to an S3 bucket:

```
aws s3 cp Connect-Lambda-with-slack.zip s3://indikacode/
```

**Step 7:** Retrieve the URL of the "Connect-Lambda-with-slack.zip" file stored in your S3 bucket. This URL will be used to upload the code to the Lambda function.

**Step 8:** In the Lambda function's configuration, under the "Runtime" settings, set the handler to "Connect-Lambda-with-slack.lambda_handler."

**Step 9:** Perform a test of the Lambda function to ensure its functionality.

**Step 10:** Upon running the test, you will observe the following output, and the message will be sent to your designated Slack channel.

```
Response
"Message sent to Slack successfully"
```


![Slack Output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pp4hkwehdieebl5jeg3m.JPG)

Finally, we have reached the end of this post on AWS Lambda. We hope you found it informative and enjoyable.