Deploying LangFuse on Azure with Terraform
Deploying LangFuse on Azure with Terraform
Problem: You need to deploy a self-hosted LangFuse instance on Azure infrastructure for your organization’s AI observability needs.
Solution: Use the official LangFuse Terraform module to deploy a production-ready LangFuse instance on Azure Kubernetes Service (AKS) with Application Gateway, PostgreSQL, and proper DNS configuration.
Prerequisites
Before starting, ensure you have:
Required Tools
- Azure CLI installed and configured
- Terraform installed (version 1.0+)
- kubectl for Kubernetes management
Azure Requirements
- Valid Azure subscription with appropriate permissions
- Domain name you want to use for LangFuse (e.g.,
<YOUR_DOMAIN_URL>)
Required Azure Permissions
- Contributor role on the subscription or resource group
- User Access Administrator (for role assignments)
- Key Vault Contributor (for Key Vault operations)
Pre-Deployment Setup
1. Azure Authentication
# Login to Azure
az login
# Set your subscription
az account set --subscription "your-subscription-id"
# Verify current subscription
az account showTerraform Configuration
1. Create Your Main Configuration
Create a main.tf file with your deployment configuration:
main.tf
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
subscription_id = "your-subscription-id"
}
module "langfuse" {
source = "github.com/langfuse/langfuse-terraform-azure?ref=0.1.2"
# REQUIRED: Domain configuration
domain = "<YOUR_DOMAIN_URL>" # Your domain
name = "<INSERT_SHORT_NAME>" # Short name for your deployment
location = "uksouth"
# OPTIONAL: Network configuration
virtual_network_address_prefix = "10.224.0.0/12"
aks_subnet_address_prefix = "10.224.0.0/16"
app_gateway_subnet_address_prefix = "10.225.0.0/16"
# OPTIONAL: Kubernetes configuration
kubernetes_version = "1.32"
node_pool_vm_size = "Standard_D8s_v6"
node_pool_min_count = 2
node_pool_max_count = 10
# OPTIONAL: Database configuration
postgres_instance_count = 2
postgres_ha_mode = "SameZone"
postgres_sku_name = "GP_Standard_D2s_v3"
# OPTIONAL: Security features
use_ddos_protection = true # review this as can be costly
}
# Provider configurations for Kubernetes and Helm
provider "kubernetes" {
host = module.langfuse.cluster_host
client_certificate = base64decode(module.langfuse.cluster_client_certificate)
client_key = base64decode(module.langfuse.cluster_client_key)
cluster_ca_certificate = base64decode(module.langfuse.cluster_ca_certificate)
}
provider "helm" {
kubernetes = {
host = module.langfuse.cluster_host
client_certificate = base64decode(module.langfuse.cluster_client_certificate)
client_key = base64decode(module.langfuse.cluster_client_key)
cluster_ca_certificate = base64decode(module.langfuse.cluster_ca_certificate)
}
}Version Check: Always use the latest stable version from LangFuse Terraform releases.
2. Initialize and Validate
# Initialize Terraform
terraform init
# Validate configuration
terraform validate
# Check the deployment plan
terraform planDeployment Process
Option A: Single Deployment (Recommended for Simple Cases)
terraform apply -auto-approveOption B: Phased Deployment (Recommended for Complex Deployments)
For large deployments or when you encounter permission issues:
# Phase 1: Core infrastructure
terraform apply -target="module.langfuse.azurerm_resource_group.this" -auto-approve
terraform apply -target="module.langfuse.azurerm_virtual_network.this" -auto-approve
# Phase 2: Security resources
terraform apply -target="module.langfuse.azurerm_key_vault.this" -auto-approve
terraform apply -target="module.langfuse.azurerm_key_vault_access_policy.this" -auto-approve
# Wait for Azure propagation
sleep 60
# Phase 3: Application resources
terraform apply -auto-approvePermission Propagation: If you encounter permission errors, wait 30-60 seconds and retry. Azure permissions take time to propagate.
DNS Configuration
1. Get Your Deployment IP Address
# List all public IPs in your resource group
az network public-ip list --resource-group <YOUR_RESOURCE_GROUP> --output table
# Get the specific Application Gateway IP
az network public-ip show --resource-group <YOUR_RESOURCE_GROUP> --name <YOUR_DEPLOYMENT_NAME>-appgw --query "ipAddress" -o tsv2. DNS Delegation Setup
Your deployment creates an Azure DNS zone that requires proper delegation from your parent domain.
Why NS Records Are Required:
- SSL Certificate Validation: Let’s Encrypt uses DNS-01 challenges requiring TXT record creation
- Automatic Certificate Renewal: cert-manager needs DNS authority to manage records
- Full DNS Control: Azure DNS needs authority over the entire subdomain
3. Configure DNS Delegation
Step 1: Get Azure DNS Nameservers
az network dns zone show --resource-group <YOUR_RESOURCE_GROUP> --name <YOUR_DOMAIN_URL> --query "nameServers" -o tableStep 2: Configure Parent Domain
For MoJ justice.gov.uk domains:
- DNS Repository: https://github.com/ministryofjustice/dns
- Follow the README instructions for making DNS changes
- Open a Pull Request with your NS records:
<YOUR SUBDOMAIN>:
ttl: 3600
type: NS
value:
- ns1-xx.azure-dns.com.
- ns2-xx.azure-dns.net.
- ns3-xx.azure-dns.org.
- ns4-xx.azure-dns.info.For other domains: Add NS records in your domain management system:
<YOUR_SUBDOMAIN>.<YOUR_DOMAIN>.com. IN NS ns1-xx.azure-dns.com.
<YOUR_SUBDOMAIN>.<YOUR_DOMAIN>.com. IN NS ns2-xx.azure-dns.net.
<YOUR_SUBDOMAIN>.<YOUR_DOMAIN>.com. IN NS ns3-xx.azure-dns.org.
<YOUR_SUBDOMAIN>.<YOUR_DOMAIN>.com. IN NS ns4-xx.azure-dns.info.
Example:
langfuse-ai:
ttl: 3600
type: NS
value:
- ns1-06.azure-dns.com.
- ns2-06.azure-dns.net.
- ns3-06.azure-dns.org.
- ns4-06.azure-dns.info.
Note that the DNS repo has certain standards for domain names that you will need to comply with. You will also need to ensure that the records and record attributes are in strict alphabetical order. Failing to do this will likely result in your PR being closed by the cloud operations team.
4. Test DNS Delegation
# Test NS delegation is working
nslookup -type=NS <YOUR_DOMAIN_URL>
# Test DNS propagation (may take 5-30 minutes)
nslookup <YOUR_DOMAIN_URL>
# Should show the Azure Application Gateway IPWhat Happens After NS Delegation:
- ✅ A record created automatically by Terraform in Azure DNS
- ✅ Automatic certificate renewal forever
- ✅ Full DNS control for any future DNS records
Initial Validation
1. Verify Kubernetes Deployment
# Get AKS credentials
az aks get-credentials --resource-group <YOUR_RESOURCE_GROUP> --name aks-<YOUR_DEPLOYMENT_NAME> --overwrite-existing
# Check LangFuse pods
kubectl get pods -n langfuse
# Check services
kubectl get services -n langfuse
# Check ingress
kubectl get ingress -n langfuse2. Test Access
# Test HTTP access (before SSL setup)
curl -I http://<YOUR_DOMAIN_URL>
# Expected: Should show Application Gateway responseSSL Required: The deployment creates self-signed certificates by default. You’ll need to configure proper SSL certificates before production use. See the SSL Configuration Guide for next steps.
Post-Deployment Configuration
SSO (Single Sign-On) Configuration
Configure Azure AD SSO for your LangFuse deployment to enforce organizational authentication policies:
# Configure SSO environment variables
kubectl set env deployment/langfuse-web -n langfuse \
SSO_DOMAIN_ENFORCEMENT=justice.gov.uk \
DISABLE_USERNAME_PASSWORD=trueConfiguration Options:
| Variable | Purpose | Default | Recommended |
|---|---|---|---|
SSO_DOMAIN_ENFORCEMENT |
Restricts user registration to specific domain | justice.gov.uk |
Set to your organization’s domain |
DISABLE_USERNAME_PASSWORD |
Disables password-based authentication | true |
true for production environments |
Important Notes:
- Domain Enforcement: Only users with email addresses from the specified domain can register or be invited
- Password Disable: When
true, users can only authenticate via Azure AD SSO, not username/password - Existing Users: Users with existing password-based accounts may need migration (see User Management Guide)
Verify SSO Configuration:
# Check environment variables are set
kubectl exec -n langfuse deployment/langfuse-web -- printenv | grep -E "(SSO_DOMAIN|DISABLE_USERNAME)"
# Restart deployment to ensure changes take effect
kubectl rollout restart deployment/langfuse-web -n langfuse
kubectl rollout status deployment/langfuse-web -n langfuse --timeout=120sSSO Migration: If you have existing password-based users, see the User Management Guide for migration procedures to avoid authentication conflicts.
Next Steps
Your LangFuse infrastructure is now deployed! To make it production-ready:
- Configure SSL Certificates - Set up Let’s Encrypt for trusted SSL
- Set Up Email Notifications - Enable user invitations and notifications
- Deployment Troubleshooting - Common issues and solutions
Common Issues During Deployment
Permission Errors: Wait 30-60 seconds and retry
sleep 30
terraform apply -auto-approveKey Vault Naming Conflicts: Use shorter names or different domains
DNS Propagation: Allow 5-30 minutes for DNS changes to propagate globally
🚀 You now have LangFuse deployed on Azure! Continue with SSL configuration to make it production-ready.