AWS Terraform Deployment
Deploy the full RoostGPT stack on AWS using Roost's Terraform scripts. Terraform provisions all infrastructure automatically — VPC, EC2, ALB, RDS, Route53, and supporting networking.
What Terraform Provisions
| Resource | Details |
|---|---|
| VPC | Public and private subnets with NAT gateway |
| EC2 Instances | Ubuntu compute instances with associated storage volumes |
| Application Load Balancer | With target groups |
| Supporting networking | Route tables, security groups, internet gateway |
1. Getting Started
Before running Terraform, prepare the following:
- MySQL or PostgreSQL database (or let Terraform provision RDS)
- SSL certificates and a DNS domain
- OAuth application — client ID, secret, and redirect URI (see OAuth Provider Setup below)
- IP CIDR range, AWS region, and preferred availability zones
- AWS user account with Admin privileges to run Terraform
Required Terraform variables to gather:
regionroute53_hosted_zone_idec2_ami— Ubuntu Jammy 22.04 AMI for your regionenterprise_dns— e.g.roostgpt.yourcompany.comip_block_vpc— VPC CIDR block- OAuth provider client ID (Okta, Google, or Azure ADFS)
- Company name
Download the Terraform Scripts
curl -LO https://github.com/roost-io/roost-support/raw/refs/heads/master/terraform-ec2.zip
unzip terraform-ec2.zip
cd terraform-ec2
2. OAuth Provider Setup
Roost supports the following authentication providers. Configure one before running Terraform.
Okta
- Sign in to your Okta account with admin privileges (developer.okta.com)
- Go to Applications → Applications
- Click Create App Integration → OIDC - OpenID Connect → Web Application → Next
- Fill in the App integration name and upload your logo
- Add Sign-in redirect URI:
https://<DNS_NAME>/login - Under Assignments → Controlled Access, select user groups or allow everyone
- Save — note the Client ID and Client Secret
- Go to Security → API and note the Issuer URI for the default Authorization Server:
https://<your_domain>.okta.com/oauth2/default
Google
- Go to console.cloud.google.com/apis/credentials
- Click Create Credentials → OAuth Client ID → Web Application
- Add Authorized JavaScript Origins:
https://<DNS_NAME> - Add Authorized Redirect URIs:
https://<DNS_NAME>/loginhttps://<DNS_NAME>/api/auth/redirect/google
- Download the JSON — note the Client ID and Client Secret
Microsoft Azure ADFS
Applies to Windows Server 2016/2019 with ADFS 4.0.
Register the application:
- Open Server Manager → Tools → AD FS Management
- Go to AD FS → Application Groups
- Click Add Application Group on the right panel
- Enter a name (e.g.
Roost) and select Server Application Web browser accessing a web API → Next - Note the Client Identifier — this is your
AZURE_ADFS_CLIENT_ID - Add Redirect URI:
https://<DNS_NAME>/login→ click Add → Next - Check Generate a shared secret and copy the secret — this is
AZURE_ADFS_CLIENT_SECRET→ Next - Enter the Web API Identifier: same URL as the redirect URI → Next
- On Access Control Policy, select Permit everyone → Next
- On Configure Application Permissions, select scope openid → Next → Finish
Configure claims:
- Open Properties for the application group you just created
- Select the Web application entry (Roost - Web API) and click Edit
- On the Issuance Transform Rules tab, click Add Rule
- Select Send LDAP Attributes as Claims → Next
- Name the rule
Roost Claimsand select Active Directory as the attribute store - Configure the following LDAP Attribute → Outgoing Claim Type mappings:
E-Mail-Addresses→ E-Mail AddressGiven-Name→ Given NameSurname→ SurnameSAM-Account-Name→ Windows Account NameUser-Principal-Name→ UPN
- Click Finish → OK to save
Environment variables from Azure ADFS setup:
| Variable | Value |
|---|---|
AZURE_ADFS_CLIENT_ISSUER | Domain of ADFS server (e.g. https://adfs.contoso.com) |
AZURE_ADFS_CLIENT_ID | Client Identifier of the server application |
AZURE_ADFS_CLIENT_SECRET | Client Secret (leave empty if using Native Application instead) |
3. Database Setup
Roost stores workflow state, connector information, and user/team data in a relational database. MySQL, PostgreSQL, and Amazon Aurora are all supported. Only one database is required.
Amazon Aurora (MySQL Compatible) or MySQL
- Open the AWS Console → RDS → Create Database
- Select Easy Create → Amazon Aurora with MySQL compatibility or MySQL
- Modify the Security Group to allow TCP port
3306from the Control Plane instance security group only - Note the writer instance endpoint, username, and password
- Create a dedicated Roost user — avoid using the admin login:
-- Connect
mysql -h <SQL_HOST_URL> -u <root|master|admin> -p
-- Create user and database
CREATE USER 'Roost'@'%' IDENTIFIED WITH mysql_native_password BY 'Roost#123';
CREATE DATABASE roostio;
GRANT ALL ON roostio.* TO 'Roost'@'%';
-- Apply the Roost schema, if provided by the Roost team
\. /var/tmp/Roost/db/roost.sql
Amazon Aurora (PostgreSQL Compatible) or PostgreSQL
- Open the AWS Console → RDS → Create Database
- Select Easy Create → Amazon Aurora with PostgreSQL compatibility or PostgreSQL
- Modify the Security Group to allow TCP port
5432from the Control Plane instance security group only - Note the writer instance endpoint, username, and password
- Create a dedicated Roost user:
-- Connect
psql "host=<PG_HOST_URL> user=<admin> dbname=postgres port=5432 sslmode=require"
-- Create database and user
CREATE DATABASE roostio;
CREATE USER roost WITH PASSWORD 'Roost#123';
GRANT ALL PRIVILEGES ON DATABASE roostio TO roost;
-- Connect to the new database and set schema privileges
\c roostio
GRANT USAGE ON SCHEMA public TO roost;
GRANT ALL ON ALL TABLES IN SCHEMA public TO roost;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO roost;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO roost;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE ON SEQUENCES TO roost;
-- Apply the Roost schema, if provided by the Roost team
\i /var/tmp/Roost/db/roost.sql
4. Terraform Variables
Copy the example file and fill in your values:
cp terraform.tfvars.original terraform.tfvars
Example terraform.tfvars:
enterprise_dns = "subdomain.domain.com"
admin_email = "comma,separated@emails.com"
enterprise_email_domain = "email-domain.com"
company = ""
license_key = ""
roost_jwt_token = "32-character-secure-long-secret"
roost_version = "v1.1.17"
az1_suffix = "b"
az2_suffix = "c"
certificate_arn = "arn:aws:acm:region:account:certificate/cert-id"
ec2_ami = "ami-023a307f3d27ea427"
region = "us-west-1"
ip_block_vpc = "172.32.255.192"
route53_hosted_zone_id = ""
key_pair = "roost-ssh"
azure_tenant_id = ""
azure_client_id = ""
azure_client_secret = ""
okta_client_id = "your-client-id"
okta_client_secret = "your-client-secret"
okta_issuer = "https://account.okta.com/oauth2/default"
is_own_mysql = false
db_type = "mysql"
mysql_db_name = "roostio"
mysql_host = "mysqldb_host_url"
mysql_password = "Roost#123"
mysql_port = 3306
mysql_root_password = "Admin#123"
mysql_username = "Roost"
Variable Reference
| Variable | Example | Description |
|---|---|---|
roost_version | v1.1.17 | RoostGPT version to deploy |
license_key | Roost license key | |
prefix | terraform-gpt | Resource name prefix |
region | us-west-1 | AWS region |
az1_suffix | b | First availability zone suffix |
az2_suffix | c | Second availability zone suffix |
deletion_protection | false | Enable RDS deletion protection |
route53_hosted_zone_id | Route 53 hosted zone ID | |
enterprise_dns | roostgpt.example.com | RoostGPT domain name |
enterprise_ssl_certificate_path | /var/tmp/Roost/certs/server.cer | Path to SSL certificate file |
enterprise_ssl_certificate_key_path | /var/tmp/Roost/certs/server.key | Path to SSL key file |
certificate_arn | ACM certificate ARN (leave empty to use file paths) | |
ec2_ami | ami-03df6dea56f8aa618 | Ubuntu Jammy 22.04 AMI ID for your region |
key_pair | roost-gpt-keypair | EC2 key pair name |
generate_key_pair | true | Auto-generate the key pair |
device_name | sdh | EBS device name |
ip_block_vpc | 172.32.255.192 | VPC CIDR block |
instance_type_controlplane | c5a.2xlarge | Control plane EC2 instance type |
instance_type_jumphost | t3.micro | Bastion/jumphost instance type |
disk_roostgpt | 150 | RoostGPT server disk size in GB |
disk_jumphost | 150 | Jumphost disk size in GB |
disk_controlplane | 150 | Control plane disk size in GB |
google_client_id | Google OAuth client ID | |
google_client_secret | Google OAuth client secret | |
github_client_id | GitHub OAuth client ID | |
github_client_secret | GitHub OAuth client secret | |
linkedin_client_id | LinkedIn OAuth client ID | |
linkedin_client_secret | LinkedIn OAuth client secret | |
azure_tenant_id | Azure AD tenant ID | |
azure_client_id | Azure ADFS client ID | |
azure_client_secret | Azure ADFS client secret | |
okta_client_id | Okta client ID | |
okta_client_secret | Okta client secret | |
okta_issuer | Okta authorization server issuer URL | |
roost_jwt_token | 32-character JWT signing secret | |
company | Company name | |
company_logo | https://roost.ai/hubfs/logos/Roost.ai-logo-gold.svg | Company logo URL |
enterprise_email_domain | example.com | Corporate email domain |
admin_email | admin@company.com | Admin email address |
admin_email_pass | Admin email password | |
senders_email | sender@company.com | Notification sender email |
senders_email_pass | Sender email password | |
email_smtp_host | SMTP host for email notifications | |
is_own_mysql | false | true = use existing external DB, false = provision RDS |
db_type | mysql | Database type: mysql or postgres |
mysql_host | mysqldb_host_url | MySQL/Aurora host endpoint |
mysql_password | MySQL user password | |
mysql_username | Roost | MySQL username |
mysql_port | 3306 | MySQL port |
mysql_db_name | roostio | MySQL database name |
mysql_root_password | MySQL root password |
5. Apply Terraform
terraform init
terraform plan
terraform apply
Confirm with yes when prompted. Provisioning typically takes 10–15 minutes.
Once complete, navigate to https://<enterprise_dns> to verify the stack is running.
Upgrading / Maintaining the Control Plane
Three options are available for refreshing or upgrading the RoostGPT stack.
Option A: Upgrade via Terraform (version change)
Update roost_version in terraform.tfvars:
roost_version = "v1.1.17"
Then run:
terraform apply
Option B: Refresh Control Plane via Terraform (no config change)
Force-replace the provisioning resources without changing configuration:
terraform apply \
--replace="null_resource.provision-controlplane-system" \
--replace="null_resource.provision-roostgpt-server" \
--replace="null_resource.run-controlplane-services"
Option C: Upgrade via SSH to Control Plane
The control plane runs a Docker Compose stack and can be updated directly:
- SSH into the infrastructure bastion instance as the
ubuntuuser - Run the following, replacing
v1.1.17with the target version:
ssh cp "ROOST_VER='v1.1.17' /var/tmp/Roost/bin/roost-enterprise.sh -c /var/tmp/Roost/config.json -i roostai"
Post-Deployment
After deployment:
- Configure webhooks for your Git repositories
- Add AI provider credentials in the web UI
- Add Git platform tokens in the web UI
- Run a test to verify end-to-end functionality
For further help, contact support@roost.ai.