AWS Cloud Portfolio Project

Back to Projects
Project Photo

Project Overview

Objective:

Developed a professional resume website hosted on AWS, utilizing various AWS services for enhanced performance, scalability, and security.

Key AWS Services Used:

  • Amazon S3 for static website hosting
  • AWS CloudFront for content delivery
  • AWS Certificate Manager (ACM) for SSL/TLS
  • AWS Route 53 for DNS management
  • AWS DynamoDB for data storage
  • AWS CodePipeline, CodeBuild, and CodeDeploy for CI/CD automation
  • AWS IAM for secure access management

Website Development & Hosting

  • Built a static resume website using a Bootstrap template.
  • Hosted the static content on an S3 bucket named after the domain.
  • Configured static website hosting and uploaded website files.

Issue: Initial 403 error occurred when accessing the website.
Cause: Missing bucket policy permissions.
Solution: Defined a bucket policy to allow public read access while noting the security implications.

CloudFront Integration for Performance & Security

  • Integrated AWS CloudFront as a Content Delivery Network (CDN) to improve performance through caching at edge locations.
  • Generated an SSL certificate via ACM (in the N. Virginia region) to enable HTTPS.
  • Updated the S3 bucket policy to restrict direct access, allowing access only through CloudFront.

DNS Management with AWS Route 53

  • Created a hosted zone for the domain.
  • Added name servers to the domain register.
  • Created an A record (Alias) to point the domain to the CloudFront distribution.

CI/CD Pipeline for Frontend Deployment

  • Configured a GitHub Actions workflow to automate website deployment to the S3 bucket.
  • Stored AWS credentials as encrypted GitHub secrets.
GitHub Actions Workflow:
name: Push to S3
on: [push]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup AWS CLI
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}
      - name: Sync files to S3
        run: |
          aws s3 sync ./website s3://yourdomain.com --delete
                

View Tracking API Development

  • Developed a View Tracking API using Go with the Gin framework.
  • Integrated AWS DynamoDB for storing and retrieving view counts.

API Functionality:

On a GET / request, the API increments and retrieves the current view count.

Docker Containerisation:

Containerised the API using Docker for easy deployment.

Dockerfile:
FROM golang:1.22
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN go build -o /view-tracker
CMD ["/view-tracker"]
                
BuildSpec.yml File:
version: 0.2
env:
  parameter-store:
    DOCKER_USERNAME: docker_username
    DOCKER_PASSWORD: docker_password
    DOCKER_URL: docker_url
phases:
  build:
    commands:
      - cd tracker_api/
      - echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin $DOCKER_URL
      - docker build -t "$DOCKER_USERNAME/view_api_img:latest" .
      - docker push "$DOCKER_USERNAME/view_api_img:latest"
  post_build:
    commands:
      - echo "Successfully pushed to Docker Hub"
artifacts:
  files:
    - '**/*'
  name: my-artifact
                

Deployment Automation with AWS CodeDeploy

  • Created CodeDeploy applications and deployment groups.
  • Installed the CodeDeploy agent on the EC2 instance.
  • Utilised IAM roles for secure communication between CodeDeploy and EC2.
  • Pulls the new Docker image from Docker Hub.
  • Stops the old container.
  • Starts the new container.
AppSpec.yml File:
version: 0.0
os: linux
hooks:
  ApplicationStop:
    - location: scripts/stop_container.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: scripts/start_container.sh
      timeout: 300
      runas: root
                

Common Issues & Resolutions

  1. CodeDeploy Agent Connection Failure
    • Error: CodeDeploy agent couldn't receive lifecycle events.
    • Solution: Restart the agent and verify IAM role permissions.
  2. AWS CodePipeline Role Authorisation Failure
    • Cause: Insufficient permissions for accessing S3 artifacts.
    • Solution: Updated IAM policy to allow artifact access.
  3. CloudFront Cache Invalidation
    • Issue: Website didn't reflect recent changes due to caching.
    • Solution: Manually invalidated the CloudFront cache.
  4. Mixed Content Block (HTTP/HTTPS)
    • Error: API requests over HTTP were blocked.
    • Solution: Implemented Nginx reverse proxy with HTTPS.

Key Learnings & Best Practices

  • S3 Bucket Permissions: Always re-enable "Block Public Access" after configuring CloudFront.
  • Docker: Understanding the isolation between container and host networks is crucial.
  • CloudFront: Cache invalidation is essential during website updates.
  • CI/CD: Parameterizing credentials with AWS Parameter Store enhances security.
  • Bash Scripting: Simplifies Docker container management.

Unanswered Questions

  • Why are Deployment Groups necessary?
  • Why must artifacts be uploaded to an S3 bucket in AWS CodePipeline?

References: