BYO Infrastructure
ThinkWork creates all its infrastructure by default, but most production teams already have a VPC, a database, and an identity system. Rather than creating parallel infrastructure, ThinkWork can adopt yours.
Every major infrastructure component has a create_* flag and a corresponding existing_* variable. Set create_vpc = false and provide existing_vpc_id, and ThinkWork deploys into your VPC instead of creating one.
BYO VPC
Section titled “BYO VPC”The most common scenario: you already have a VPC with private subnets and NAT gateways, and you want ThinkWork to deploy into it.
create_vpc = falseexisting_vpc_id = "vpc-0a1b2c3d4e5f67890"
# Provide at least 2 private subnets for Aurora and Lambdaexisting_private_subnet_ids = [ "subnet-0a1b2c3d4e5f67890", "subnet-0b2c3d4e5f6789012"]
# Provide at least 2 public subnets for the NAT gateway (if already exists)existing_public_subnet_ids = [ "subnet-0c3d4e5f678901234", "subnet-0d4e5f6789012345"]
# If you have an existing NAT gateway, specify its ID# existing_nat_gateway_id = "nat-0a1b2c3d4e5f67890"VPC requirements
Section titled “VPC requirements”Your existing VPC must have:
- At least 2 private subnets in different AZs (for Aurora Multi-AZ and Lambda ENIs)
- At least 2 public subnets in different AZs (for load balancers, if used)
- DNS resolution and DNS hostnames enabled on the VPC
- Outbound internet access from private subnets (NAT gateway or VPC endpoints)
- Inbound HTTPS (443) from 0.0.0.0/0 to public subnets (for API Gateway and CloudFront origins)
BYO Database
Section titled “BYO Database”If you have an existing Aurora Postgres or RDS Postgres cluster, ThinkWork can use it instead of creating a new one.
create_database = falseexisting_db_host = "mydb.cluster-xyz.us-east-1.rds.amazonaws.com"existing_db_port = 5432existing_db_name = "thinkwork"existing_db_username = "thinkwork_app"db_password = "your-existing-db-password"
# The Lambda security group needs access to your DB security groupexisting_db_security_group_id = "sg-0a1b2c3d4e5f67890"Database requirements
Section titled “Database requirements”| Requirement | Details |
|---|---|
| Engine | Postgres 15+ or Aurora Postgres 15+ |
| Min storage | 20 GB |
| Extensions | pgvector, uuid-ossp, pg_trgm |
| Connectivity | Private subnet, accessible from Lambda security group |
To enable required extensions (run once as a superuser):
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";CREATE EXTENSION IF NOT EXISTS "pg_trgm";CREATE EXTENSION IF NOT EXISTS "vector";Migrations
Section titled “Migrations”ThinkWork runs migrations via a Lambda function invoked during deploy. The migration runner uses the db_password variable to connect. After initial deploy, schema changes in subsequent ThinkWork versions are applied automatically on thinkwork deploy -s <stage>.
To preview schema changes before applying, use thinkwork plan -s <stage> — it prints the Terraform plan including any migration Lambda invocations.
BYO Cognito
Section titled “BYO Cognito”If your team already uses Cognito for authentication, ThinkWork can attach to your existing user pool.
create_cognito = falseexisting_user_pool_id = "us-east-1_ABC123XYZ"existing_user_pool_arn = "arn:aws:cognito-idp:us-east-1:123456789012:userpool/us-east-1_ABC123XYZ"existing_identity_pool_id = "us-east-1:12345678-abcd-efgh-ijkl-123456789012"
# ThinkWork will create a new app client in your existing pool# unless you provide an existing one# existing_user_pool_client_id = "1abc2def3ghi4jkl"Cognito requirements
Section titled “Cognito requirements”Your existing user pool must have:
- Email as a required attribute
- Username or email sign-in enabled
ALLOW_USER_SRP_AUTHandALLOW_REFRESH_TOKEN_AUTHauth flows enabled- A compatible password policy (ThinkWork enforces minimum 8 characters)
BYO everything: example configuration
Section titled “BYO everything: example configuration”# terraform.tfvars — full BYO configuration
stage = "prod"region = "us-east-1"account_id = "123456789012"
# Bring your own networkcreate_vpc = falseexisting_vpc_id = "vpc-0a1b2c3d4e5f67890"existing_private_subnet_ids = ["subnet-aaa", "subnet-bbb"]existing_public_subnet_ids = ["subnet-ccc", "subnet-ddd"]
# Bring your own databasecreate_database = falseexisting_db_host = "prod.cluster-abc.us-east-1.rds.amazonaws.com"existing_db_port = 5432existing_db_name = "thinkwork_prod"existing_db_username = "thinkwork"db_password = "secure-password-here"existing_db_security_group_id = "sg-0a1b2c3d4e5f"
# Bring your own Cognitocreate_cognito = falseexisting_user_pool_id = "us-east-1_PROD123"existing_user_pool_arn = "arn:aws:cognito-idp:us-east-1:123456789012:userpool/us-east-1_PROD123"existing_identity_pool_id = "us-east-1:prod-identity-pool-id"
# ThinkWork still creates: AppSync, API Gateway, Lambda, S3, Step Functions,# CloudFront, KMS, SES, Bedrock KB (backed by Aurora pgvector), EventBridge, IAMPartial BYO
Section titled “Partial BYO”You can mix and match. A common pattern for teams migrating to ThinkWork:
# Bring your existing VPC and Cognito, but let ThinkWork create the databasecreate_vpc = falseexisting_vpc_id = "vpc-existing"# ... subnet IDs ...
create_cognito = falseexisting_user_pool_id = "us-east-1_existing"# ... other Cognito vars ...
# Database: let ThinkWork create Aurora (default behavior)create_database = truedb_password = "new-password-for-thinkwork-db"database_engine = "aurora-serverless"VPC endpoints (no NAT gateway)
Section titled “VPC endpoints (no NAT gateway)”If your private subnets have no NAT gateway, enable VPC endpoints so Lambda functions can reach AWS services privately:
create_vpc_endpoints = true# Creates Interface endpoints for: Bedrock, BedrockRuntime, S3, STS,# Cognito, AppSync, DynamoDB, SecretsManager, SSM, ECR, Logs