modularise?

This commit is contained in:
2025-09-18 01:10:57 -05:00
parent 4e913599cb
commit 6e106657ea
7 changed files with 253 additions and 201 deletions

204
main.tf
View File

@@ -8,202 +8,10 @@ provider "aws" {
provider "cloudflare" { provider "cloudflare" {
} }
locals { module "static_website" {
common_tags = { source = "./modules/static-website"
Project = var.project_name
Environment = var.environment site_domain = var.site_domain
ManagedBy = "terraform" project_name = var.project_name
Domain = var.site_domain environment = var.environment
}
}
# block with type resource, uses provider's aws_s3_bucket resource type and names it site
resource "aws_s3_bucket" "site" {
# presumably
bucket = var.site_domain
tags = local.common_tags
}
# necessary to allow public users to eventually hit the s3 bucket
resource "aws_s3_bucket_public_access_block" "site" {
bucket = aws_s3_bucket.site.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
# name says it all
resource "aws_s3_bucket_website_configuration" "site" {
bucket = aws_s3_bucket.site.id
# Note that this isn't an =, i don't know why
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}
# This controls the ownership of the objects inside the bucket upon upload
# If possible, this sets the ownership of objects to the bucket owner
resource "aws_s3_bucket_ownership_controls" "site" {
bucket = aws_s3_bucket.site.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
resource "aws_s3_bucket_acl" "site" {
bucket = aws_s3_bucket.site.id
acl = "public-read"
depends_on = [
aws_s3_bucket_ownership_controls.site,
aws_s3_bucket_public_access_block.site
]
}
# Public read access for website objects only (not bucket itself)
resource "aws_s3_bucket_policy" "site" {
bucket = aws_s3_bucket.site.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "PublicReadGetObject"
Effect = "Allow"
Principal = "*"
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.site.arn}/*"
},
]
})
depends_on = [
aws_s3_bucket_public_access_block.site
]
}
# Cloudflare time
# data block is about retrieving data from ext. source, not configuring a resource that lives in state
data "cloudflare_zones" "domain" {
# why a filter?
filter {
name = var.site_domain
}
}
# DNS setup
resource "cloudflare_record" "site_cname" {
zone_id = data.cloudflare_zones.domain.zones[0].id
name = var.site_domain
value = aws_s3_bucket_website_configuration.site.website_endpoint
type = "CNAME"
ttl = 1
proxied = true
}
resource "cloudflare_record" "www" {
zone_id = data.cloudflare_zones.domain.zones[0].id
name = "www"
value = var.site_domain
type = "CNAME"
ttl = 1
proxied = true
}
# S3 bucket versioning for content protection
resource "aws_s3_bucket_versioning" "site" {
bucket = aws_s3_bucket.site.id
versioning_configuration {
status = "Enabled"
}
}
# Access logging bucket for monitoring
# resource "aws_s3_bucket" "access_logs" {
# bucket = "${var.site_domain}-access-logs"
#
# tags = merge(local.common_tags, {
# Purpose = "access-logs"
# })
# }
# resource "aws_s3_bucket_public_access_block" "access_logs" {
# bucket = aws_s3_bucket.access_logs.id
#
# block_public_acls = true
# block_public_policy = true
# ignore_public_acls = true
# restrict_public_buckets = true
# }
# Enable access logging for the main site bucket
# resource "aws_s3_bucket_logging" "site" {
# bucket = aws_s3_bucket.site.id
#
# target_bucket = aws_s3_bucket.access_logs.id
# target_prefix = "access-logs/"
# }
# Lifecycle rules for cost management
resource "aws_s3_bucket_lifecycle_configuration" "site" {
bucket = aws_s3_bucket.site.id
rule {
id = "cleanup_old_versions"
status = "Enabled"
noncurrent_version_expiration {
noncurrent_days = 90
}
filter {
prefix = ""
}
}
rule {
id = "cleanup_incomplete_uploads"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 7
}
filter {
prefix = ""
}
}
}
# Lifecycle rules for access logs
# resource "aws_s3_bucket_lifecycle_configuration" "access_logs" {
# bucket = aws_s3_bucket.access_logs.id
#
# rule {
# id = "delete_old_logs"
# status = "Enabled"
#
# expiration {
# days = 90
# }
# }
# }
resource "cloudflare_page_rule" "https" {
zone_id = data.cloudflare_zones.domain.zones[0].id
target = "*.${var.site_domain}/*"
actions {
always_use_https = true
}
} }

View File

@@ -0,0 +1,141 @@
locals {
common_tags = {
Project = var.project_name
Environment = var.environment
ManagedBy = "terraform"
Domain = var.site_domain
}
}
resource "aws_s3_bucket" "site" {
bucket = var.site_domain
tags = local.common_tags
}
resource "aws_s3_bucket_public_access_block" "site" {
bucket = aws_s3_bucket.site.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
resource "aws_s3_bucket_website_configuration" "site" {
bucket = aws_s3_bucket.site.id
index_document {
suffix = "index.html"
}
error_document {
key = "error.html"
}
}
resource "aws_s3_bucket_ownership_controls" "site" {
bucket = aws_s3_bucket.site.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
resource "aws_s3_bucket_acl" "site" {
bucket = aws_s3_bucket.site.id
acl = "public-read"
depends_on = [
aws_s3_bucket_ownership_controls.site,
aws_s3_bucket_public_access_block.site
]
}
resource "aws_s3_bucket_policy" "site" {
bucket = aws_s3_bucket.site.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "PublicReadGetObject"
Effect = "Allow"
Principal = "*"
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.site.arn}/*"
},
]
})
depends_on = [
aws_s3_bucket_public_access_block.site
]
}
data "cloudflare_zones" "domain" {
filter {
name = var.site_domain
}
}
resource "cloudflare_record" "site_cname" {
zone_id = data.cloudflare_zones.domain.zones[0].id
name = var.site_domain
value = aws_s3_bucket_website_configuration.site.website_endpoint
type = "CNAME"
ttl = 1
proxied = true
}
resource "cloudflare_record" "www" {
zone_id = data.cloudflare_zones.domain.zones[0].id
name = "www"
value = var.site_domain
type = "CNAME"
ttl = 1
proxied = true
}
resource "aws_s3_bucket_versioning" "site" {
bucket = aws_s3_bucket.site.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_lifecycle_configuration" "site" {
bucket = aws_s3_bucket.site.id
rule {
id = "cleanup_old_versions"
status = "Enabled"
noncurrent_version_expiration {
noncurrent_days = 90
}
filter {
prefix = ""
}
}
rule {
id = "cleanup_incomplete_uploads"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 7
}
filter {
prefix = ""
}
}
}
resource "cloudflare_page_rule" "https" {
zone_id = data.cloudflare_zones.domain.zones[0].id
target = "*.${var.site_domain}/*"
actions {
always_use_https = true
}
}

View File

@@ -0,0 +1,14 @@
output "website_bucket_name" {
description = "Name (id) of the bucket"
value = aws_s3_bucket.site.id
}
output "bucket_endpoint" {
description = "Bucket endpoint"
value = aws_s3_bucket_website_configuration.site.website_endpoint
}
output "domain_name" {
description = "Website endpoint"
value = var.site_domain
}

View File

@@ -0,0 +1,20 @@
variable "site_domain" {
type = string
description = "The domain name of the site"
}
variable "project_name" {
type = string
description = "Name of the project for resource tagging"
default = "tuffas"
}
variable "environment" {
type = string
description = "Environment name (e.g., dev, staging, prod)"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be one of: dev, staging, prod."
}
}

View File

@@ -0,0 +1,14 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.92"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 2.19.2"
}
}
required_version = ">= 1.2"
}

55
moved.tf Normal file
View File

@@ -0,0 +1,55 @@
moved {
from = aws_s3_bucket.site
to = module.static_website.aws_s3_bucket.site
}
moved {
from = aws_s3_bucket_acl.site
to = module.static_website.aws_s3_bucket_acl.site
}
moved {
from = aws_s3_bucket_lifecycle_configuration.site
to = module.static_website.aws_s3_bucket_lifecycle_configuration.site
}
moved {
from = aws_s3_bucket_ownership_controls.site
to = module.static_website.aws_s3_bucket_ownership_controls.site
}
moved {
from = aws_s3_bucket_policy.site
to = module.static_website.aws_s3_bucket_policy.site
}
moved {
from = aws_s3_bucket_public_access_block.site
to = module.static_website.aws_s3_bucket_public_access_block.site
}
moved {
from = aws_s3_bucket_versioning.site
to = module.static_website.aws_s3_bucket_versioning.site
}
moved {
from = aws_s3_bucket_website_configuration.site
to = module.static_website.aws_s3_bucket_website_configuration.site
}
moved {
from = cloudflare_record.www
to = module.static_website.cloudflare_record.www
}
moved {
from = cloudflare_record.site_cname
to = module.static_website.cloudflare_record.site_cname
}
moved {
from = cloudflare_page_rule.https
to = module.static_website.cloudflare_page_rule.https
}

View File

@@ -1,14 +1,14 @@
output "website_bucket_name" { output "website_bucket_name" {
description = "Name (id) of the bucket" description = "Name (id) of the bucket"
value = aws_s3_bucket.site.id value = module.static_website.website_bucket_name
} }
output "bucket_endpoint" { output "bucket_endpoint" {
description = "Bucket endpoint" description = "Bucket endpoint"
value = aws_s3_bucket_website_configuration.site.website_endpoint value = module.static_website.bucket_endpoint
} }
output "domain_name" { output "domain_name" {
description = "Website endpoint" description = "Website endpoint"
value = var.site_domain value = module.static_website.domain_name
} }