Ryan's Cool Website!

This is still a work in progress
I'm always adding new stuff for fun!

Recent
Projects

How I developed this website

This site was built using a mix of IaC and CI/CD. It is designed to completely rebuild in AWS S3 after every push to the master branch. Below are the steps I took to deploy it.

Register Domain and Create Certificate

The first steps I had to perform to make this a production level site was to register a domain and obtain a certificate. This was fairly straightforward from following the AWS docs.

I ended up registering ryanscoolwebsite.com and created an ACM Certificate for it.

Deploy my CloudFormation to build out most of the IaC.

Next I created and deployed a CloudFormation template to build out my infrastructure. The template contained resources for the following:

  • S3 Bucket
  • Bucket Policy
  • CloudFront
  • Origin Access Identity
  • WAFV2 WebACL with rules

Below is a sample of the template:


---
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
    FullDomainName:
        Type: String
    CertificateARN:
        Type: String
    BucketName:
        Type: String
Resources:
    Bucket:
        Type: AWS::S3::Bucket
        Properties:
        AccessControl: Private
        WebsiteConfiguration:
            IndexDocument: index.html
            ErrorDocument: error.html
        BucketName:
            Ref: BucketName
        BucketEncryption:
            ServerSideEncryptionConfiguration:
            - ServerSideEncryptionByDefault:
                SSEAlgorithm: AES256
        PublicAccessBlockConfiguration:
            BlockPublicAcls: true
            BlockPublicPolicy: true
            IgnorePublicAcls: true
            RestrictPublicBuckets: true
        DeletionPolicy: Retain
    BucketPolicy:
        Type: AWS::S3::BucketPolicy
        Properties:
        Bucket:
            Ref: Bucket
        PolicyDocument:
            Id: CFOAIPolicy
            Version: 2012-10-17
            Statement:
            - Sid: CloudFront Origin Access Identity
                Effect: Allow
                Action: s3:GetObject
                Resource:
                Fn::Join:
                    - ''
                    - - 'arn:aws:s3:::'
                    - Ref: Bucket
                    - "/*"
                Principal:
                AWS:
                    Fn::Sub: arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity
                    ${OriginAccessID}
    OriginAccessID:
        Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
        Properties:
        CloudFrontOriginAccessIdentityConfig:
            Comment:
            Ref: Bucket
                                

Create an IAM user.

After the majority of the infrastructure was configured I then created an IAM user to access the S3 bucket. I scoped the IAM policy permissions down to only access the bucket we previously created and also limited the actions for it.

Below is a sample IAM policy:


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Resource": [
                "arn:aws:s3:::$Bucket-Name",
                "arn:aws:s3:::$Bucket-Name/*"
            ],
            "Effect": "Allow",
            "Action": [
                "s3:DeleteObject",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:PutObject"
            ]
        }
    ]
}
                                

I then created a set of IAM access/secret keys to be used in GitHub.

Create GitHub Repo / Configure Secrets

Next I created a new private GitHub repo.

Once that was created I configured two Secrets in the GitHub repo for my IAM keys.

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Configure GitHub Actions/AWS CodePipeline

After that I created a CICD pipeline by configuring AWS CodePipeline to upload to my S3 bucket every time there was a push to my Master branch.

Map DNS

After deploying the website code (HTML, CSS, JS, ect...) to GitHub, my site was fully up and running. The final step I did was map ryanscoolwebsite.com as an Alias to the CloudFront distribution in my Route 53 hosted zone.

Finished Product & Security Considerations

My final product ended up being a fully functional static website that is served protected by a WAF.

Security was considered in every piece of infrastructure. Including the following:

  • S3 Bucket Encryption with AES256.
  • S3 Bucket can only be accessed via CloudFront OAI.
  • S3 Bucket Public Access Settings are all set to block.
  • CloudFront has a GeoRestriction to whitelist the US only.
  • CloudFront uses an ACM Certificate.
  • CloudFront using WAFV2 for layer 7 protection
  • WAFV2 has multiple AWS managed rules attached.

Contact Me

Email me at murphyimportant@gmail.com for any inquiries