diff --git a/output/builds/k8s-manifests.yaml b/output/builds/k8s-manifests.yaml index 3bfcd60..b7c1116 100644 --- a/output/builds/k8s-manifests.yaml +++ b/output/builds/k8s-manifests.yaml @@ -32,22 +32,24 @@ data: PLATE_SOLVE_RESIDUAL_MAX_ARCSEC: "0.5" CORRELATION_MAHALANOBIS_MAX: "4.0" KAFKA_BOOTSTRAP: "kafka.sentinelforge.svc.cluster.local:9092" - POSTGIS_DSN: "postgresql://sentinelforge:sf@postgis.sentinelforge.svc:5432/catalog" + # POSTGIS_DSN moved to pipeline-secrets (SEC-03) GPU_UTILIZATION_TARGET_PCT: "40" FRAME_PROCESS_MAX_MS: "500" --- -# Secret: database and Kafka credentials -apiVersion: v1 -kind: Secret -metadata: - name: pipeline-secrets - namespace: sentinelforge -type: Opaque -stringData: - POSTGIS_PASSWORD: "${POSTGIS_PASSWORD}" - KAFKA_SSL_KEY: "${KAFKA_SSL_KEY}" - GEMINI_API_KEY: "${GEMINI_API_KEY}" +# Pipeline Secrets (SEC-05): +# NOTE: Secrets must not contain unexpanded literal ${VAR} placeholders in committed manifests. +# Provision the 'pipeline-secrets' secret externally before deploying (e.g. in GitOps/K8s cluster): +# kubectl create secret generic pipeline-secrets \ +# --namespace=sentinelforge \ +# --from-env-file=.env +# Expected secret keys referenced by deployments and statefulsets: +# - POSTGIS_PASSWORD: Database user password +# - POSTGIS_DSN: Credentialed database connection string (moved from ConfigMap, SEC-03) +# - DATABASE_URL: Standard database connection string +# - KAFKA_SSL_KEY: SSL key for mutual TLS Kafka transport +# - GEMINI_API_KEY: Google Gemini API key +# - SF_API_KEY: SentinelForge internal API key --- # Edge Pipeline - DaemonSet (runs on every Jetson Orin node) diff --git a/terraform/main.tf b/terraform/main.tf index 146f746..0562cea 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -5,6 +5,76 @@ provider "aws" { region = var.aws_region } +# --- Data Sources --- +data "aws_vpc" "selected" { + id = var.vpc_id +} + +# --- Security Groups (Least Privilege) --- +resource "aws_security_group" "kafka_sg" { + name = "sentinelforge-kafka-sg" + description = "Security group for Managed Streaming for Apache Kafka (MSK)" + vpc_id = var.vpc_id + + ingress { + description = "MSK TLS broker access from within VPC" + from_port = 9094 + to_port = 9094 + protocol = "tcp" + cidr_blocks = [data.aws_vpc.selected.cidr_block] + } + + ingress { + description = "MSK plain broker access from within VPC" + from_port = 9092 + to_port = 9092 + protocol = "tcp" + cidr_blocks = [data.aws_vpc.selected.cidr_block] + } + + egress { + description = "Allow all outbound traffic" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { + Name = "sentinelforge-kafka-sg" + Environment = "production" + Project = "SentinelForge" + } +} + +resource "aws_security_group" "db_sg" { + name = "sentinelforge-db-sg" + description = "Security group for PostGIS RDS PostgreSQL instance" + vpc_id = var.vpc_id + + ingress { + description = "PostgreSQL access from within VPC" + from_port = 5432 + to_port = 5432 + protocol = "tcp" + cidr_blocks = [data.aws_vpc.selected.cidr_block] + } + + egress { + description = "Allow all outbound traffic" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { + Name = "sentinelforge-db-sg" + Environment = "production" + Project = "SentinelForge" + } +} + # 1. Managed Streaming for Apache Kafka (MSK) # Replaces the basic Kafka StatefulSet for production resilience resource "aws_msk_cluster" "sentinelforge_kafka" { diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..6514141 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,30 @@ +# Variables for SentinelForge Terraform Infrastructure + +variable "aws_region" { + type = string + description = "AWS region for infrastructure deployment" + default = "us-gov-west-1" +} + +variable "vpc_id" { + type = string + description = "VPC ID where the infrastructure is deployed" +} + +variable "private_subnets" { + type = list(string) + description = "List of private subnet IDs for MSK and EKS" +} + +variable "db_username" { + type = string + description = "Master username for RDS PostGIS database" + default = "sentinelforge" +} + +variable "db_password" { + type = string + description = "Master password for RDS PostGIS database" + sensitive = true + # No default for secrets +}