Mastering S3: Scalable Storage Solutions in AWS

Static Website Hosting with Terraform

Amazon S3 (Simple Storage Service) is a versatile object storage service that offers industry-leading scalability, data availability, security, and performance. One of its many use cases is static website hosting. In this blog post, we'll explore how to set up an S3 bucket for static website hosting using Terraform.

Why Use S3 for Static Website Hosting?

  • Highly scalable and reliable
  • Cost-effective for static content
  • Easy to integrate with CDNs like CloudFront
  • Supports custom domain names
  • Automatic versioning and backup options

Prerequisites

Before we begin, ensure you have:

  • An AWS account
  • Terraform installed on your local machine
  • AWS CLI configured with appropriate credentials

Step-by-Step Implementation

1. Set Up the Terraform Configuration

Create a new directory for your Terraform project and initialize it:

mkdir s3-static-website
cd s3-static-website
terraform init

2. Create the Main Terraform File

Create a file named main.tf with the following content:

provider "aws" {
  region = "us-west-2"  # Change this to your preferred region
}

resource "aws_s3_bucket" "static_website" {
  bucket = "your-unique-bucket-name"  # Change this to a unique name
  acl    = "public-read"

  website {
    index_document = "index.html"
    error_document = "error.html"
  }

  tags = {
    Name = "Static Website Bucket"
  }
}

resource "aws_s3_bucket_policy" "static_website_policy" {
  bucket = aws_s3_bucket.static_website.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "PublicReadGetObject"
        Effect    = "Allow"
        Principal = "*"
        Action    = "s3:GetObject"
        Resource  = "${aws_s3_bucket.static_website.arn}/*"
      },
    ]
  })
}

output "website_endpoint" {
  value = aws_s3_bucket.static_website.website_endpoint
}

3. Explanation of the Terraform Code

  • aws_s3_bucket resource: Creates an S3 bucket with website hosting enabled.
  • acl = "public-read": Makes the bucket contents publicly readable.
  • website block: Configures the bucket for static website hosting, specifying index and error documents.
  • aws_s3_bucket_policy resource: Attaches a policy to the bucket allowing public read access to all objects.
  • output block: Displays the website endpoint URL after Terraform applies the configuration.

4. Deploy the Infrastructure

Run the following commands to create the S3 static website:

terraform plan
terraform apply

5. Upload Your Website Content

After the infrastructure is created, you can upload your website files to the S3 bucket:

aws s3 sync ./your-website-folder s3://your-unique-bucket-name

Advanced Configurations

Custom Domain with Route 53

To use a custom domain, you can add the following Terraform code:

resource "aws_route53_zone" "main" {
  name = "yourdomain.com"
}

resource "aws_route53_record" "website" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "www.yourdomain.com"
  type    = "A"

  alias {
    name                   = aws_s3_bucket.static_website.website_domain
    zone_id                = aws_s3_bucket.static_website.hosted_zone_id
    evaluate_target_health = false
  }
}

CloudFront Distribution

To improve performance and security, you can add a CloudFront distribution:

resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name = aws_s3_bucket.static_website.bucket_regional_domain_name
    origin_id   = "S3-${aws_s3_bucket.static_website.id}"
  }

  enabled             = true
  default_root_object = "index.html"

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "S3-${aws_s3_bucket.static_website.id}"

    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}

Conclusion

Using Terraform to set up an S3 static website provides a scalable, cost-effective, and easily manageable solution for hosting static content. By leveraging AWS services like Route 53 and CloudFront, you can further enhance your website's performance and security.

Remember to always follow AWS best practices, especially regarding security and cost optimization. Happy hosting!