Examples
These examples demonstrate practical, real-world usage patterns for the s3-bucket module. Each example is self-contained and ready to run—simply copy the configuration, customize the values for your environment, and apply.
Getting Started
To run any example, follow these steps:
- Authenticate with the registry:
terraform login registry.patterneddesigns.ca - Initialize the working directory:
terraform init - Review the execution plan:
terraform plan - Apply the configuration:
terraform apply
Usage Examples
Minimal configuration for a secure S3 bucket
module "data_bucket" {
source = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
version = "3.0.0"
bucket_name = "my-app-data"
}
S3 bucket with versioning enabled for data protection
module "versioned_bucket" {
source = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
version = "3.0.0"
bucket_name = "important-documents"
versioning_enabled = true
lifecycle_rules = [
{
prefix = ""
noncurrent_version_expiration_days = 90
}
]
}
S3 bucket with customer-managed KMS encryption
resource "aws_kms_key" "bucket" {
description = "KMS key for S3 bucket encryption"
deletion_window_in_days = 7
enable_key_rotation = true
}
resource "aws_kms_alias" "bucket" {
name = "alias/s3-bucket-key"
target_key_id = aws_kms_key.bucket.key_id
}
module "secure_bucket" {
source = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
version = "3.0.0"
bucket_name = "sensitive-data"
versioning_enabled = true
encryption_type = "aws:kms"
kms_key_arn = aws_kms_key.bucket.arn
}
S3 bucket configured for static website hosting
module "website_bucket" {
source = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
version = "3.0.0"
bucket_name = "www-example-com"
versioning_enabled = false
website_configuration = {
index_document = "index.html"
error_document = "error.html"
}
cors_configuration = {
cors_rules = [{
allowed_headers = ["*"]
allowed_methods = ["GET", "HEAD"]
allowed_origins = ["https://example.com"]
max_age_seconds = 86400
}]
}
}
resource "aws_s3_bucket_policy" "website" {
bucket = module.website_bucket.bucket_id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "PublicReadGetObject"
Effect = "Allow"
Principal = "*"
Action = "s3:GetObject"
Resource = "${module.website_bucket.bucket_arn}/*"
}]
})
}
S3 bucket with automated lifecycle management
module "data_lake" {
source = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
version = "3.0.0"
bucket_name = "data-lake-raw"
versioning_enabled = true
encryption_type = "aws:kms"
kms_key_arn = module.kms.key_arn
lifecycle_rules = [
{
id = "logs-cleanup"
prefix = "logs/"
enabled = true
expiration_days = 90
},
{
id = "archive-old-data"
prefix = "data/"
enabled = true
transition_days = 30
transition_class = "STANDARD_IA"
},
{
id = "deep-archive"
prefix = "backups/"
enabled = true
transition_days = 90
transition_class = "GLACIER"
},
{
id = "cleanup-incomplete-uploads"
prefix = ""
enabled = true
abort_incomplete_multipart_upload_days = 7
}
]
}
S3 bucket with cross-region replication for disaster recovery
provider "aws" {
alias = "replica"
region = "us-west-2"
}
module "source_bucket" {
source = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
version = "3.0.0"
bucket_name = "data-primary-us-east-1"
versioning_enabled = true
encryption_type = "aws:kms"
kms_key_arn = aws_kms_key.primary.arn
}
module "replica_bucket" {
source = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
version = "3.0.0"
providers = {
aws = aws.replica
}
bucket_name = "data-replica-us-west-2"
versioning_enabled = true
encryption_type = "aws:kms"
kms_key_arn = aws_kms_key.replica.arn
}
resource "aws_iam_role" "replication" {
name = "s3-replication-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
Service = "s3.amazonaws.com"
}
Action = "sts:AssumeRole"
}]
})
}
resource "aws_s3_bucket_replication_configuration" "main" {
bucket = module.source_bucket.bucket_id
role = aws_iam_role.replication.arn
rule {
id = "replicate-all"
status = "Enabled"
destination {
bucket = module.replica_bucket.bucket_arn
storage_class = "STANDARD"
encryption_configuration {
replica_kms_key_id = aws_kms_key.replica.arn
}
}
source_selection_criteria {
sse_kms_encrypted_objects {
status = "Enabled"
}
}
}
}
S3 bucket as a secure CloudFront distribution origin
module "assets_bucket" {
source = "registry.patterneddesigns.ca/essentials/s3-bucket/aws"
version = "3.0.0"
bucket_name = "cdn-assets"
versioning_enabled = true
}
resource "aws_cloudfront_origin_access_control" "main" {
name = "s3-oac"
description = "OAC for S3 bucket"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
resource "aws_cloudfront_distribution" "cdn" {
enabled = true
default_root_object = "index.html"
origin {
origin_id = "s3-origin"
domain_name = module.assets_bucket.bucket_regional_domain_name
origin_access_control_id = aws_cloudfront_origin_access_control.main.id
}
default_cache_behavior {
target_origin_id = "s3-origin"
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
resource "aws_s3_bucket_policy" "cdn" {
bucket = module.assets_bucket.bucket_id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "AllowCloudFrontServicePrincipal"
Effect = "Allow"
Principal = {
Service = "cloudfront.amazonaws.com"
}
Action = "s3:GetObject"
Resource = "${module.assets_bucket.bucket_arn}/*"
Condition = {
StringEquals = {
"AWS:SourceArn" = aws_cloudfront_distribution.cdn.arn
}
}
}]
})
}