Skip to content

Deploy the voice service

Same shape as Call an LLM → Deploy and RAG → Deploy. The Terraform module composes the E1 baseline and the E2 call-an-llm module; the Helm chart extends the E2 chart's env-var block with STT/TTS keys. Voice does not need its own state store — Azure Speech + Polly are stateless per-call APIs; Transcribe uses S3 for the audio blob.

Official docs verified 2026-08-08

Layout

examples/voice/
  service/                        # composes E2 chat_native + chat_claude
    stt.py                        # provider-picking speech-to-text
    tts.py                        # provider-picking text-to-speech
    voice.py                      # transcribe → E2 chat → synthesize
    main.py                       # FastAPI /voice-turn + /voice-turn-claude
    Dockerfile                    # layers call-an-llm/service alongside voice/service
    requirements.txt
  chart/                          # extends the E2 chart with STT/TTS env
    Chart.yaml
    values.yaml
    templates/
      deployment.yaml
      service.yaml
      serviceaccount.yaml
  terraform/
    azure/     (module "baseline" + "call_an_llm" + azurerm_cognitive_account speech)
    gcp/       (module "baseline" + "call_an_llm" + google_project_service speech+tts)
    aws/       (module "baseline" + "call_an_llm" + audio S3 bucket + IAM polly/transcribe policy)

Terraform — compose, don't duplicate

module "baseline" {
  source  = "../../../foundations/azure"
  name    = var.name
  region  = var.region
  compute = var.compute
}

module "call_an_llm" {
  source                    = "../../../call-an-llm/terraform/azure"
  name                      = var.name
  region                    = var.region
  compute                   = var.compute
  azure_openai_base_url     = var.azure_openai_base_url
  azure_openai_deployment   = var.azure_openai_deployment
  foundry_claude_deployment = var.foundry_claude_deployment
}

# Azure AI Speech Cognitive account — one resource covers both STT + TTS.
resource "azurerm_cognitive_account" "speech" {
  name                = "${var.name}-speech"
  location            = var.region
  resource_group_name = module.baseline.resource_group_name
  kind                = "SpeechServices"
  sku_name            = "S0"
}
module "baseline" {
  source     = "../../../foundations/gcp"
  project_id = var.project_id
  name       = var.name
  region     = var.region
  compute    = var.compute
}

module "call_an_llm" {
  source     = "../../../call-an-llm/terraform/gcp"
  project_id = var.project_id
  name       = var.name
  region     = var.region
  compute    = var.compute
}

# Enable STT + TTS APIs on the project.
resource "google_project_service" "speech_to_text" {
  project = var.project_id
  service = "speech.googleapis.com"
}
resource "google_project_service" "text_to_speech" {
  project = var.project_id
  service = "texttospeech.googleapis.com"
}
module "baseline" {
  source  = "../../../foundations/aws"
  name    = var.name
  region  = var.region
  compute = var.compute
}

module "call_an_llm" {
  source                = "../../../call-an-llm/terraform/aws"
  name                  = var.name
  region                = var.region
  compute               = var.compute
  eks_oidc_provider_arn = var.eks_oidc_provider_arn
}

# Transcribe needs an S3 bucket for input audio + transcript output.
resource "aws_s3_bucket" "audio" {
  bucket        = "${var.name}-audio-${data.aws_caller_identity.current.account_id}"
  force_destroy = true
}

Helm — env-var extension

The E3 chart's env block is bigger; the voice chart re-uses the E2 shape and adds only:

  • Azure: SPEECH_KEY, SPEECH_ENDPOINT, AZURE_TTS_VOICE
  • GCP: GCP_TTS_VOICE (STT + TTS use ADC)
  • AWS: AWS_POLLY_VOICE, AWS_POLLY_ENGINE, CHIRON_AUDIO_BUCKET
helm upgrade --install voice ./examples/voice/chart \
  --set image.repository="…/voice" --set image.tag="v1" \
  --set env.CHIRON_PROVIDER="azure" \
  --set env.AZURE_TTS_VOICE="en-US-JennyNeural"

Verify (validate-only)

for p in azure gcp aws; do
  ( cd examples/voice/terraform/$p && terraform init -backend=false && terraform validate )
done

helm lint examples/voice/chart
helm template voice examples/voice/chart > /dev/null

python -m compileall examples/voice/service

Live voice needs real STT/TTS credentials; Phase 3 covers billed apply.