AWS Cloud Resume Challenge
Serverless Website deployment using Infrastructure as Code
What is this challenge?
The Cloud Resume Challenge is a multiple-step resume project which helps build and demonstrate skills fundamental to pursuing a career as an AWS Cloud Engineer. The project was published by Forrest Brazeal. Details of this challenge can be found here. The final result can be seen here.
Big picture of deployments
This project is about creating a website which is hosted on amazon S3, then on the site display the number of visitors which is calculated with an AWS Lambda Function and stored in DynamoDB table.
The tasks and the progression
HTML
The CV is needed to be a HTML document which is styled using CSS. It doesn't need to be an original masterpiece, any HTML CV template will be acceptable. You can find mine here for inspiration.CSS
The same goes to CSS too. You can write your own, or use tailwind or something similar.Static Website
The HTML/CSS website should be deployed to an AWS S3 bucket. I have done it via CloudFormation template. The code is below:MyWebsite: Type: AWS::S3::Bucket Properties: AccessControl: PublicRead WebsiteConfiguration: IndexDocument: index.html BucketName: cloud-cv-website
Javascript
The CV webpage should include a visitor counter that displays how many people have accessed the site. This script should be written in JavaScript. For the counter to work, we need to add a few extra line in our HTML website and write a JavaScript code:var dev_env = false if (dev_env == false) { fetch("https://8tqg9v6zog.execute-api.us-east-1.amazonaws.com/prod/hello") .then(function (response) { return response.json() }) .then(function (myJson) { console.log("Visitor Count: " + myJson.visit_count); document.querySelector("#visitorCount").innerHTML = "Total visitors: " + myJson.visit_count; }) .catch(function (error) { console.log("Error: " + error) }) }
The HTML addition:
<p class="h3 email"><span id="visitorCount"></span></p>
Database
The visitor counter will need to retrieve and update its count in a database somewhere. I have used DynamoDB for this task as it was the most convenient solution. The code from the CloudFormation template to create the DynamoDB table:DynamoDBTable: Type: AWS::DynamoDB::Table Properties: TableName: cloud_resume BillingMode: PAY_PER_REQUEST AttributeDefinitions: - AttributeName: "ID" AttributeType: "S" KeySchema: - AttributeName: "ID" KeyType: "HASH"
API
We shouldn't communicate directly with DynamoDB from our Javascript code. Instead, a REST API should be created that accepts requests from your web app and communicates with the database.Python
The Lambda script to retrieve the counter from the database and update the number should be written in Python. The final script is below:
import json
import boto3
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('cloud_resume')
def lambda_handler(event, context):
response = table.get_item(
Key = {
'ID':'visit'
}
)
visit_count = response['Item']['counts']
visit_count = int(visit_count) + 1
response = table.put_item(
Item = {
'ID':'visit',
'counts': visit_count
}
)
# print(visit_count)
responseBody = json.dumps({"visitorCount": visit_count})
logger.debug("Execution complete")
# return {
# 'statusCode': 200,
# 'body': f'{visit_count}'
#}
apiResponse = {
"isBase64Encoded": False,
"statusCode": 200,
#"visitorCount": int(float(ddbResponse["Attributes"]["amount"])),
"body": responseBody,
"headers": {
"Access-Control-Allow-Headers" : "Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,OPTIONS"
},
}
return {"visit_count": visit_count}
And to deploy it via CloudFormation:
Lambdafunction:
Type: AWS::Serverless::Function
Properties:
Policies:
- DynamoDBCrudPolicy:
TableName: cloud_resume
CodeUri: Lambda/
Handler: visitor_count.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
Events:
getCount:
Type: Api
Properties:
Path: /
Method: get
8.Infrastructure as Code
I have used the AWS Serverless Application Model (SAM) template and deployed the different services using the AWS SAM CLI. The code snippets can be found under each step where applicable.
9.Blog post
The final step is to write a blog about the experience and what I have learned during the project work. You are reading this blog right now.