These step-by-step demonstrations walk you through complete workflows using the s3-bucket module. Each demonstration includes prerequisites, detailed instructions, and verification steps.

Getting Started

To follow any demonstration, ensure you have:

  1. Prerequisites met: Terraform >= 1.0, AWS CLI configured
  2. Authenticate with the registry: terraform login registry.patterneddesigns.ca
  3. Clone the demonstration repository: git clone <demo-repo-url>
  4. Follow the step-by-step instructions below

Step-by-Step Guides

Static Website Hosting

Deploy a static website with S3 and CloudFront

Prerequisites

  • AWS account with appropriate permissions
  • Terraform >= 1.0
  • Domain name (optional, for custom domain)

Step 1: Create the S3 Bucket

module "website_bucket" {
  source  = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
  version = "3.0.0"

  bucket_name        = "my-static-website"
  versioning_enabled = true
}

Step 2: Configure CloudFront

resource "aws_cloudfront_origin_access_control" "main" {
  name                              = "website-oac"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

resource "aws_cloudfront_distribution" "website" {
  enabled             = true
  default_root_object = "index.html"

  origin {
    origin_id                = "s3"
    domain_name              = module.website_bucket.bucket_regional_domain_name
    origin_access_control_id = aws_cloudfront_origin_access_control.main.id
  }

  default_cache_behavior {
    target_origin_id       = "s3"
    viewer_protocol_policy = "redirect-to-https"
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]

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

  restrictions {
    geo_restriction { restriction_type = "none" }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}

Step 3: Add Bucket Policy

resource "aws_s3_bucket_policy" "website" {
  bucket = module.website_bucket.bucket_id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "cloudfront.amazonaws.com" }
      Action    = "s3:GetObject"
      Resource  = "${module.website_bucket.bucket_arn}/*"
      Condition = {
        StringEquals = {
          "AWS:SourceArn" = aws_cloudfront_distribution.website.arn
        }
      }
    }]
  })
}

Step 4: Deploy and Upload Content

Run terraform apply and upload your website files:

aws s3 sync ./public/ s3://my-static-website/

Step 5: Access Your Website

Your website is now available at the CloudFront distribution URL shown in the Terraform output.

Lambda Event Processing

Process S3 events with Lambda functions

Prerequisites

  • AWS account with appropriate permissions
  • Terraform >= 1.0

Step 1: Create the S3 Bucket

module "uploads_bucket" {
  source  = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
  version = "3.0.0"

  bucket_name        = "file-uploads"
  versioning_enabled = true
  encryption_type    = "aws:kms"
  kms_key_arn        = aws_kms_key.main.arn
}

Step 2: Create the Lambda Function

module "processor" {
  source  = "registry.patterneddesigns.ca/patterneddesigns/lambda-function/aws"
  version = "3.1.0"

  function_name = "s3-event-processor"
  runtime       = "python3.12"
  handler       = "main.handler"
  source_path   = "./src/processor"
  timeout       = 60

  environment_variables = {
    BUCKET_NAME = module.uploads_bucket.bucket_id
  }
}

Step 3: Configure S3 Event Notification

resource "aws_lambda_permission" "s3" {
  statement_id  = "AllowS3Invoke"
  action        = "lambda:InvokeFunction"
  function_name = module.processor.function_name
  principal     = "s3.amazonaws.com"
  source_arn    = module.uploads_bucket.bucket_arn
}

resource "aws_s3_bucket_notification" "uploads" {
  bucket = module.uploads_bucket.bucket_id

  lambda_function {
    lambda_function_arn = module.processor.function_arn
    events              = ["s3:ObjectCreated:*"]
    filter_prefix       = "uploads/"
    filter_suffix       = ".json"
  }

  depends_on = [aws_lambda_permission.s3]
}

Step 4: Grant Lambda Access to S3

resource "aws_iam_role_policy" "lambda_s3" {
  name = "lambda-s3-access"
  role = module.processor.role_arn

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "s3:GetObject",
          "s3:PutObject"
        ]
        Resource = "${module.uploads_bucket.bucket_arn}/*"
      }
    ]
  })
}

Step 5: Deploy and Test

Run terraform apply and test by uploading a file:

aws s3 cp test.json s3://file-uploads/uploads/test.json

Check CloudWatch Logs to verify the Lambda function processed the event.