Compare commits
2 Commits
269545596a
...
4e913599cb
| Author | SHA1 | Date | |
|---|---|---|---|
|
4e913599cb
|
|||
|
043c379647
|
@@ -10,6 +10,10 @@ env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
TF_VAR_aws_region: ${{ vars.TF_VAR_aws_region }}
|
||||
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
|
||||
jobs:
|
||||
nix:
|
||||
@@ -46,3 +50,7 @@ jobs:
|
||||
- name: Plan
|
||||
id: plan
|
||||
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
97
main.tf
@@ -1,17 +1,28 @@
|
||||
provider "aws" {
|
||||
region = var.aws_region
|
||||
assume_role {
|
||||
role_arn = "arn:aws:iam::677425296084:role/tuffas-applier"
|
||||
role_arn = var.tuffas_applier_role_arn
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
@@ -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" {
|
||||
bucket = aws_s3_bucket.site.id
|
||||
|
||||
@@ -72,10 +83,7 @@ resource "aws_s3_bucket_policy" "site" {
|
||||
Effect = "Allow"
|
||||
Principal = "*"
|
||||
Action = "s3:GetObject"
|
||||
Resource = [
|
||||
aws_s3_bucket.site.arn,
|
||||
"${aws_s3_bucket.site.arn}/*",
|
||||
]
|
||||
Resource = "${aws_s3_bucket.site.arn}/*"
|
||||
},
|
||||
]
|
||||
})
|
||||
@@ -115,6 +123,83 @@ resource "cloudflare_record" "www" {
|
||||
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}/*"
|
||||
|
||||
17
terraform.tfvars.example
Normal file
17
terraform.tfvars.example
Normal 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"
|
||||
21
variables.tf
21
variables.tf
@@ -7,3 +7,24 @@ variable "site_domain" {
|
||||
type = string
|
||||
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."
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user