Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.jitera.ai/llms.txt

Use this file to discover all available pages before exploring further.

The fastest way to deploy Jitera Self-Hosted is to use the companion Terraform scripts, which automate the full workflow end-to-end: cloud infrastructure, managed databases, storage, email, DNS, Helm chart deployment, and CLI authentication.
The parameters and values shown in this guide are examples. Replace all placeholder values with your actual configuration.
This Quick Start deploys an evaluation environment using Terraform. For manual step-by-step deployment or production-grade customization, see the platform-specific guides: AWS EKS or Azure AKS.

What the scripts provision

AWS EKSAzure AKS
KubernetesEKS (managed node group)AKS (system + app node pools)
PostgreSQL 14 (Automation)RDSAzure Flexible Server
PostgreSQL 16 (PGVector)RDSAzure Flexible Server
MongoDB 5.0DocumentDBCosmos DB (serverless)
Redis 6ElastiCacheAzure Cache for Redis
RabbitMQAmazon MQIn-cluster (Bitnami)
StorageS3 (ap-northeast-1)Azure Blob Storage
EmailSESAzure Communication Services
DNSRoute 53Azure DNS
TLSACM (wildcard cert)cert-manager + Let’s Encrypt
Egress FirewallAWS Network Firewall (optional)Azure Firewall (optional)
Spot/PreemptibleConfigurable (use_spot_instances)Configurable (use_spot_instances)

Prerequisites

  • Terraform >= 1.5.0
  • Cloud CLI installed and authenticated (aws / az)
  • kubectl installed
  • Jitera Helm chart zip (provided by Jitera)
  • Jitera ACR credentials (provided by Jitera)
  • Azure subscription (for Azure OpenAI — required even for AWS-only deployments)

Azure OpenAI — create or reuse?

Jitera requires an Azure OpenAI instance with 6 model deployments. The Terraform scripts support two modes, controlled by a single variable:
Set in terraform.tfvars:
create_azure_openai         = true
azure_openai_resource_group = "my-openai-rg"           # will be created
azure_openai_account_name   = "my-openai"              # name for the new account
azure_openai_location       = "swedencentral"           # region that supports gpt-4.1
Terraform will create:
  • A new resource group
  • A new Azure OpenAI account (named by azure_openai_account_name)
  • 6 model deployments: gpt-4.1, gpt-4.1-mini, gpt-4.1-nano, gpt-4o, gpt-4o-mini, text-embedding-ada-002
  • Network ACL with the local NAT Gateway IP auto-included (deny all except allowed IPs)
Which should I choose?
  • Deploying AWS only — set create_azure_openai = true (AWS stack creates it)
  • Deploying Azure only — set create_azure_openai = true (Azure stack creates it)
  • Deploying both AWS and Azure — set true on whichever you deploy first, then false on the second stack pointing to the instance the first one created
  • Already provisioned OpenAI outside Terraform — set false and provide the existing account details
Both the AWS EKS and Azure AKS scripts have this same variable. It works identically in both. You only need one Azure OpenAI instance total, shared across all environments.

AWS EKS

Step 1: Prepare

cd aws-eks/
unzip jitera-helm-chart.zip -d ./jitera
cp terraform.tfvars.example terraform.tfvars

Step 2: Fill in terraform.tfvars

Required values:
VariableHow to get it
aws_regionYour target region (e.g., ap-northeast-1)
aws_profileYour AWS CLI profile name
azure_subscription_idaz account show --query id -o tsv
route53_zone_name / app_domain / chat_domainYour DNS zone and hostnames
ses_domain / sender_emailSES domain identity and sender address
registry_server / registry_username / registry_passwordProvided by Jitera
azure_openai_resource_groupResource group for OpenAI (created or looked up)
azure_openai_account_nameAccount name for OpenAI (created or looked up). Find existing: az cognitiveservices account list --query "[?kind=='OpenAI'].{name:name, rg:resourceGroup}" -o table
jwt_secretpwgen 64 1
db_password / pgvector_db_passwordpwgen 24 1 (each)
documentdb_passwordpwgen 24 1 (no /, ", or @)
redis_auth_tokenpwgen 32 1
rabbitmq_passwordpwgen 24 1
Optional values:
VariableDefaultDescription
create_azure_openaitrueCreate new OpenAI instance or use existing
use_spot_instancesfalseSpot (~70% cheaper) vs On-Demand
use_firewallfalseAWS Network Firewall for egress filtering (~$300/mo)
inbound_allow_cidrs[]CIDR list for Kong LB access restriction (empty = open)
extra_ca_cert_path""Path to additional CA cert (e.g., corporate TLS proxy)

Step 3: Deploy

terraform init
terraform plan    # review the plan
terraform apply   # ~30-40 minutes

Step 4: Configure kubectl

aws eks update-kubeconfig \
  --profile <your-aws-profile> \
  --region $(terraform output -raw aws_region) \
  --name $(terraform output -raw cluster_name)

Step 5: Verify

kubectl get pods -n jitera          # all Running
curl -I https://$(terraform output -raw app_url | sed 's|https://||')

Step 6: SES Production Access

New AWS accounts start in SES sandbox — emails can only be sent to verified addresses. For testing/pilot: verify individual recipients:
aws ses verify-email-identity \
  --profile <your-aws-profile> \
  --region $(terraform output -raw aws_region) \
  --email-address <recipient>
For production: request production access (approval typically takes ~24 hours):
aws sesv2 put-account-details \
  --profile <your-aws-profile> \
  --region $(terraform output -raw aws_region) \
  --production-access-enabled \
  --mail-type TRANSACTIONAL \
  --website-url "$(terraform output -raw app_url)" \
  --use-case-description "Jitera Self-Hosted platform emails"
See Amazon SES sandbox documentation for details.

Step 7: CLI Access (optional)

terraform output -raw cli_public_key > public_key.pem
jitera set PRIVATE_API_ENDPOINT=$(terraform output -raw app_url)/automation/private
jitera set STUDIO_URL=$(terraform output -raw app_url)
jitera set ENCRYPTED_PUBLIC_KEY="$(cat public_key.pem)"

Azure AKS

Step 1: Prepare

cd azure-aks/
unzip jitera-helm-chart.zip -d ./jitera
cp terraform.tfvars.example terraform.tfvars

Step 2: Fill in terraform.tfvars

Required values:
VariableHow to get it
azure_subscription_idaz account show --query id -o tsv
dns_zone_name / dns_zone_resource_groupYour existing Azure DNS zone and its resource group
app_domain / chat_domainFull FQDNs for the app and chat
letsencrypt_emailYour team email
registry_server / registry_username / registry_passwordProvided by Jitera
azure_openai_resource_groupResource group for OpenAI (created or looked up)
azure_openai_account_nameAccount name for OpenAI (created or looked up). Find existing: az cognitiveservices account list --query "[?kind=='OpenAI'].{name:name, rg:resourceGroup}" -o table
jwt_secretpwgen 64 1
db_password / pgvector_db_passwordpwgen 24 1 (each)
sender_emailSet after first apply — copy MailFrom from Azure Portal (see Step 7)
Optional values:
VariableDefaultDescription
create_azure_openaifalseCreate new OpenAI instance or use existing
use_spot_instancesfalseSpot (~70% cheaper) vs Regular VMs
use_firewallfalseAzure Firewall for egress filtering (~$900/mo)
inbound_allow_cidrs[]CIDR list for Kong LB access restriction (empty = open)
locationjapaneastAzure region (check PG Flexible Server availability)
extra_ca_cert_path""Path to additional CA cert (e.g., corporate TLS proxy)

Step 3: Login and Deploy

az login
az account set --subscription "<subscription-id>"
terraform init
terraform plan
terraform apply   # ~30-40 minutes

Step 4: Corporate Proxy (if applicable)

If behind a corporate TLS-intercepting proxy (e.g., Netskope, Zscaler), add the AKS API server FQDN to the SSL bypass list:
*.hcp.<region>.azmk8s.io

Step 5: Configure kubectl

az aks get-credentials \
  --resource-group $(terraform output -raw resource_group_name) \
  --name $(terraform output -raw cluster_name)

Step 6: Verify

kubectl get pods -n jitera          # all Running
curl -I https://$(terraform output -raw app_url | sed 's|https://||')

Step 7: Email Setup (manual Portal steps)

Azure Communication Services SMTP requires two manual steps after terraform apply:
  1. Navigate to Portal > Communication Services > <cluster>-comm > Email > Domains > Connect domain
  2. Select <cluster>-email > AzureManagedDomain > Connect
  3. Note the MailFrom address from the domain (e.g., DoNotReply@<random-uuid>.azurecomm.net)
  4. Update sender_email in terraform.tfvars to match the MailFrom address
  5. Re-apply: terraform apply -target=helm_release.jitera
Azure Communication Services is a global resource type. When deployed via Azure CLI, this requires --location global. The azurerm_communication_service Terraform resource hides this — the provider sets location = "global" internally, so there is no location field to configure. Only data_location (email data residency region, e.g. "United States", "Europe", "Asia Pacific") is user-configurable.
Azure CLITerraform (azurerm_communication_service)
Deployment region--location global (required)Hardcoded by provider — no field
Data residency--data-location "United States"data_location = "United States"

Step 8: CLI Access (optional)

terraform output -raw cli_public_key > public_key.pem
jitera set PRIVATE_API_ENDPOINT=https://<app_domain>/automation/private
jitera set STUDIO_URL=https://<app_domain>
jitera set ENCRYPTED_PUBLIC_KEY="$(cat public_key.pem)"

Configurable Options

FeatureVariableAWS DefaultAzure DefaultImpact
Azure OpenAIcreate_azure_openaitruefalseCreate new instance or reuse existing
OpenAI account nameazure_openai_account_name(required)(required)Used as resource name when creating AND lookup key when reusing
OpenAI subscriptionazure_openai_subscription_id""""Set only if OpenAI is in a different Azure subscription (same tenant)
OpenAI allowed IPsazure_openai_allowed_ips[][]Additional IPs for OpenAI access. Local NAT Gateway IP is auto-included.
Spot Instancesuse_spot_instancesfalsefalsetrue = ~70% cost savings, risk of eviction
Egress Firewalluse_firewallfalsefalseFQDN allowlist filtering, +$300-900/mo
Inbound Restrictioninbound_allow_cidrs[][]CIDR list for Kong LB access (empty = open)
Corporate Proxy CAextra_ca_cert_path""""Path to additional CA cert for TLS-intercepting proxies
Node countnode_min / node_max3 / 43 / 43 nodes = evaluation minimum (12 vCPU)
Helm release namehelm_release_namejiterajiteraPrefixes all K8s resource names
Namespacehelm_namespacejiterajiteraK8s namespace for all Jitera pods
GitHub Integrationgithub_app_name etc.emptyemptyOptional, see GitHub Integration

Azure OpenAI Network Access

When create_azure_openai = true, the OpenAI instance is created with network_acls.default_action = "Deny" (IP allowlist only). The local cluster’s NAT Gateway IP is automatically included — no manual configuration needed for the creating stack to access OpenAI. To grant access from other clusters or developers, add their IPs to azure_openai_allowed_ips:
# Example: AWS creates OpenAI, Azure AKS also needs access
azure_openai_allowed_ips = [
  "20.96.49.36",    # Azure AKS NAT Gateway IP (from Azure stack: terraform output nat_gateway_ip)
  "106.72.157.66"   # Developer laptop (optional, for testing)
]
The IPs are plain addresses without CIDR notation (Azure OpenAI ip_rules format).

Known Limitations

  1. S3 region must be ap-northeast-1 — The Jitera app hardcodes presigned URL region to Tokyo. S3 buckets are created in ap-northeast-1 regardless of the EKS region.
  2. CLI_ZIPPER_PRIVATE_KEY newlines — The Helm chart strips PEM newlines. Terraform patches the secret post-deploy via terraform_data.cli_zipper_patch and restarts Ultron automatically.
  3. Azure Email requires Portal steps — Domain linking and sender address setup cannot be automated via Terraform (see Step 7 above).
  4. Azure SLB + source ranges breaks hairpin — When inbound_allow_cidrs is set on Azure, the Standard LB’s source-range filter interacts incorrectly with DSR session tracking for same-VNet traffic. Terraform installs a CoreDNS rewrite (coredns_rewrite.tf) that resolves the public ingress domain to Kong’s ClusterIP from inside the cluster, bypassing the SLB for internal traffic. External clients are unaffected.
  5. Switching Spot / Regular — Destroys and recreates the node pool (~5-10 min downtime).
  6. Switching Firewall on/off — Requires cluster recreation on Azure (AKS outbound_type is immutable).
  7. Azure PG Flexible Server region restrictions — Some regions may restrict provisioning. Verify with: az postgres flexible-server list-skus --location <region>

Teardown

terraform destroy   # removes ALL resources — irreversible
terraform destroy deletes all infrastructure including databases and storage. This action cannot be undone. Back up any data before running this command.

AWS EKS Installation

Manual step-by-step AWS deployment guide

Azure AKS Installation

Manual step-by-step Azure deployment guide

CLI Configuration

Manual RSA key pair generation and CLI setup

Deployment Requirements

Cluster specs, credentials, and prerequisites