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>
280 lines
7.7 KiB
HCL
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"
|
|
}
|