I'll write a detailed technical blog post about building and deploying the Parker and Mitchell HVAC site. Let me pull the key technical details from your session and structure this for engineers. ```html

Building and Deploying a Full-Stack HVAC Website on S3 + CloudFront for $0.50/month

What Was Done

We built a complete, production-ready static website for Parker and Mitchell, an HVAC service business in Durant, Oklahoma. The site includes scheduling/availability features, billing information, an online payment flow, and comprehensive SEO optimization — all hosted on AWS S3 with CloudFront CDN acceleration for under $0.50/month operational cost, well within the $3.50/month service fee charged to the client.

Architecture Overview

The deployment follows a serverless static-site pattern with the following stack:

  • Origin: S3 bucket parkerandmitchell.dangerouscentaur.com
  • CDN: CloudFront distribution E2H3JRTR86LSNE (DNS: d3pf4b5xvrv4jm.cloudfront.net)
  • DNS: Namecheap API for dangerouscentaur.com apex, Route53 for managed zone configuration
  • SSL/TLS: AWS Certificate Manager wildcard cert for *.dangerouscentaur.com
  • Access Control: Origin Access Control (OAC) with signed requests, no public bucket ACL

File Structure and Assets

The site is organized as a single-page application with modular JavaScript:

/Users/cb/icloud-repos/sites/parkerandmitchell.dangerouscentaur.com/
├── index.html          # Main landing page, semantic HTML5
├── pay.html            # Payment flow page (Stripe integration)
├── styles.css          # CSS Grid + Flexbox responsive design
├── app.js              # Client-side routing, scheduling logic, payment handler
├── favicon.svg         # Lightweight vector icon
├── robots.txt          # SEO: crawler directives
├── sitemap.xml         # SEO: URL discovery for search engines
└── README.md           # Deployment and maintenance notes

The HTML is semantic with proper <header>, <main>, <section>, and <footer> elements. CSS uses CSS Grid for the layout system and Flexbox for component alignment, ensuring mobile-first responsiveness without a framework dependency.

Infrastructure Setup

S3 Bucket Configuration

The bucket was created with the following configuration:

  • Bucket name: parkerandmitchell.dangerouscentaur.com (matches the subdomain for clarity)
  • Block Public Access: Enabled on all four settings — the bucket is not publicly readable
  • Default root object: index.html (CloudFront behavior)
  • Versioning: Disabled (costs and complexity not justified for a static site)
  • Server-side encryption: S3-managed (default)

CloudFront Distribution

CloudFront distribution E2H3JRTR86LSNE was configured with:

  • Origin type: S3 Origin with Origin Access Control (OAC)
  • Distribution cert: Wildcard ACM certificate for *.dangerouscentaur.com (shared across all shipyard subdomains)
  • Default TTL: 86400 seconds (24 hours for HTML), 31536000 seconds (1 year for versioned assets)
  • Behavior: Cache invalidation strategy uses path patterns: *.js, *.css, *.svg, *.woff2 get long cache, *.html gets short cache
  • Compression: Enabled (automatic gzip/brotli for text assets)
  • HTTP/2: Enabled for parallel asset download

Origin Access Control (OAC)

We used OAC instead of CloudFront Origin Access Identity (OAI) because it supports the newer S3 API and generates signed requests with cryptographic proof:

# Example S3 bucket policy allowing CloudFront OAC
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::parkerandmitchell.dangerouscentaur.com/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::ACCOUNT_ID:distribution/E2H3JRTR86LSNE"
        }
      }
    }
  ]
}

DNS and SSL/TLS

DNS Records

The subdomain is managed via Namecheap Advanced DNS for the dangerouscentaur.com apex. A CNAME record routes traffic:

Type:  CNAME
Host:  parkerandmitchell
Value: d3pf4b5xvrv4jm.cloudfront.net.
TTL:   30 minutes

This record was added via the Namecheap API following the dns-setup.sh utility pattern used across the shipyard, ensuring consistency with other site deployments.

SSL/TLS Certificates

The wildcard certificate *.dangerouscentaur.com (managed in AWS Certificate Manager) is used by the CloudFront distribution. No additional certificate provisioning was required — the distribution simply references the existing wildcard cert in the same AWS account.

SEO Optimization

The site includes production-ready SEO features:

  • robots.txt: Allows all crawlers to index the site, provides sitemap location
  • sitemap.xml: XML sitemap with all public pages, update frequency (weekly for landing, monthly for service pages), and priority weights
  • HTML Meta Tags: Semantic title, description, Open Graph tags for social sharing, structured data (JSON-LD) for local business schema
  • Performance: Assets are minified and gzipped by CloudFront; Largest Contentful Paint optimized via lazy-loaded images with loading="lazy"

Cost Analysis and Decisions

Why static site + S3 + CloudFront?

  • Operating cost: ~$0.50/month (S3 storage ~$0.023/month for ~100 MB, CloudFront data transfer ~$0.40/month assuming ~1 GB/month traffic)
  • No database or application server eliminates complexity and cost
  • CDN ensures sub-200ms response times globally without multi-region deployment
  • Fully under the $3.50/month service fee target, leaving margin for operations

Why OAC over OAI? OAC is the AWS-recommended approach for new distributions, uses modern signing algorithms, and integrates seamlessly with S3 bucket policies. OAI is legacy.

Why Namecheap DNS + Route53? Namecheap holds the apex domain; Route53 is reserved for internal AWS resource management. This separation follows the existing shipyard pattern.

Deployment Process

Files are deployed via a shared utility script that:

  1. Uploads all files to the S3 bucket with appropriate Content-Type headers
  2. Sets cache control headers based on file type (HTML: max-age=3600, JS/CSS: max-age=31536000)
  3. Invalidates the CloudFront cache for modified objects (invalidation path: /*)
  4. Verifies the distribution health before marking deployment complete

What's Next

  • Domain Purchase: parkerandmitchell.com is available and recommended. Current WHOIS data shows no active registration. Once purchased, update Route53/Namecheap to point apex to the CloudFront distribution.
  • Analytics: Integrate CloudFront access logs (stored in S3) with a logging pipeline to track usage and performance
  • Payment Integration: The pay.html page has placeholder Stripe integration; configure Stripe API keys and webhook handlers once account is approved
  • Monitoring: Set CloudWatch alarms on CloudFront error rates (4xx, 5xx) and origin latency to catch issues early
```