3-deploying-serverless-applications-on-aws-using-terraform-and-docker.html

Deploying Serverless Applications on AWS Using Terraform and Docker

In today's fast-paced digital landscape, businesses are increasingly turning to serverless architectures to reduce overhead costs, improve scalability, and streamline deployment processes. Amazon Web Services (AWS) offers a robust platform for building serverless applications, while Terraform provides an excellent infrastructure as code (IaC) tool to automate the deployment of these applications. By combining Terraform with Docker, developers can create portable, efficient, and scalable serverless applications. In this article, we will explore how to deploy serverless applications on AWS using Terraform and Docker, complete with clear code examples and actionable insights.

Understanding Serverless Architecture

What is Serverless Computing?

Serverless computing allows developers to build and run applications without having to manage the underlying infrastructure. Instead of provisioning servers, developers can focus on writing code and deploying functions that respond to events. AWS Lambda is a prime example of a serverless computing service, enabling users to execute code in response to specific triggers, such as HTTP requests or database updates.

Advantages of Serverless Applications

  • Cost-Effective: Pay only for the compute time you consume.
  • Scalability: Automatically scales with demand, handling thousands of requests per second.
  • Reduced Operational Overhead: No need to manage servers or infrastructure.

Why Use Terraform and Docker?

Terraform for Infrastructure as Code

Terraform is an open-source tool that allows you to define and provision your infrastructure using a declarative configuration language. It enables you to manage cloud services through code, making it easier to version, share, and collaborate on infrastructure setups.

Docker for Containerization

Docker is a platform for developing, shipping, and running applications in containers. Containers package an application with its dependencies, ensuring it runs consistently across different environments. When used together with AWS Lambda, Docker allows you to deploy complex applications that require specific runtimes or dependencies.

Use Case: Building a Serverless API

In this example, we will create a simple serverless API using AWS Lambda and API Gateway, deploying it with Terraform and Docker. The API will respond to HTTP requests and return a JSON response.

Prerequisites

  • AWS Account: Ensure you have an active AWS account.
  • Terraform: Install Terraform on your local machine.
  • Docker: Install Docker to create container images.
  • AWS CLI: Install and configure the AWS CLI.

Step-by-Step Deployment Guide

Step 1: Create the Docker Image

First, let’s create a simple Node.js application that will run in a Docker container. Create a new directory and add the following files.

1.1 Create app.js

const http = require('http');

const requestHandler = (req, res) => {
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify({ message: 'Hello, Serverless World!' }));
};

const server = http.createServer(requestHandler);

const PORT = process.env.PORT || 3000;

server.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

1.2 Create Dockerfile

FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm install

COPY . .

CMD ["node", "app.js"]

1.3 Create package.json

{
  "name": "serverless-app",
  "version": "1.0.0",
  "main": "app.js",
  "dependencies": {
    "http": "^0.0.1"
  }
}

Step 2: Build and Test Your Docker Image

Navigate to your project directory in the terminal and build the Docker image.

docker build -t serverless-app .

Run the Docker container to test your application locally:

docker run -p 3000:3000 serverless-app

Visit http://localhost:3000 in your browser, and you should see the JSON response.

Step 3: Create Terraform Configuration

Next, we will configure Terraform to deploy our Dockerized application on AWS Lambda. Create a new directory for your Terraform files and add the following files.

3.1 Create main.tf

provider "aws" {
  region = "us-west-2"
}

resource "aws_lambda_function" "serverless_app" {
  function_name = "ServerlessApp"
  handler       = "app.handler"
  runtime       = "nodejs14.x"
  role          = aws_iam_role.lambda_exec.arn

  # Specify the Docker image
  image_uri = "${aws_ecr_repository.serverless_app.repository_url}:latest"

  memory_size = 128
  timeout     = 10
}

resource "aws_iam_role" "lambda_exec" {
  name = "lambda_exec"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action    = "sts:AssumeRole"
      Effect    = "Allow"
      Principal = {
        Service = "lambda.amazonaws.com"
      }
    }]
  })
}

resource "aws_ecr_repository" "serverless_app" {
  name = "serverless-app"
}

resource "aws_lambda_permission" "api_gateway" {
  statement_id  = "AllowExecutionFromAPIGateway"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.serverless_app.function_name
  principal     = "apigateway.amazonaws.com"
}

resource "aws_api_gateway_rest_api" "api" {
  name = "ServerlessAPI"
}

resource "aws_api_gateway_resource" "resource" {
  rest_api_id = aws_api_gateway_rest_api.api.id
  parent_id   = aws_api_gateway_rest_api.api.root_resource_id
  path_part   = "hello"
}

resource "aws_api_gateway_method" "method" {
  rest_api_id   = aws_api_gateway_rest_api.api.id
  resource_id   = aws_api_gateway_resource.resource.id
  http_method   = "GET"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "integration" {
  rest_api_id = aws_api_gateway_rest_api.api.id
  resource_id = aws_api_gateway_resource.resource.id
  http_method = aws_api_gateway_method.method.http_method

  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.serverless_app.invoke_arn
}

Step 4: Deploy with Terraform

Initialize Terraform and apply the configuration:

terraform init
terraform apply

Follow the prompts to confirm the deployment.

Step 5: Test Your API

Once deployed, you will receive an API Gateway endpoint. Use Postman or your web browser to test the API:

GET <your_api_gateway_url>/hello

You should receive the JSON response from your serverless application.

Optimizing and Troubleshooting

Code Optimization Tips

  • Minimize Dependencies: Keep your Docker image lightweight by including only necessary libraries.
  • Environment Variables: Use environment variables for configuration to keep your code clean and secure.

Troubleshooting Common Issues

  • Permission Errors: Ensure that your IAM role has the correct permissions.
  • Lambda Timeouts: Adjust the timeout setting in your Terraform configuration if your function takes too long to execute.

Conclusion

Deploying serverless applications on AWS using Terraform and Docker not only simplifies the deployment process but also enhances scalability and maintainability. By following this guide, you can efficiently build and deploy a serverless API that responds to user requests, all while leveraging the power of infrastructure as code with Terraform. As you continue to explore serverless architectures, consider experimenting with different runtimes and services offered by AWS to further enhance your applications. Happy coding!

SR
Syed
Rizwan

About the Author

Syed Rizwan is a Machine Learning Engineer with 5 years of experience in AI, IoT, and Industrial Automation.