Deploying LangFuse on Azure with Terraform

Infrastructure & Deployment
Azure
Terraform
Note

🛠️ How-to Guide - This guide walks you through deploying LangFuse on Azure using Terraform, including DNS configuration and initial validation.

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 show

Terraform 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 = "westeurope"
  
  # 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
}

# 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)
  }
}
Tip

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 plan

Deployment Process

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 tsv

2. 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 table

Step 2: Configure Parent Domain

For MoJ justice.gov.uk domains:

  1. DNS Repository: https://github.com/ministryofjustice/dns
  2. Follow the README instructions for making DNS changes
  3. 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 IP

What 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 langfuse

2. Test Access

# Test HTTP access (before SSL setup)
curl -I http://<YOUR_DOMAIN_URL>

# Expected: Should show Application Gateway response
Warning

SSL 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.

Next Steps

Your LangFuse infrastructure is now deployed! To make it production-ready:

  1. Configure SSL Certificates - Set up Let’s Encrypt for trusted SSL
  2. Set Up Email Notifications - Enable user invitations and notifications
  3. Deployment Troubleshooting - Common issues and solutions

Common Issues During Deployment

Permission Errors: Wait 30-60 seconds and retry

sleep 30
terraform apply -auto-approve

Key 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.