# main.tf — GAC compliance fixture
# Produces zero policy violations across all evaluated categories

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

locals {
  baseline_tags = {
    "stack-name"          = "gac-compliance-fixture"
    "application-name"    = "GACFixture"
    "project"             = "DC-Migration-Project"
    "environment"         = "dev"
    "cost-center-opex"    = "271"
    "cost-center-capex"   = "000"
    "data-classification" = "Internal"
    "availability-tier"   = "Tier 1"
    "app-owner"           = "Director IT Infrastructure and Platform Engineering"
    "team"                = "devops"
    "assignment-group"    = "hca-aws-support"
    "owner"               = "hca-itinfradevopsengineering@hcs.com"
    "business-unit"       = "Infrastructure and Planning"
    "managed-by"          = "terraform"
  }
}

# GAC-025 — Provider with all mandatory default tags
provider "aws" {
  region = "ap-south-1"

  default_tags {
    tags = {
      managed-by = "terraform"
    }
  }
}

# GAC-003 — S3 bucket with versioning enabled
resource "aws_s3_bucket" "good_bucket" {
  bucket = "good-gac-bucket"
  tags   = local.baseline_tags
}

resource "aws_s3_bucket_versioning" "good_versioning" {
  bucket = aws_s3_bucket.good_bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}

# GAC-001 / STR-001 — Public access block
resource "aws_s3_bucket_public_access_block" "good_bucket" {
  bucket                  = aws_s3_bucket.good_bucket.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# GAC-002 / STR-004 — Server-side encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "good_bucket" {
  bucket = aws_s3_bucket.good_bucket.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = "arn:aws:kms:ap-south-1:123456789012:key/abcd1234-a123-456a-a12b-a123b4cd56ef"
    }
  }
}

# STR-007 — Ownership controls
resource "aws_s3_bucket_ownership_controls" "good_bucket" {
  bucket = aws_s3_bucket.good_bucket.id
  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}

# GAC-004 / STR-005 — TLS-only bucket policy
resource "aws_s3_bucket_policy" "good_bucket" {
  bucket = aws_s3_bucket.good_bucket.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid       = "DenyInsecureTransport"
      Effect    = "Deny"
      Principal = "*"
      Action    = "s3:*"
      Resource = [
        aws_s3_bucket.good_bucket.arn,
        "${aws_s3_bucket.good_bucket.arn}/*"
      ]
      Condition = {
        Bool = { "aws:SecureTransport" = "false" }
      }
    }]
  })
}

# GAC-012 — RDS with adequate backup retention (max 35 days)
# GAC-009 / DAT-002 — Storage encryption
# GAC-011 / DAT-004 — Deletion protection
# DAT-003 / LOM-008 — CloudWatch log exports
resource "aws_db_instance" "good_rds" {
  identifier                      = "good-gac-rds"
  engine                          = "mysql"
  engine_version                  = "8.0"
  instance_class                  = "db.t3.micro"
  allocated_storage               = 20
  username                        = "admin"
  password                        = "Goodpassword123"
  skip_final_snapshot             = true
  backup_retention_period         = 35
  storage_encrypted               = true
  deletion_protection             = true
  enabled_cloudwatch_logs_exports = ["error", "general", "slowquery"]
  tags                            = local.baseline_tags
}

# GAC-014 — IAM policy with scoped permissions
resource "aws_iam_policy" "good_admin_policy" {
  name = "good-admin-policy"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Action   = ["s3:GetObject", "s3:PutObject"]
      Resource = "arn:aws:s3:::good-gac-bucket/*"
    }]
  })
  tags = local.baseline_tags
}

# GAC-015 — IAM role with scoped trust principal and specific action
# IAM-004 — Permissions boundary
resource "aws_iam_role" "good_role" {
  name                 = "good-gac-role"
  permissions_boundary = "arn:aws:iam::123456789012:policy/good-permissions-boundary"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect    = "Allow"
      Principal = { Service = "ec2.amazonaws.com" }
      Action    = "sts:AssumeRole"
    }]
  })
  tags = local.baseline_tags
}

# GAC-016 — Strong password policy
resource "aws_iam_account_password_policy" "good_password_policy" {
  minimum_password_length      = 14
  require_symbols              = true
  require_numbers              = true
  require_uppercase_characters = true
  require_lowercase_characters = true
  password_reuse_prevention    = 24
  max_password_age             = 90
}

# GAC-022 — CloudFront with modern TLS
resource "aws_cloudfront_distribution" "good_cf" {
  enabled = true

  default_cache_behavior {
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    target_origin_id       = "good-origin"
    viewer_protocol_policy = "redirect-to-https"
    forwarded_values {
      query_string = false
      cookies { forward = "none" }
    }
  }

  viewer_certificate {
    acm_certificate_arn      = "arn:aws:acm:us-east-1:123456789012:certificate/abc-123"
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.2_2021"
  }

  origin {
    domain_name = "example.com"
    origin_id   = "good-origin"
    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "https-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }
  }

  restrictions {
    geo_restriction { restriction_type = "none" }
  }

  tags = local.baseline_tags
}

# GAC-023 — EKS with private endpoint only
resource "aws_eks_cluster" "good_eks" {
  name     = "good-eks"
  role_arn = "arn:aws:iam::123456789012:role/eks-role"

  vpc_config {
    subnet_ids              = ["subnet-12345678"]
    endpoint_public_access  = false
    endpoint_private_access = true
  }

  tags = local.baseline_tags
}
