Building Serverless Websites in AWS

Researching on RESTful APIs, I found the use case of AWS services to build Serverless websites very appealing. This can help small to mid-size organizations to reduce their operational overhead while delivering highly scalable and reliable services to customers. In this blog post, I will document steps to develop such a serverless website in AWS.

Step 1: Creating a static web front-end

We will be using the unique public url for AWS S3 bucket as our web front-end. The S3 bucket would be simply used to host static content for the website like HTML files, image files, CSS files, etc.

S3 bucket after content upload

4. Add a bucket policy to allow READs from the public. Below is the JSON that your bucket policy must have to allow Public READ access:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::[YOUR_BUCKET_NAME]/*"
}
]
}

Note: Depending on your bucket setting, you may or may not be able to do the above operation. If an error like ‘Access Denied’ comes up while granting updating bucket policy, please first update the Public Access Settings to remove the block on updating the bucket policy.

5. To enable users in the region of your S3 bucket to be able to see the contents of bucket as if they are coming from a website, you need to enable website hosting on your S3 bucket. This can be done from Properties of the bucket:

Enabling static website hosting on S3 bucket

6. Visit your S3 endpoint to see your implementation of static website at:

http://<bucket-name>.s3-website-<region-name>.amazonaws.com

Step 2: Creating a Server-less backend process

Amazon offers a fully-managed SQL database through RDS and a fully-managed no-SQL database using DynamoDB. You can use either one for your serverless solution depending on your use case. For application level logic like getting or putting data from these databases, Amazon offers a very neat and powerful solution using AWS Lambda. In this section, we would create a new NoSQL table in DynamoDB and do a test to insert data into it through AWS Lambda

a. AWS managed policy = AWSLambdaBasicExecutionRole

b. Inline policy with the below JSON, allowing PUT permission to the DynamoDB:

{
“Version”: “2012–10–17”,
“Statement”: [
{
“Sid”: “VisualEditor0”,
“Effect”: “Allow”,
“Action”: “dynamodb:PutItem”,
“Resource”: “<dynamoDB table ARN>”
}
]
}

3. Create a Lambda function at your preferred region, attaching the above-created role and selecting your preferred programming language.

4. Code your Lambda function to receive a POST-type request, capture necessary details in variables, and put these variables in the DynamoDB/RDS using AWS-offered SDKs.

5. In order to test this implementation, create a Test Event matching the details of the POST request. Test the Lambda function against the test event and see if values are populated in the back-end database.

Step 3: Expose Lambda function using RESTful API

The back-end process we created in Step 2 is a stand-alone process and is not connected to the front-end in Step 1. Before the birth of API Gateway, AWS Lambda was just a cloud event-driven coding platform. API Gateway has revolutionized the way in which Lambda can be used for delivering application logic outside of cloud events. In this blogpost, we would be using API Gateway to expose the functionality of the Lambda function we created in Step 2 as a RESTful API.

For the purpose of this demonstration, we have taken authorization for this API as None. However, in most of the cases, you will need to authorize your APIs using JWT authorization or API keys or other methods as considered necessary.