Compare commits

...

2 Commits

Author SHA1 Message Date
4e913599cb doc: change example vars
All checks were successful
Terraform validate and apply / nix (ubuntu-latest) (push) Successful in 3m7s
2025-09-17 15:58:44 -05:00
043c379647 adding some refactor and example values 2025-09-17 15:58:11 -05:00
4 changed files with 137 additions and 6 deletions

View File

@@ -10,6 +10,10 @@ env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
TF_VAR_aws_region: ${{ vars.TF_VAR_aws_region }} TF_VAR_aws_region: ${{ vars.TF_VAR_aws_region }}
TF_VAR_site_domain: ${{ vars.TF_VAR_site_domain }} TF_VAR_site_domain: ${{ vars.TF_VAR_site_domain }}
TF_VAR_project_name: ${{ vars.TF_VAR_project_name }}
TF_VAR_environment: ${{ vars.TF_VAR_environment }}
TF_VAR_tuffas_applier_role_arn: ${{ vars.TF_VAR_tuffas_applier_role_arn }}
TF_VAR_tfstate_backend_role_arn: ${{ vars.TF_VAR_tfstate_backend_role_arn }}
TF_PLUGIN_CACHE_DIR: ${{ github.workspace }}/.terraform.d/plugin-cache TF_PLUGIN_CACHE_DIR: ${{ github.workspace }}/.terraform.d/plugin-cache
jobs: jobs:
nix: nix:
@@ -46,3 +50,7 @@ jobs:
- name: Plan - name: Plan
id: plan id: plan
run: terraform plan -no-color -input=false run: terraform plan -no-color -input=false
- name: Apply
id: apply
run: terraform apply -auto-approve -no-color -input=false
if: github.ref == 'refs/heads/master' && github.event_name == 'push'

97
main.tf
View File

@@ -1,17 +1,28 @@
provider "aws" { provider "aws" {
region = var.aws_region region = var.aws_region
assume_role { assume_role {
role_arn = "arn:aws:iam::677425296084:role/tuffas-applier" role_arn = var.tuffas_applier_role_arn
} }
} }
provider "cloudflare" { provider "cloudflare" {
} }
locals {
common_tags = {
Project = var.project_name
Environment = var.environment
ManagedBy = "terraform"
Domain = var.site_domain
}
}
# block with type resource, uses provider's aws_s3_bucket resource type and names it site # block with type resource, uses provider's aws_s3_bucket resource type and names it site
resource "aws_s3_bucket" "site" { resource "aws_s3_bucket" "site" {
# presumably # presumably
bucket = var.site_domain bucket = var.site_domain
tags = local.common_tags
} }
# necessary to allow public users to eventually hit the s3 bucket # necessary to allow public users to eventually hit the s3 bucket
@@ -60,7 +71,7 @@ resource "aws_s3_bucket_acl" "site" {
} }
# Full permissions for the bucket, which allows anyone to access any object in the bucket # Public read access for website objects only (not bucket itself)
resource "aws_s3_bucket_policy" "site" { resource "aws_s3_bucket_policy" "site" {
bucket = aws_s3_bucket.site.id bucket = aws_s3_bucket.site.id
@@ -72,10 +83,7 @@ resource "aws_s3_bucket_policy" "site" {
Effect = "Allow" Effect = "Allow"
Principal = "*" Principal = "*"
Action = "s3:GetObject" Action = "s3:GetObject"
Resource = [ Resource = "${aws_s3_bucket.site.arn}/*"
aws_s3_bucket.site.arn,
"${aws_s3_bucket.site.arn}/*",
]
}, },
] ]
}) })
@@ -115,6 +123,83 @@ resource "cloudflare_record" "www" {
proxied = true 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" { resource "cloudflare_page_rule" "https" {
zone_id = data.cloudflare_zones.domain.zones[0].id zone_id = data.cloudflare_zones.domain.zones[0].id
target = "*.${var.site_domain}/*" target = "*.${var.site_domain}/*"

17
terraform.tfvars.example Normal file
View File

@@ -0,0 +1,17 @@
# Example Terraform variables file
# Copy this file to terraform.tfvars and update with your actual values
# AWS region where resources will be created
aws_region = "us-east-2"
# Your domain name (must be managed by Cloudflare)
site_domain = "example.com"
# Project name for resource tagging
project_name = "tuffas"
# Environment (dev, staging, prod)
environment = "prod"
# IAM role ARNs (update with your actual role ARNs)
tuffas_applier_role_arn = "arn:aws:iam::YOUR-ACCOUNT-ID:role/ROLE_NAME"

View File

@@ -7,3 +7,24 @@ variable "site_domain" {
type = string type = string
description = "The domain name of the site" description = "The domain name of the site"
} }
variable "tuffas_applier_role_arn" {
type = string
description = "IAM role ARN for Terraform to assume when applying changes"
}
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."
}
}