This is a demonstration of the Cloud Resume Challenge project that showcases a serverless portfolio website hosted on AWS.
Visitor Counter Implementation
The visitor counter is implemented using AWS Lambda and DynamoDB:
Lambda Function:
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event) => {
const params = {
TableName: 'cloud-resume-visitors',
Key: {
'id': 'visitors'
},
UpdateExpression: 'ADD visitors :inc',
ExpressionAttributeValues: {
':inc': 1
},
ReturnValues: 'UPDATED_NEW'
};
try {
const data = await dynamodb.update(params).promise();
const count = data.Attributes.visitors;
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({ count: count })
};
} catch (err) {
return {
statusCode: 500,
body: JSON.stringify(err)
};
}
};
Current Visitor Count:
Visitors: Loading...
CI/CD Pipeline
The project uses GitHub Actions for continuous integration and deployment:
name: Deploy Cloud Resume
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy SAM template
run: |
sam build
sam deploy --no-confirm-changeset
- name: Upload website to S3
run: aws s3 sync . s3://cloud-resume-bucket --exclude "*" --include "*.html" --include "css/*" --include "js/*" --include "img/*"
- name: Invalidate CloudFront cache
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*"