Files
SentryAgent.ai Developer 6913d62648 feat(phase-2): workstream 8 — Multi-Region Terraform Deployment
AWS environment:
- VPC (3-AZ, public + private subnets, NAT gateways, VPC endpoints for ECR/SM/CW)
- ECS Fargate service (sentryagent/agentidp) — secrets from Secrets Manager
- RDS PostgreSQL 14 (Multi-AZ, encrypted, VPC-internal, storage autoscaling)
- ElastiCache Redis 7 (primary + replica, at-rest + in-transit encryption)
- ALB with HTTPS/443, HTTP→HTTPS redirect, ACM certificate
- Route 53 alias record

GCP environment:
- VPC + private services access + Serverless VPC connector
- Cloud Run service — secrets from Secret Manager
- Cloud SQL PostgreSQL 14 (private IP, no public endpoint)
- Cloud Memorystore Redis 7 (VPC-internal, AUTH enabled)

Shared:
- 4 reusable modules: agentidp (dual AWS/GCP), rds, redis, lb
- No hardcoded secrets; all sensitive vars marked sensitive=true
- terraform.tfvars.example for both environments
- docs/devops/deployment.md — AWS + GCP step-by-step walkthrough, rollback procedures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 06:25:14 +00:00

280 lines
7.7 KiB
HCL

################################################################################
# Module: agentidp
# Variables
#
# Accepts all configuration for deploying the AgentIdP container to either
# AWS ECS Fargate (provider = "aws") or GCP Cloud Run (provider = "gcp").
################################################################################
variable "provider_type" {
description = "Cloud provider target: 'aws' or 'gcp'."
type = string
validation {
condition = contains(["aws", "gcp"], var.provider_type)
error_message = "provider_type must be either 'aws' or 'gcp'."
}
}
variable "environment" {
description = "Deployment environment label (e.g. production, staging)."
type = string
}
variable "project" {
description = "Project identifier used in resource tags and names."
type = string
default = "sentryagent-agentidp"
}
variable "app_image" {
description = "Fully-qualified container image reference including registry host and tag."
type = string
# Example: "sentryagent/agentidp:1.2.3"
}
variable "app_port" {
description = "Port the AgentIdP container listens on. Must match the PORT env var."
type = number
default = 3000
}
################################################################################
# AWS-specific variables (required when provider_type = "aws")
################################################################################
variable "aws_region" {
description = "(AWS) AWS region where ECS resources are deployed."
type = string
default = ""
}
variable "aws_vpc_id" {
description = "(AWS) VPC ID in which to create the ECS service and security group."
type = string
default = ""
}
variable "aws_subnet_ids" {
description = "(AWS) List of private subnet IDs for the ECS Fargate tasks."
type = list(string)
default = []
}
variable "aws_target_group_arn" {
description = "(AWS) ARN of the ALB target group to register ECS tasks with."
type = string
default = ""
}
variable "aws_execution_role_arn" {
description = "(AWS) IAM role ARN that ECS uses to pull images and write logs (ECS task execution role)."
type = string
default = ""
}
variable "aws_task_role_arn" {
description = "(AWS) IAM role ARN granted to the running ECS task (allows it to call Secrets Manager, etc.)."
type = string
default = ""
}
variable "aws_log_group_name" {
description = "(AWS) CloudWatch log group name where container logs are sent."
type = string
default = "/ecs/sentryagent-agentidp"
}
variable "aws_desired_count" {
description = "(AWS) Number of ECS Fargate task instances to run."
type = number
default = 2
}
variable "aws_cpu" {
description = "(AWS) ECS task CPU units (256 = 0.25 vCPU)."
type = number
default = 512
}
variable "aws_memory" {
description = "(AWS) ECS task memory in MiB."
type = number
default = 1024
}
# Secret ARNs — the ECS task fetches these from Secrets Manager at launch time.
# The task execution role must have secretsmanager:GetSecretValue on each ARN.
variable "aws_secret_database_url_arn" {
description = "(AWS) ARN of the Secrets Manager secret holding DATABASE_URL."
type = string
default = ""
sensitive = true
}
variable "aws_secret_redis_url_arn" {
description = "(AWS) ARN of the Secrets Manager secret holding REDIS_URL."
type = string
default = ""
sensitive = true
}
variable "aws_secret_jwt_private_key_arn" {
description = "(AWS) ARN of the Secrets Manager secret holding JWT_PRIVATE_KEY."
type = string
default = ""
sensitive = true
}
variable "aws_secret_jwt_public_key_arn" {
description = "(AWS) ARN of the Secrets Manager secret holding JWT_PUBLIC_KEY."
type = string
default = ""
sensitive = true
}
variable "aws_secret_vault_token_arn" {
description = "(AWS) ARN of the Secrets Manager secret holding VAULT_TOKEN. Leave empty to omit Vault integration."
type = string
default = ""
sensitive = true
}
variable "aws_vault_addr" {
description = "(AWS) HashiCorp Vault address injected as a plain env var (not a secret). Leave empty to disable."
type = string
default = ""
}
variable "aws_vault_mount" {
description = "(AWS) HashiCorp Vault KV v2 mount path."
type = string
default = "secret"
}
variable "aws_cors_origin" {
description = "(AWS) Value for CORS_ORIGIN env var."
type = string
default = "*"
}
variable "aws_policy_dir" {
description = "(AWS) Path inside the container where OPA policy files are located."
type = string
default = "/app/policies"
}
################################################################################
# GCP-specific variables (required when provider_type = "gcp")
################################################################################
variable "gcp_project_id" {
description = "(GCP) GCP project ID where Cloud Run and supporting resources live."
type = string
default = ""
}
variable "gcp_region" {
description = "(GCP) GCP region for Cloud Run deployment."
type = string
default = ""
}
variable "gcp_service_account_email" {
description = "(GCP) Service account email attached to the Cloud Run service."
type = string
default = ""
}
variable "gcp_vpc_connector_name" {
description = "(GCP) Serverless VPC Access connector name for reaching Cloud SQL and Memorystore."
type = string
default = ""
}
variable "gcp_min_instances" {
description = "(GCP) Minimum number of Cloud Run instances (set > 0 to avoid cold starts)."
type = number
default = 1
}
variable "gcp_max_instances" {
description = "(GCP) Maximum number of Cloud Run instances."
type = number
default = 10
}
variable "gcp_cpu" {
description = "(GCP) CPU limit for each Cloud Run container instance (e.g. '1', '2')."
type = string
default = "1"
}
variable "gcp_memory" {
description = "(GCP) Memory limit for each Cloud Run container instance (e.g. '512Mi', '1Gi')."
type = string
default = "512Mi"
}
# Secret Manager secret IDs — the Cloud Run service fetches these at startup.
variable "gcp_secret_database_url_id" {
description = "(GCP) Secret Manager secret ID for DATABASE_URL."
type = string
default = ""
sensitive = true
}
variable "gcp_secret_redis_url_id" {
description = "(GCP) Secret Manager secret ID for REDIS_URL."
type = string
default = ""
sensitive = true
}
variable "gcp_secret_jwt_private_key_id" {
description = "(GCP) Secret Manager secret ID for JWT_PRIVATE_KEY."
type = string
default = ""
sensitive = true
}
variable "gcp_secret_jwt_public_key_id" {
description = "(GCP) Secret Manager secret ID for JWT_PUBLIC_KEY."
type = string
default = ""
sensitive = true
}
variable "gcp_secret_vault_token_id" {
description = "(GCP) Secret Manager secret ID for VAULT_TOKEN. Leave empty to omit Vault integration."
type = string
default = ""
sensitive = true
}
variable "gcp_vault_addr" {
description = "(GCP) HashiCorp Vault address injected as a plain env var. Leave empty to disable."
type = string
default = ""
}
variable "gcp_vault_mount" {
description = "(GCP) HashiCorp Vault KV v2 mount path."
type = string
default = "secret"
}
variable "gcp_cors_origin" {
description = "(GCP) Value for CORS_ORIGIN env var."
type = string
default = "*"
}
variable "gcp_policy_dir" {
description = "(GCP) Path inside the Cloud Run container where OPA policy files are located."
type = string
default = "/app/policies"
}