Skip to content

Running indx on AWS, Azure, and GCP

indx ships cloud defaults out of the box and can run the entire pipeline on your own hardware with nothing leaving the network. This guide covers the third path: running every slot on a single cloud vendor’s managed services, with credentials taken from each cloud’s standard environment and no configuration beyond a flag.

Three self-contained cloud profiles are available:

Terminal window
pip install "indx[aws]" # Textract → Bedrock → Titan → S3 Vectors
pip install "indx[azure]" # Document Intelligence → Azure OpenAI → AI Search
pip install "indx[gcp]" # Document AI → Gemini → gemini-embedding → BigQuery

After installing, a single flag selects the entire stack:

Terminal window
indx ./docs --out ./ai-ready.indx --aws
indx ./docs --out ./ai-ready.indx --azure
indx ./docs --out ./ai-ready.indx --gcp

The promise: one install + one flag = a fully managed, single-vendor knowledge-space build, with every backend still individually swappable. The --aws preset is a convenience, not a coupling: you can mix --parser textract --store qdrant freely, and the per-backend path (indx[cloud], indx[local]) is still the route for minimalists or mixed stacks.

Each preset fills every pipeline slot with that cloud’s managed service. VLM is off by default in every preset (opt in with --vlm bedrock, --vlm azure, or --vlm vertex). Any slot you set explicitly wins over the preset.

SlotAWS — indx[aws]Azure — indx[azure]GCP — indx[gcp]
Parsertextract — Amazon Textractdocintel — Azure AI Document Intelligencedocai — Google Document AI
LLMbedrock — Bedrock Converseazure — Azure OpenAIvertex — Vertex AI Gemini
VLMbedrock — Bedrock Converse (image)azure — Azure OpenAI visionvertex — Gemini multimodal
Embedderbedrock — Titan v2 / Cohereazure — Azure OpenAI embeddingsvertex — gemini-embedding-001
Store (default)s3vectors — Amazon S3 Vectorsazure-search — Azure AI Searchbigquery — BigQuery vector search
Store (opt-in)opensearch — OpenSearch Serverlessvertex-vector — Vertex Vector Search
SDK footprintboto3openai, azure-ai-documentintelligence, azure-search-documents, azure-identitygoogle-genai, google-cloud-documentai, google-cloud-bigquery

The default stores are chosen for zero-infrastructure friction: S3 Vectors and BigQuery are serverless APIs that need no endpoint deployment. See Choosing a Vector Store for the latency trade-offs and the opt-in OpenSearch and Vertex Vector Search stores.

Terminal window
pip install "indx[aws]"

The entire default AWS stack — Textract, Bedrock, Titan, and S3 Vectors — is covered by a single dependency: boto3. The opt-in OpenSearch Serverless store adds opensearch-py:

Terminal window
pip install "indx[aws-opensearch]" # includes indx[aws] + opensearch-py
Terminal window
indx ./docs --out ./ai-ready.indx --aws

To override a single slot:

Terminal window
# Use Textract + Bedrock, but store in Qdrant instead of S3 Vectors
indx ./docs --out ./ai-ready.indx --aws --store qdrant

AWS credentials are discovered automatically by boto3’s standard chain. Adapters never read or log keys directly — they pass only region and, optionally, profile to boto3.Session.

VariablePurpose
AWS_REGION or AWS_DEFAULT_REGIONRegion for all service clients (required)
AWS_ACCESS_KEY_IDStatic credentials (optional — roles / SSO preferred)
AWS_SECRET_ACCESS_KEYStatic credentials
AWS_SESSION_TOKENTemporary credentials
AWS_PROFILENamed profile in ~/.aws/credentials

In production, prefer an IAM role attached to your compute (EC2 instance profile, ECS task role, Lambda execution role, or EKS IRSA) over static keys. boto3 discovers instance metadata credentials automatically with no environment variables needed.

The minimum IAM permissions for the default stack are:

  • textract:DetectDocumentText (parser)
  • bedrock-runtime:Converse, bedrock-runtime:InvokeModel (LLM, embedder)
  • s3vectors:PutVectors, s3vectors:QueryVectors, s3vectors:DeleteVectors, s3vectors:CreateVectorIndex (store)

Non-secret knobs only. Credentials come from the boto3 chain, never from config.

[parser]
engine = "textract"
[parser.textract]
region = "us-east-1"
# features = ["TABLES", "FORMS"] # enable Analyze Document (off by default)
[enrich]
llm = "bedrock:us.anthropic.claude-sonnet-4-6"
[embed]
model = "bedrock:amazon.titan-embed-text-v2:0"
[embed.bedrock]
dimensions = 1024 # also accepts 512 or 256
[store]
backend = "s3vectors"
[store.s3vectors]
bucket = "indx-vectors"
index = "handbook"
region = "us-east-1"

Terminal window
pip install "indx[azure]"

The Azure extra installs the full SDK set: openai, azure-ai-documentintelligence, azure-search-documents, azure-identity, and azure-core. If you previously installed indx[azure] for the LLM alone, re-installing picks up the new dependencies additively.

Terminal window
indx ./docs --out ./ai-ready.indx --azure

Azure adapters support two credential modes, selected automatically per service. If the service’s API key environment variable is set, it is used. If not, DefaultAzureCredential is attempted (managed identity, az login, workload identity). Keys stay in environment variables and are never written to indx.toml.

VariableServicePurpose
AZURE_OPENAI_API_KEYAzure OpenAILLM, VLM, embedder API key
AZURE_OPENAI_ENDPOINTAzure OpenAIService endpoint URL
AZURE_OPENAI_DEPLOYMENTAzure OpenAILLM chat deployment name
AZURE_OPENAI_EMBED_DEPLOYMENTAzure OpenAIEmbedder deployment name
AZURE_OPENAI_VLM_DEPLOYMENTAzure OpenAIVLM deployment name
AZURE_OPENAI_API_VERSIONAzure OpenAIAPI version (default: 2024-10-21)
AZURE_DOCUMENTINTELLIGENCE_ENDPOINTDocument IntelligenceService endpoint URL
AZURE_DOCUMENTINTELLIGENCE_KEYDocument IntelligenceAPI key
AZURE_SEARCH_SERVICE_ENDPOINTAI SearchService endpoint URL
AZURE_SEARCH_API_KEYAI SearchAdmin key (for index create/upload)
AZURE_SEARCH_INDEX_NAMEAI SearchIndex to write to / query

When no key variable is set, the adapter falls back to DefaultAzureCredential, which works automatically in Azure-hosted compute (App Service, AKS, Container Apps) and via az login on a developer machine. No azure-identity configuration is needed beyond having the package installed (it is included in indx[azure]).

[parser]
engine = "docintel"
[parser.docintel]
model_id = "prebuilt-read" # or "prebuilt-layout" for tables/structure
[enrich]
llm = "azure"
[embed]
model = "azure"
[store]
backend = "azure-search"
[store.azure-search]
index_name = "handbook"

Terminal window
pip install "indx[gcp]"

The GCP extra installs google-genai (for all three model slots: LLM, VLM, embedder), google-cloud-documentai (parser), and google-cloud-bigquery (default store). The heavier google-cloud-aiplatform package is pulled only by the opt-in Vertex Vector Search store:

Terminal window
pip install "indx[gcp-vectorsearch]" # includes indx[gcp] + google-cloud-aiplatform
Terminal window
indx ./docs --out ./ai-ready.indx --gcp

GCP uses Application Default Credentials (ADC) for every service. Adapters never handle keys directly.

VariablePurpose
GOOGLE_APPLICATION_CREDENTIALSPath to a service account JSON key file
GOOGLE_CLOUD_PROJECTGCP project ID
GOOGLE_CLOUD_LOCATIONRegion / multi-region (e.g. us-central1, us)
GOOGLE_GENAI_USE_VERTEXAISet to true to use Vertex AI (required for production)

On GCE, Cloud Run, GKE, or Cloud Functions, the attached service account is discovered automatically with no environment variables needed. On a developer machine, run gcloud auth application-default login once. In CI, export GOOGLE_APPLICATION_CREDENTIALS pointing at a service account key file.

[parser]
engine = "docai"
[parser.docai]
project = "my-proj"
location = "us" # "us" or "eu" — multi-region bucket, not a zone
processor_id = "abc123def456"
[enrich]
llm = "vertex:gemini-2.5-flash"
[embed]
model = "vertex:gemini-embedding-001"
[embed.vertex]
output_dimensionality = 768 # native default is 3072; 768 for cost/compat
task_type = "RETRIEVAL_DOCUMENT"
[store]
backend = "bigquery"
[store.bigquery]
project = "my-proj"
dataset = "indx"
table = "handbook"

The cloud presets fill only the slots you did not set explicitly. Any slot you override wins:

Terminal window
# AWS parser + embedder, but keep your existing Qdrant store
indx ./docs --out ./ai-ready.indx --aws --store qdrant
# Azure OpenAI LLM only, with Docling parser and bge-m3 embedder
indx ./docs --out ./ai-ready.indx --llm azure --parser docling --embedder bge-m3

The same mixing works in indx.toml. See Configuring indx for the full resolution order.

Every run writes its resolved slot names into the .indx manifest:

// manifest.json (illustrative — AWS run)
{
"indx_version": "1.0",
"tool_version": "indx 0.5.0",
"slots": {
"parser": "textract",
"llm": "bedrock:us.anthropic.claude-sonnet-4-6",
"vlm": "none",
"embedder": "bedrock:amazon.titan-embed-text-v2:0",
"store": "s3vectors",
"output": "indx"
},
"embedder": { "name": "bedrock:amazon.titan-embed-text-v2:0", "dim": 1024 }
}

Use indx inspect ./ai-ready.indx to view the manifest and confirm which backends were active.