Files
turnstone/deploy/terraform/modules/aws-ecs/security.tf
T
Patrick Buckley 2b58c127b1 Add pluggable storage backend (SQLite + PostgreSQL) and deployment packaging (#20)
* Add pluggable storage backend (SQLite + PostgreSQL) and deployment packaging

Database abstraction: StorageBackend protocol with 21 methods, SQLAlchemy Core
schema, SQLite backend (FTS5), PostgreSQL backend (tsvector/ILIKE), Alembic
migrations, singleton registry. memory.py reduced to thin facade. Session.py
open_db() calls replaced with generic KV methods. [database] config section
with env var support.

Deployment: Docker Compose production profile with PostgreSQL, Dockerfile with
postgres extras and migration entrypoint, Helm chart with bitnami subcharts,
Terraform AWS ECS/Fargate module with RDS + ElastiCache + ALB.

39 new storage tests (934 total). mypy strict clean. Docs and diagrams updated.

* Address PR #20 review feedback (16 items)

- Backends only call create_all() when Alembic migrations are disabled
- Helm configmap uses correct TURNSTONE_DB_BACKEND env var; DB URL
  constructed via env expansion with secret reference instead of ConfigMap
- Migration errors fail fast for PostgreSQL (only non-fatal for SQLite)
- save_memory/delete_memory wrapped in exception handling like other facade fns
- pool_size passed through from config/env to init_storage() in cli + server
- Terraform: DB URL moved to Secrets Manager, auth enabled flag set,
  optional TLS listeners with certificate_arn, Redis transit encryption on
- Docker entrypoint no longer suppresses migration output
- Diagram fixes: removed StaticPool claim, removed non-existent migration ref
- compose.yaml/README: clarified production profile requires DB env vars
2026-03-03 22:57:34 -08:00

134 lines
4.6 KiB
Terraform

# ---------- ALB Security Group ----------
resource "aws_security_group" "alb" {
name = "${var.name_prefix}-alb-${var.environment}"
description = "Allow inbound HTTP to ALB for server and console"
vpc_id = var.vpc_id
tags = local.common_tags
}
resource "aws_vpc_security_group_ingress_rule" "alb_http" {
security_group_id = aws_security_group.alb.id
description = "HTTP traffic to server"
from_port = 80
to_port = 80
ip_protocol = "tcp"
cidr_ipv4 = "0.0.0.0/0"
tags = local.common_tags
}
resource "aws_vpc_security_group_ingress_rule" "alb_https" {
count = var.certificate_arn != "" ? 1 : 0
security_group_id = aws_security_group.alb.id
description = "HTTPS traffic to server"
from_port = 443
to_port = 443
ip_protocol = "tcp"
cidr_ipv4 = "0.0.0.0/0"
tags = local.common_tags
}
resource "aws_vpc_security_group_ingress_rule" "alb_console" {
security_group_id = aws_security_group.alb.id
description = "HTTP traffic to console"
from_port = 8090
to_port = 8090
ip_protocol = "tcp"
cidr_ipv4 = "0.0.0.0/0"
tags = local.common_tags
}
resource "aws_vpc_security_group_ingress_rule" "alb_console_https" {
count = var.certificate_arn != "" ? 1 : 0
security_group_id = aws_security_group.alb.id
description = "HTTPS traffic to console"
from_port = 8443
to_port = 8443
ip_protocol = "tcp"
cidr_ipv4 = "0.0.0.0/0"
tags = local.common_tags
}
resource "aws_vpc_security_group_egress_rule" "alb_all" {
security_group_id = aws_security_group.alb.id
description = "Allow all outbound"
ip_protocol = "-1"
cidr_ipv4 = "0.0.0.0/0"
tags = local.common_tags
}
# ---------- ECS Tasks Security Group ----------
resource "aws_security_group" "ecs_tasks" {
name = "${var.name_prefix}-ecs-tasks-${var.environment}"
description = "Allow traffic from ALB to ECS tasks and outbound internet"
vpc_id = var.vpc_id
tags = local.common_tags
}
resource "aws_vpc_security_group_ingress_rule" "ecs_from_alb_server" {
security_group_id = aws_security_group.ecs_tasks.id
description = "Server port from ALB"
from_port = 8080
to_port = 8080
ip_protocol = "tcp"
referenced_security_group_id = aws_security_group.alb.id
tags = local.common_tags
}
resource "aws_vpc_security_group_ingress_rule" "ecs_from_alb_console" {
security_group_id = aws_security_group.ecs_tasks.id
description = "Console port from ALB"
from_port = 8090
to_port = 8090
ip_protocol = "tcp"
referenced_security_group_id = aws_security_group.alb.id
tags = local.common_tags
}
resource "aws_vpc_security_group_egress_rule" "ecs_all" {
security_group_id = aws_security_group.ecs_tasks.id
description = "Allow all outbound (LLM APIs, ECR, Secrets Manager, etc.)"
ip_protocol = "-1"
cidr_ipv4 = "0.0.0.0/0"
tags = local.common_tags
}
# ---------- RDS Security Group ----------
resource "aws_security_group" "rds" {
name = "${var.name_prefix}-rds-${var.environment}"
description = "Allow PostgreSQL access from ECS tasks"
vpc_id = var.vpc_id
tags = local.common_tags
}
resource "aws_vpc_security_group_ingress_rule" "rds_from_ecs" {
security_group_id = aws_security_group.rds.id
description = "PostgreSQL from ECS tasks"
from_port = 5432
to_port = 5432
ip_protocol = "tcp"
referenced_security_group_id = aws_security_group.ecs_tasks.id
tags = local.common_tags
}
# ---------- Redis Security Group ----------
resource "aws_security_group" "redis" {
name = "${var.name_prefix}-redis-${var.environment}"
description = "Allow Redis access from ECS tasks"
vpc_id = var.vpc_id
tags = local.common_tags
}
resource "aws_vpc_security_group_ingress_rule" "redis_from_ecs" {
security_group_id = aws_security_group.redis.id
description = "Redis from ECS tasks"
from_port = 6379
to_port = 6379
ip_protocol = "tcp"
referenced_security_group_id = aws_security_group.ecs_tasks.id
tags = local.common_tags
}