Consolidating Operational Tools: Building a Unified Ops Dashboard with S3 Static Hosting and CloudFront CDN

We recently rebuilt the operations dashboard at https://ops.queenofsandiego.com/ to serve as a single point of access for business-critical tools, payment processing, and external platform integrations. This post details the technical architecture, deployment pipeline, and design decisions behind consolidating scattered operational resources into one static site.

What Was Done

The ops dashboard needed to evolve from a basic reference page into a comprehensive operational hub. The primary requests were:

  • Add a Payments section with integrated Stripe deposit links and alternative payment methods (Zelle)
  • Consolidate links to all public-facing websites and marketing properties
  • Create a centralized index for external platforms (Instagram, email services, document signing tools)
  • Fix broken references to critical Google Sheets (particularly the Port Sheet submission tracker)
  • Add links to development and AWS resources for backend operations

The file modified was /Users/cb/Documents/repos/sites/ops/index.html, which is then deployed to an S3 bucket and distributed via CloudFront.

Technical Architecture and Infrastructure

Static Site Hosting on S3

The ops dashboard is hosted as a static HTML site on Amazon S3. This architectural choice provides several advantages:

  • Cost efficiency — S3 static hosting costs pennies per month compared to compute-based solutions
  • High availability — S3 provides 99.99% uptime SLA with automatic redundancy
  • Version control friendly — HTML files are tracked in git and deployed via automated pipelines
  • No server management — no patching, scaling, or operational overhead

The S3 bucket is configured with:

  • Static website hosting enabled on the bucket
  • Index document set to index.html
  • Block public access disabled (allowing CloudFront origin access)
  • Bucket versioning enabled for rollback capability

CloudFront Distribution and CDN Caching

Rather than serving content directly from S3, we use CloudFront as the CDN layer. This provides:

  • Global edge caching — content cached at AWS edge locations worldwide, reducing latency
  • HTTPS termination — CloudFront handles SSL/TLS certificates and HTTPS enforcement
  • Cache invalidation — ability to purge specific objects or patterns when content updates
  • Request compression — automatic gzip compression of HTML, CSS, and JavaScript

The deployment process invalidates the CloudFront cache after each HTML update, ensuring users see fresh content immediately:

aws cloudfront create-invalidation \
  --distribution-id DISTRIBUTION_ID \
  --paths "/*"

This wildcard invalidation clears all cached objects, guaranteeing the latest version is delivered to all users.

DNS Resolution via Route 53

The domain ops.queenofsandiego.com is managed through Route 53 with an alias record pointing to the CloudFront distribution. This approach:

  • Allows seamless domain management alongside other queenofsandiego.com subdomains
  • Provides health checking and automatic failover if needed (though not required for a static site)
  • Integrates with AWS's native DNS service for consistent infrastructure-as-code management

Content Organization and Design Decisions

Payments Section

The new Payments section was prioritized at the top of the page with green accent styling to indicate its importance. It includes:

  • Primary CTA button$500 Deposit linking directly to the Stripe payment page
  • Parent card layout — groups all payment-related actions and information
  • Zelle alternative — provides non-card payment option with account details
  • Sub-links — quick access to the $125 birthday sail offering, recent payments, and balance/payout information

This mirrors common e-commerce dashboard patterns where payment processing is front-and-center for operational teams.

Tool Categorization

Tools were organized into logical sections:

  • Public Sites — customer-facing properties (sailjada.com, queenofsandiego.com, Events Hub, burials at sea microsite)
  • External Platforms — third-party services (Instagram, ImprovMX email aliases, DocuSign, Google Business Profile)
  • Dev — development resources including Google Apps Script projects (booking engine, Rady Shell GAS scripts)
  • AWS — cloud infrastructure (DynamoDB tables like jada-crew-dispatch, S3 buckets, CloudFront distributions)

This taxonomy reflects the operational workflow: first check public sites, then external platforms, then dive into development/infrastructure as needed.

Critical Bug Fixes

Port Sheet Link Correction

The original Port Sheet link was broken. We corrected it to point to the actual active Google Sheet ID: 1jUxYXS24VS-D9tO37ckNqMNclvOBqQuh, which serves as the Sheraton submission tracker referenced in the ACTIVE.md memory file. This is a critical operational tool used for port operations and needed to be easily accessible.

Key Architectural Decisions

Why Static HTML Over a Framework

We chose static HTML (no React, Vue, or dynamic backend) because:

  • The ops dashboard is essentially a list of links — HTML is the appropriate tool
  • No real-time data updates required — external services (Stripe, Google Sheets, Instagram) are linked directly
  • Minimal JavaScript dependency surface reduces security risk
  • Faster deploy cycles (seconds, not minutes of build time)
  • Lower barrier to entry for operational team members to add/edit links

CloudFront vs. Direct S3 Serving

While S3 can serve websites directly, CloudFront adds critical value:

  • HTTPS everywhere — S3 websites don't support HTTPS; CloudFront provides certificate management
  • Custom domain — CloudFront enables subdomains like ops.queenofsandiego.com with clean routing
  • Performance — edge caching means repeated visitors get sub-100ms response times
  • Observability — CloudFront logs provide request metrics and cache hit ratios

Deployment Pipeline

The deployment workflow is straightforward:

  1. Modify /Users/cb/Documents/repos/sites/ops/index.html locally
  2. Commit and push to git
  3. Sync to S3