Work

Modernizing and Deploying an Agentic Data Application on Azure

Modernized and deployed Microsoft's agentic enterprise-data accelerator using FastAPI, Terraform, Managed Identity, Azure Container Apps, and Azure SQL.

Deployed · Live

Cloud Deployment · Infrastructure · Modernization · Troubleshooting

View Live Project ↗

Attribution: This project is based on Microsoft’s Agentic Applications for Unified Data Foundation solution accelerator; my work focused on modernization, Terraform infrastructure management, Azure deployment, troubleshooting, integration changes and end-to-end validation.

What was built
Modernized and deployed Microsoft’s agentic enterprise-data accelerator on Azure
Role
Cloud Deployment · Infrastructure · Modernization · Troubleshooting
Status
Deployed · Live
Key technologies
Microsoft Foundry · Azure Container Apps · Terraform · Python · Azure SQL

Problem

The starting point was Microsoft’s “Agentic Applications for Unified Data Foundation” solution accelerator — a reference implementation for building AI-powered data query agents on Azure. The accelerator provides a React frontend, a Python FastAPI backend, a Microsoft Foundry-hosted agent, and a SQL Query Tool that translates natural-language questions into T-SQL queries against a structured database.

The prescribed deployment target was an Azure App Service B1 plan. When I attempted to provision it, the deployment failed immediately: the Azure subscription had zero App Service VM quota in the East US region. The error was unambiguous — no App Service SKU could be deployed there. Following the accelerator’s instructions verbatim was not possible.

Solution

Rather than wait for a quota increase, I pivoted the hosting architecture to Azure Container Apps Consumption plan. The Consumption tier provisions compute on-demand per request and does not consume pre-allocated VM quota — a direct solution to the quota constraint without changing the application code.

I introduced Terraform as the infrastructure owner for the entire Azure stack: Container Apps environment, Azure Container Registry (ACR), user-assigned Managed Identity, Log Analytics workspace, and all RBAC role assignments. Both the React frontend (containerized with nginx) and the Python FastAPI backend were built as container images, pushed to ACR, and deployed as Container Apps.

Azure SQL with AdventureWorksLT sample data was retained as the active structured-data backend. Azure Cosmos DB was used for conversation persistence. All service authentication used the user-assigned Managed Identity — no connection strings or embedded credentials.

My Contribution

Microsoft provided

  • Microsoft Foundry project and agent runtime
  • FoundryAgent (“first-agent”) definition and tool registration
  • SQL Query Tool agent implementation
  • Chat orchestration layer
  • React frontend application (base)
  • Original accelerator architecture and configuration

My engineering work

Application
  • FastAPI backend modernization and customization
  • Runtime integration changes
Infrastructure
  • Terraform brownfield infrastructure configuration
  • Azure Container Apps environment and ACR setup
  • Container image build pipeline for frontend and backend
  • Deployment automation scripting
Security & Data
  • User-assigned Managed Identity configuration and RBAC assignments
  • Azure SQL networking, firewall rules, and Entra authorization
  • Cosmos DB networking configuration and data-plane permissions
Engineering & Validation
  • App Service quota investigation and architectural pivot
  • Identity and credential resolution troubleshooting
  • Networking and firewall troubleshooting
  • SQL authorization and schema troubleshooting
  • End-to-end system validation

Key Architectural Decision

Original Approach

Azure App Service B1 plan per the accelerator’s prescribed deployment instructions.

Constraint

East US App Service VM quota: 0 cores. No App Service SKU could be deployed — the error was explicit and immediate.

Investigation

Confirmed quota limit via Azure portal and CLI. A quota increase request could take days or weeks with no guarantee of approval on a learning subscription.

Decision

Pivot to Azure Container Apps Consumption plan — no pre-allocated VM quota; compute provisions on-demand per request. This bypasses the App Service quota constraint entirely.

Outcome

Full stack deployed successfully. Terraform manages the Container Apps environment, ACR, Managed Identity, Log Analytics, and all RBAC assignments — an infrastructure pattern not present in the original accelerator.

Architecture

The diagram below shows the verified final deployment. Simplified view is shown by default — toggle to see the full infrastructure layer.

Architecture diagram: Agentic data application on AzurePrimary Request Path — click a node for detailsUserBrowserReact / nginxFrontend · Container AppPython FastAPIBackend · Container AppFoundryAgent(first-agent · Microsoft Foundry)SQL Query ToolMicrosoft-providedCosmos DBConversation historyAzure SQLAdventureWorksLTJoel-configuredMicrosoft-providedResponse path
Text description of the architecture

User sends a message to the React/nginx frontend deployed on Azure Container Apps. The frontend forwards it to the Python FastAPI backend (also on Container Apps). FastAPI persists the conversation to Cosmos DB and routes the chat request to the Chat Orchestrator, which dispatches it to the FoundryAgent (“first-agent”) running in Microsoft Foundry. The FoundryAgent invokes the SQL Query Tool, which generates and executes a T-SQL query against the Azure SQL database (AdventureWorksLT). Query results flow back to the FoundryAgent, which streams a natural-language response back through FastAPI to the frontend and user. Infrastructure is managed by Terraform. A user-assigned Managed Identity provides credential-less access to Cosmos DB, ACR, and other Azure services. Microsoft Fabric was an alternative accelerator data path but was not active in the final deployment (USE_DATA_AGENT=false).

How It Works

The following steps trace a single natural-language question through the full stack.

  1. User asks — Types a question (e.g., “Which products had the highest sales last quarter?”) into the React frontend.
  2. Frontend sends — Forwards the message to the Python FastAPI backend via HTTP.
  3. FastAPI persists and routes — Saves the user message to Cosmos DB, then forwards the chat request to the Chat Orchestrator.
  4. Orchestrator dispatches — Routes the request to the FoundryAgent (“first-agent”) running in the Microsoft Foundry project.
  5. Agent decides — FoundryAgent determines the question requires a database lookup and invokes the SQL Query Tool.
  6. SQL Query Tool executes — Generates a T-SQL query from the natural-language question and runs it against Azure SQL (AdventureWorksLT).
  7. SQL returns results — Query results flow back to the SQL Query Tool, then to FoundryAgent.
  8. Agent composes response — FoundryAgent builds a natural-language answer from the query results.
  9. Streaming back — Response travels back through FastAPI to the React frontend.
  10. User reads the answer — Streamed in real time in the chat interface.

Cosmos DB is written on a parallel path at step 3 — FastAPI persists both the user message and the agent response to maintain full conversation history across sessions.

Data Model

The project queries the AdventureWorksLT sample database — Microsoft’s standard SQL schema for e-commerce scenarios. The diagram below shows all 10 entities and 12 verified foreign-key relationships.

AdventureWorksLT entity-relationship diagram — 10 entities, 12 foreign-key relationshipsCustomersSalesProduct CatalogSalesLT.CustomerCustomerID (PK)FirstName, LastNameEmailAddressSalesLT.SalesOrderHeaderSalesOrderID (PK)CustomerID (FK)ShipToAddressID, BillToAddressID (FK)OrderDate, TotalDue, StatusSalesLT.SalesOrderDetailSalesOrderDetailID (PK)SalesOrderID (FK)ProductID (FK)OrderQty, LineTotalSalesLT.ProductProductID (PK)ProductModelID (FK)ProductCategoryID (FK)Name, ListPriceSellStartDateSalesLT.ProductCategoryProductCategoryID (PK)ParentCategoryID (FK → self)NameSalesLT.ProductModelProductModelID (PK)NameSalesLT.ProductDescriptionProductDescriptionID (PK)DescriptionSalesLT.ProductModelProductDescription[junction table]ProductModelID (PK+FK)ProductDescriptionID (PK+FK)Culture (PK, language code)SalesLT.CustomerAddressCustomerID (PK+FK)AddressID (PK+FK)AddressTypeSalesLT.AddressAddressID (PK)AddressLine1City, StateProvinceCountryRegionPostalCode1:N1:NN:11:NN:1N:1N:1selfN:1N:1

All 10 AdventureWorksLT entities with 12 verified foreign-key relationships. Dashed border = junction table.

Technical Challenge

Original Approach: Deploy the application to an Azure App Service B1 plan per the accelerator’s prescribed instructions.

Constraint: The Azure subscription had zero App Service VM quota in the East US region. The error was explicit — quota exhausted at 0 cores, making any App Service SKU deployment impossible.

Investigation: Confirmed the quota limit through the Azure portal and CLI. A quota increase request could take days or weeks with no guarantee of approval on a learning subscription.

Decision: Pivot the entire hosting architecture to Azure Container Apps Consumption plan. The Consumption tier has no pre-allocated VM quota; it provisions compute on-demand per request. This bypasses the App Service quota constraint entirely without requiring any quota approval process.

Implementation: Terraform remained the infrastructure owner through the migration. I introduced a Terraform configuration to manage the Container Apps environment, ACR, Managed Identity, and all associated RBAC assignments — giving the deployment a reproducible, auditable infrastructure state from the start.

Outcome: The pivot was successful. Both frontend and backend containers were built, pushed to ACR, and deployed to Container Apps. The full accelerator stack became operational under a Terraform-managed architecture not present in the original accelerator design.

Troubleshooting

Beyond the primary architectural pivot, several specific issues required investigation and resolution:

ProblemContainer Apps deployment failed with resource provider not found errors.
Root CauseMicrosoft.App and related Azure resource providers were not registered in the subscription.
FixRan az provider register commands for the required providers before proceeding with Container Apps deployment.
ProblemFastAPI backend authentication failures when accessing Azure services from inside the container.
Root CauseDefaultAzureCredential attempted local credential sources before the Managed Identity, failing inside the container environment.
FixConfigured the Managed Identity client ID as an explicit environment variable in the Container Apps configuration to force the correct credential chain.
ProblemFastAPI could not connect to Cosmos DB from the Container Apps environment.
Root CausePublic network access to Cosmos DB was restricted by default configuration.
FixEnabled access from Azure services and added Container Apps outbound IP addresses to the Cosmos DB account firewall settings.
ProblemAzure SQL blocked outbound traffic from Container Apps.
Root CauseAzure SQL firewall did not include the Container Apps outbound IP ranges.
FixAdded the correct IP ranges to the SQL server firewall and enabled “Allow Azure services” access.
ProblemApplication could not authenticate to Azure SQL using Managed Identity.
Root CauseThe application used Entra (Azure AD) authentication. No contained database user existed for the Managed Identity.
FixCreated a contained database user mapped to the Managed Identity and granted db_datareader and db_datawriter roles.
ProblemSQL Query Tool behaved unexpectedly on certain table queries.
Root CauseAdventureWorksLT includes temporal history tables that the SQL Query Tool targeted incorrectly.
FixAdjusted query scope to target the primary tables directly, bypassing the history tables.
ProblemContainer Apps revisions failed to start or crashed on launch.
Root CauseSeveral environment variables required by the FastAPI backend were not correctly propagated to the Container Apps revision.
FixInspected Container Apps logs in Log Analytics and iteratively updated the Terraform environment variable configuration until all required variables were correctly set.

Validation Results

11/11 validation scenarios passed.

ValidationResult
Backend warm health check✅ PASS
Backend cold-start response✅ PASS
Frontend availability✅ PASS
Runtime configuration✅ PASS
Cosmos DB connectivity✅ PASS
Azure SQL connectivity✅ PASS
E2E AI chat and streaming✅ PASS
Conversation persistence✅ PASS
Terraform state (plan exit 0)✅ PASS
No committed secrets✅ PASS
Repeatable deployment✅ PASS

Production Considerations

What I would add for a production deployment:

  • CI/CD pipeline with automated container builds and deployments
  • Application Insights or distributed tracing for request visibility
  • Private networking and VNet integration for all services
  • Production load testing and cold-start latency benchmarking
  • Full resilience and failure-mode testing
  • Automated SQL schema lifecycle management
  • Key Vault integration for secrets management
  • Enterprise-grade governance and compliance controls

The following articles are planned based on this deployment experience:

  • Terraform brownfield infrastructure management on Azure — Managing existing Azure resources with Terraform without destroying and recreating them; handling state imports and drift.
  • Troubleshooting Azure Container Apps: identity, networking, and SQL authorization — A practical guide to the specific failure modes encountered: Managed Identity credential chains, Cosmos DB firewall rules, SQL Entra authorization, and environment variable propagation.
  • Deploying agentic applications with Microsoft Foundry — Setting up a Microsoft Foundry project, registering a FoundryAgent, and connecting it to custom tools via the FastAPI backend.
  • AdventureWorksLT as an AI agent data source — Using the AdventureWorksLT schema for natural-language data queries: entity structure, common query patterns, and temporal table considerations.