• Home
  • About me
  • Projects
  • Contacts
Static site with S3 and CloudFront

Static site with S3 and CloudFront

Reading time: 4 minutes and 54 seconds


When I decided to build my own site, I knew I wanted something fast, scalable, and modern — not just in terms of the tech stack, but also in the way it’s managed and deployed. This post walks you through exactly how my site (Cloudy Mountains) is deployed using Hugo, AWS (S3 + CloudFront), Terraform, GitHub Actions, and OIDC authentication. I’ll show you the challenges that I had and how to solve them properly.
First policy as code using OPA

First policy as code using OPA

Reading time: 5 minutes and 1 seconds


As I mentioned in my previous blog post, my first OPA policy was just to catch one simple parameter, if we have in the S3 Terrafom module set the force_destroy = true.

Here’s a simple OPA policy that will catch this dangerous configuration:

package terraform.plan

deny[msg] {
    # Find all resources in the plan
    resource := input.resource_changes[_]
    
    # Check if it's an S3 bucket
    resource.type == "aws_s3_bucket"
    
    # Look for force_destroy in the configuration
    resource.change.after.force_destroy == true
    
    msg := sprintf("S3 bucket '%s' has force_destroy set to true. This is dangerous as it allows bucket deletion even when not empty.", [resource.address])
}

This policy works by:

© 2025 Cloudy Mountains. All rights reserved.