Get started with deploying web apps on AWS



This content originally appeared on DEV Community and was authored by Reet

A serverless To-Do Web Application on AWS

This document outlines the steps to build and deploy a simple, serverless to-do application. The project uses a suite of AWS services to create a fully functional web app without managing any servers. The frontend has a minimalist, brutalist design and interacts with a serverless backend to manage tasks.

This project is a great introduction to serverless architecture, demonstrating how to connect a static frontend to a dynamic, event-driven backend in the cloud.

Architecture

The application is built on a classic serverless pattern:

  • Frontend Hosting: An Amazon S3 bucket is configured to host the static web files (HTML, CSS, JavaScript).
  • API Layer: Amazon API Gateway provides a RESTful API endpoint that the frontend can call. It acts as the front door to our backend logic.
  • Backend Logic: An AWS Lambda function, written in Python, contains all the business logic for creating, reading, updating, and deleting tasks.
  • Database: Amazon DynamoDB, a NoSQL database, stores the tasks in a table.

The flow is straightforward: The user interacts with the website hosted on S3. The JavaScript on the site makes secure calls to API Gateway, which triggers the Lambda function. The Lambda function then executes the required logic and manipulates the data in the DynamoDB table.

Setup Instructions

Follow these steps carefully to deploy the application in your own AWS account.

Step 1: Create the DynamoDB Table

First, we need a database to store our tasks.

  1. Navigate to the Amazon DynamoDB console.
  2. Click on Create table.
  3. Set the Table name to ToDo_Tasks. This name must match exactly what is in the Lambda function code.
  4. For the Partition key, enter taskId and ensure its type is set to String.
  5. Leave all other settings as their default values and click Create table.

Step 2: Create the IAM Role

Our backend function will need permission to access the database. We will create an IAM role for this purpose.

  1. Navigate to the IAM console.
  2. Select Roles from the side menu and click Create role.
  3. For the Trusted entity type, select AWS service.
  4. For the Use case, choose Lambda, then click Next.
  5. On the “Add permissions” page, search for and attach the following two policies:
    • AWSLambdaBasicExecutionRole (This allows the function to write logs).
    • AmazonDynamoDBFullAccess (This grants full access to DynamoDB).
  6. Click Next.
  7. Set the Role name to TasksLambdaRole and click Create role.

Step 3: Create the Lambda Function

This is the core of our backend, containing the application logic.

  1. Navigate to the AWS Lambda console.
  2. Click Create function.
  3. Select Author from scratch.
  4. Set the Function name to tasksManager.
  5. For the Runtime, select a recent Python version (e.g., Python 3.9).
  6. Expand the Change default execution role section.
  7. Select Use an existing role and choose the TasksLambdaRole you created in the previous step.
  8. Click Create function.
  9. Once the function is created, go to the Code source editor and replace the default code with the full Python script for the application.
  10. Click the Deploy button to save your code.

Step 4: Configure the API Gateway

Next, we will create a public endpoint for our frontend to communicate with the Lambda function.

  1. Navigate to the Amazon API Gateway console.
  2. Find the REST API option and click Build.
  3. Select New API and give it an API name, such as TasksAPI.
  4. Click Create API.
  5. Create the Resources and Methods:
    • Select the root (/) resource, click Actions, and choose Create Resource. Name it tasks.
    • With the new /tasks resource selected, click Actions and Create Method. Choose GET from the dropdown. For the integration, select Lambda Function, check the Use Lambda Proxy integration box, and select your tasksManager function. Save the method.
    • Repeat the process to create a POST method on the /tasks resource, linking it to the same Lambda function.
    • Now, select the /tasks resource again, click Actions, and Create Resource. For the Resource Path, enter {taskId}. The curly braces are critical as they define a path parameter.
    • On the new /tasks/{taskId} resource, create PUT and DELETE methods, linking both to the same tasksManager Lambda function with proxy integration.
  6. Enable CORS (Cross-Origin Resource Sharing):
    • Select the /tasks resource, click Actions, and select Enable CORS.
    • Confirm the settings in the dialog box and click the Enable CORS… button. This will automatically create an OPTIONS method to handle preflight requests from the browser.
  7. Deploy the API:
    • Click Actions and select Deploy API.
    • Choose [New Stage] for the deployment stage and enter a name, such as prod.
    • Click Deploy.
    • After deployment, copy the Invoke URL. You will need this for the frontend configuration.

Step 5: Prepare the Frontend Files

On your local machine, create the three frontend files: index.html, style.css, and script.js.

Crucially, open the script.js file and find the API_ENDPOINT constant. Paste the Invoke URL you copied from API Gateway as its value.

// Example from script.js
const API_ENDPOINT = 'https://xxxxxxxxx.execute-api.your-region.amazonaws.com/prod/tasks';

Step 6: Host the Website on S3

Finally, we will upload our frontend files to S3 and make them publicly accessible.

  1. Navigate to the Amazon S3 console.

  2. Click Create bucket.

  3. Provide a globally unique bucket name.

  4. Uncheck the “Block all public access” box and acknowledge the warning.

  5. Click Create bucket.

  6. Open your new bucket and go to the Properties tab.

  7. Scroll down to Static website hosting and click Edit. Enable it, and set the Index document to index.html. Save your changes.

  8. Go to the Permissions tab and edit the Bucket policy. Paste the following JSON, replacing YOUR_BUCKET_NAME with your actual bucket name.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "PublicReadGetObject",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
            }
        ]
    }
    
  9. Save the policy.

  10. Go to the Objects tab and upload your index.html, style.css, and script.js files.

Accessing Your Application

To view your live application, return to the Properties tab of your S3 bucket. Scroll down to the Static website hosting section and click on the Bucket website endpoint URL. Your serverless to-do application is now deployed and ready to use.


This content originally appeared on DEV Community and was authored by Reet