Project case study · Cloud security
Hardening the Security of andyhopla.com on AWS
Moving andyhopla.com to AWS wasn't simply an exercise in finding somewhere new to host a website.
I wanted to use the migration as a practical AWS project: build the infrastructure myself, automate its deployment, and then look at how I could reduce the security risks of running a public-facing website.
The result is a relatively simple architecture, but one where security is built into the design rather than added afterwards.
The starting point
andyhopla.com is a static website, so there was no need for a traditional web server.
Instead, I built the site around:
Route 53 → CloudFront → private S3 bucket
The infrastructure is defined using Terraform, with changes managed through GitHub Actions rather than manually configuring resources through the AWS console.
That immediately gave me an opportunity to apply one of the principles I wanted to follow throughout the project:
Only expose what actually needs to be exposed.
Keeping the S3 bucket private
One of the most important decisions was not to make the S3 bucket hosting the website publicly accessible.
The bucket has S3 Block Public Access enabled.
Visitors therefore don't retrieve the website directly from S3. Instead, requests come through CloudFront using Origin Access Control (OAC).
The bucket policy allows CloudFront to retrieve the website content while preventing someone from simply accessing the underlying S3 bucket directly.
This gives me a clear separation:
Internet → CloudFront → controlled access → S3
rather than:
Internet → public S3 bucket
It's a relatively small architectural decision, but an important security improvement.
HTTPS everywhere
The next requirement was straightforward: the site should only be accessible securely.
I used AWS Certificate Manager (ACM) to provide the TLS certificate used by CloudFront.
HTTP requests are redirected to HTTPS, meaning visitors don't need to remember to type https://.
Certificate renewal is also handled by AWS rather than requiring me to manually replace certificates.
Adding security headers
HTTPS protects the connection, but I also wanted the browser itself to have clearer instructions about how the site should be handled.
I therefore added a CloudFront Response Headers Policy.
This allowed me to introduce browser security controls including headers such as:
- Strict-Transport-Security (HSTS)
- X-Content-Type-Options
- X-Frame-Options
- Referrer-Policy
HSTS is particularly useful because it tells supporting browsers that the site should only be accessed using HTTPS.
X-Frame-Options helps protect the site from being embedded within another website as part of a clickjacking attack.
X-Content-Type-Options prevents browsers from trying to interpret files as a different content type.
These aren't replacements for secure application design, but they provide another useful defensive layer.
DNS through Route 53
I migrated the DNS for andyhopla.com to Amazon Route 53.
This means the DNS configuration now forms part of the AWS architecture rather than being managed separately by the previous hosting provider.
The apex domain points towards the CloudFront distribution, and I also configured handling for the www version of the domain so visitors reach the canonical site consistently.
No servers to patch
One security advantage of this architecture is actually something that isn't there.
There is no EC2 web server.
That means there is:
- no operating system exposed to the internet;
- no SSH service;
- no web server such as Apache or Nginx to maintain;
- no server operating system requiring security patches;
- and no server credentials to manage.
AWS obviously still operates infrastructure underneath these services, but from my perspective the attack surface I am responsible for is considerably smaller.
For a static website, introducing an EC2 instance would have added complexity and security responsibilities without providing much benefit.
Infrastructure as Code
Another part of the security model isn't directly visible to somebody visiting the website.
The AWS infrastructure is defined using Terraform.
Rather than manually creating resources through the AWS console, the configuration describes what the environment should look like.
Terraform can then show me the proposed changes before anything is applied.
That provides something I value from my IT Service Management background: controlled and repeatable change.
Infrastructure changes become something that can be reviewed rather than a collection of undocumented clicks in a management console.
Deployment through GitHub Actions
I also connected the deployment process to GitHub Actions.
Changes to the website and infrastructure can therefore move through a repeatable CI/CD process.
Again, the objective isn't automation simply for the sake of automation.
It's about reducing manual intervention and creating a predictable deployment process.
From an operational perspective, repeatability matters.
Security as layers
One of the useful lessons from building the site was that there wasn't a single setting that suddenly made it "secure".
Instead, security came from combining a number of relatively simple decisions:
- Private S3 storage
- CloudFront Origin Access Control
- HTTPS and ACM
- Security response headers
- Route 53 DNS
- Infrastructure as Code
- Controlled CI/CD deployment
Each layer addresses a slightly different risk.
What I deliberately didn't deploy
Another lesson from the project was recognising when not to use an AWS service.
It would have been easy to add EC2 instances, load balancers, databases, containers or numerous additional security products simply to demonstrate that I knew how to deploy them.
But architecture should be driven by the requirement.
andyhopla.com is fundamentally a static website.
S3 and CloudFront provide what it needs while keeping the architecture inexpensive, highly available and relatively small from a security perspective.
Sometimes good cloud architecture is as much about the services you decide not to deploy as the ones you do.
What I learned
My background is primarily IT Service Management and Service Operations rather than software development.
Projects like this are part of how I'm extending that experience into AWS and cloud operations.
What I've found particularly interesting is how many traditional operational principles still apply.
Least privilege.
Reduce the attack surface.
Automate repeatable processes.
Control change.
Monitor what matters.
Don't introduce unnecessary complexity.
The technology has changed considerably, but many of the underlying principles haven't.
andyhopla.com is a relatively small project, but that's precisely why I've found it useful.
It gives me somewhere to experiment with AWS, Terraform, CI/CD and security controls on infrastructure that I actually own and operate — and where I'm responsible for the consequences of the decisions I make.