Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ace419b
feat: Add local dev setup and deploy-to-Azure automation scripts
Abdul-Microsoft May 6, 2026
46ab935
Enhance Azure deployment script with improved error handling, role as…
Abdul-Microsoft May 8, 2026
7915908
Add automated local development setup documentation with scripts for …
Abdul-Microsoft May 8, 2026
4536355
Clean up .gitignore by removing unnecessary entries
Abdul-Microsoft May 8, 2026
978ec27
Remove .gitignore from PR changes
Abdul-Microsoft May 8, 2026
8ba3e0e
fix: Address Copilot PR review feedback
Abdul-Microsoft May 11, 2026
11befc2
fix: Make RBAC role assignment always run, remove --assign-rbac flag
Abdul-Microsoft May 11, 2026
862a064
refactor: Move automation scripts to scripts/ folder
Abdul-Microsoft May 11, 2026
3d0dd43
docs: Update script paths to scripts/ folder in documentation
Abdul-Microsoft May 11, 2026
43560f3
refactor: Move automation scripts to infra/scripts/
Abdul-Microsoft May 11, 2026
15a180e
fix: Resolve repo root path correctly from infra/scripts/ location
Abdul-Microsoft May 11, 2026
fe60b9d
fix: Correctly resolve repo root path in setup_local_dev.ps1 script
Abdul-Microsoft May 11, 2026
e5dc378
refactor: Update setup instructions and improve service startup guida…
Abdul-Microsoft May 20, 2026
233ebad
roll back commands fix
Rafi-Microsoft May 22, 2026
0b561fa
removed mount from dockerfiles
Rafi-Microsoft May 22, 2026
12c3c8f
docker image time optimization v1
Rafi-Microsoft May 22, 2026
7235e80
added fallback logic
Rafi-Microsoft May 27, 2026
b56bb21
Merge branch 'feature/local_automation_enhancements' of https://githu…
Rafi-Microsoft May 27, 2026
96845b5
Revert "docker image time optimization v1"
Rafi-Microsoft May 27, 2026
7efaf7c
Revert "removed mount from dockerfiles"
Rafi-Microsoft May 27, 2026
d565c8a
fix: address Copilot PR review feedback
Rafi-Microsoft May 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 199 additions & 0 deletions docs/AutomatedLocalSetup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Automated Local Development Setup

Two scripts — one for each platform — that automate the entire local development setup: Azure authentication, `.env` generation, Python/Node dependency installation, RBAC role assignment, and VS Code configuration.

| Platform | Script |
|---|---|
| Linux / macOS / WSL / Git Bash | `infra/scripts/setup_local_dev.sh` |
| Windows PowerShell | `infra/scripts/setup_local_dev.ps1` |

---

## Prerequisites

| Tool | Purpose |
|---|---|
| [Python 3.12+](https://www.python.org/downloads/) | Backend and frontend virtual environments |
| [Node.js 18+](https://nodejs.org/) | Frontend build |
| [uv](https://github.com/astral-sh/uv) | Fast Python package management (backend & MCP) |
| [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) | Fetch Azure config and assign RBAC roles |
| [Git](https://git-scm.com/) | Source control |

You must be logged in before running (the script will prompt if you are not):

```bash
az login
```

---

## What It Does (in order)

1. **Checks prerequisites** — Python 3.12+, Node.js, npm, uv, Azure CLI, Git
2. **Azure authentication** — logs you in if needed, confirms the active subscription
2b. **Checks Azure roles & permissions** — verifies you have role-assignment permission (Owner / User Access Administrator / RBAC Administrator) before attempting RBAC step (non-fatal warning)
3. **Fetches Azure configuration** — reads deployment outputs or queries resources individually to build `src/backend/.env`
4. **Assigns RBAC roles** — grants your user account the roles needed to run the app locally:
- Cosmos DB Built-in Data Contributor
- Azure AI User, Azure AI Developer, Cognitive Services OpenAI User
- Search Index Data Contributor
- Storage Blob Data Contributor
5. **Sets up Backend** (`src/backend`) — creates a `.venv` with `uv`, installs all dependencies
6. **Sets up MCP Server** (`src/mcp_server`) — same as backend
7. **Sets up Frontend** (`src/App`) — creates a `.venv`, installs Python deps, runs `npm install` and `npm run build`
8. **Configures VS Code** — writes `.vscode/extensions.json` and `settings.json` (skip with `--skip-vscode`)
9. **Prints a start summary** with the exact commands to run each service
Comment thread
Rafi-Microsoft marked this conversation as resolved.

---

## Quick Start

```bash
# bash (Linux / macOS / WSL / Git Bash)
bash infra/scripts/setup_local_dev.sh --resource-group <resource-group>

# PowerShell (Windows)
.\infra\scripts\setup_local_dev.ps1 -ResourceGroup <resource-group>
```

The script will:
- Fetch all Azure settings and write `src/backend/.env` automatically
- Create Python virtual environments and install all dependencies
- Assign your account the required Azure roles

---

## All Options

### Bash

```bash
bash infra/scripts/setup_local_dev.sh [options]

Options:
--resource-group, -g <name> Azure Resource Group (auto-detected from .azure/ if omitted)
--subscription, -s <id> Azure Subscription ID (uses current az account if omitted)
--skip-vscode Skip writing .vscode/ settings files
--skip-prereqs Skip prerequisite checks
-h, --help Show help
```

### PowerShell

```powershell
.\infra\scripts\setup_local_dev.ps1 [options]

Options:
-ResourceGroup <name> Azure Resource Group (auto-detected from .azure/ if omitted)
-Subscription <id> Azure Subscription ID (uses current az account if omitted)
-SkipVSCode Skip writing .vscode/ settings files
-SkipPrereqs Skip prerequisite checks
```

---

## Examples

```bash
# Fetch config from Azure and set up everything
bash infra/scripts/setup_local_dev.sh --resource-group rg-macae-dev

# Use a specific subscription
bash infra/scripts/setup_local_dev.sh --resource-group rg-macae-dev --subscription 00000000-0000-0000-0000-000000000000

# Skip VS Code settings (e.g. using a different editor)
bash infra/scripts/setup_local_dev.sh --resource-group rg-macae-dev --skip-vscode

# Skip prerequisite checks (useful in CI or if tools are on a non-standard PATH)
bash infra/scripts/setup_local_dev.sh --resource-group rg-macae-dev --skip-prereqs
```

```powershell
# Fetch config from Azure and set up everything
.\infra\scripts\setup_local_dev.ps1 -ResourceGroup rg-macae-dev

# Use a specific subscription
.\infra\scripts\setup_local_dev.ps1 -ResourceGroup rg-macae-dev -Subscription 00000000-0000-0000-0000-000000000000

# Skip VS Code settings
.\infra\scripts\setup_local_dev.ps1 -ResourceGroup rg-macae-dev -SkipVSCode
```

---

## Auto-Detection (no `--resource-group`)

If you ran `azd up` to deploy, the scripts will automatically find the `.azure/<env>/.env` file and use it — no flags needed:

```bash
bash infra/scripts/setup_local_dev.sh # reads .azure/<env>/.env written by azd up
.\infra\scripts\setup_local_dev.ps1 # same
```

If no `.azure/` folder exists and no `--resource-group` is provided, the script will prompt you to enter the resource group name interactively.

---

## RBAC Roles Assigned

The script automatically grants your user account the following roles (skips if already assigned):

| Role | Resource | Purpose |
|---|---|---|
| Cosmos DB Built-in Data Contributor | Cosmos DB account | Read/write conversation history |
| Azure AI User | AI Foundry project | Call AI Foundry APIs |
| Azure AI Developer | AI Foundry project | Deploy and manage agents |
| Cognitive Services OpenAI User | AI Foundry project | Call OpenAI endpoints |
| Search Index Data Contributor | Azure AI Search | Read/write search indexes |
| Storage Blob Data Contributor | Storage account | Read/write blob storage |

> **Note:** RBAC changes can take 5–10 minutes to propagate before the app can use them.

---

## After Setup

Once the script finishes, start the three services in separate terminals (Backend first, then MCP, then Frontend):

```
Terminal 1 — Backend (port 8000):
cd src/backend
Activate virtual environment:
PowerShell : .\.venv\Scripts\Activate.ps1
Git Bash : source .venv/Scripts/activate
Linux/macOS: source .venv/bin/activate
python app.py

Terminal 2 — MCP Server (port 9000):
cd src/mcp_server
Activate virtual environment:
PowerShell : .\.venv\Scripts\Activate.ps1
Git Bash : source .venv/Scripts/activate
Linux/macOS: source .venv/bin/activate
python mcp_server.py --transport streamable-http --host 0.0.0.0 --port 9000

Terminal 3 — Frontend (port 3000):
cd src/App
Activate virtual environment:
PowerShell : .\.venv\Scripts\Activate.ps1
Git Bash : source .venv/Scripts/activate
Linux/macOS: source .venv/bin/activate
python frontend_server.py
```

Then open [http://localhost:3000](http://localhost:3000).

---

## Troubleshooting

| Symptom | Likely cause | Fix |
|---|---|---|
| `az login` loop | CLI not installed or PATH issue | Install [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) |
| `.env` values empty | RG has no deployment outputs | Pass `--resource-group` explicitly |
| `uv: command not found` | uv not installed | `pip install uv` or see [uv docs](https://github.com/astral-sh/uv) |
| RBAC errors at runtime | Roles not propagated | Wait 10 min for Azure propagation; re-run script |
| `source .venv/Scripts/activate: No such file` | Incomplete venv | Delete `.venv/` folder and re-run the script |
| Frontend npm errors | Node.js version too old | Upgrade to Node.js 18+ |

For more detail, see [TroubleShootingSteps.md](TroubleShootingSteps.md).
178 changes: 178 additions & 0 deletions docs/DeployLocalChanges.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Deploy Local Changes to Azure

Two scripts — one for each platform — that build Docker images for the services you specify (or all by default), push them to ACR, and update the live Azure resources.

| Platform | Script |
|---|---|
| Linux / macOS / WSL | `infra/scripts/deploy_to_azure.sh` |
| Windows PowerShell | `infra/scripts/deploy_to_azure.ps1` |

---

## Prerequisites

| Tool | Required? | Purpose |
|---|---|---|
| [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) | **Yes** | Manage Azure resources, ACR login |
| [Docker Desktop](https://www.docker.com/products/docker-desktop/) | **Yes** | Build and push Docker images |

You must be logged in before running:
```bash
az login
```

---

## What It Does (in order)

1. **Checks prerequisites** — Azure CLI and Docker (both required)
1b. **Checks Azure roles & permissions** — verifies you have Contributor + role-assignment permission on the resource group (non-fatal warning)
2. **Discovers Azure resources** — finds the backend/MCP Container Apps and frontend App Service in your resource group
3. **Resolves ACR** — lists ACRs in the resource group and asks which one to use; prompts to create a new one if needed
4. **Determines services** — deploys all services by default, or only the ones you specify with `--services`
5. **Generates an image tag** — auto-generates `YYYYMMDD-HHMMSS` or uses your custom tag
6. **Builds & pushes images** — builds locally with Docker, pushes to ACR
7. **Updates Azure resources** — updates the Container App / App Service to the new image tag
8. **Prints a summary** with rollback commands
Comment thread
Rafi-Microsoft marked this conversation as resolved.

---

## Quick Start

```bash
# bash (Linux/macOS/WSL)
bash infra/scripts/deploy_to_azure.sh --resource-group <resource-group>

# PowerShell (Windows)
.\infra\scripts\deploy_to_azure.ps1 -ResourceGroup <resource-group>
```

The script will:
- Deploy all services by default (use `--services` to pick specific ones)
- Build images locally with Docker and push to ACR
- Ask which ACR to use (or offer to create one)

---

## All Options

### Bash

```bash
./infra/scripts/deploy_to_azure.sh --resource-group <resource-group> [options]

Required:
-g, --resource-group <name> Azure Resource Group name

Options:
--acr <name> Skip the ACR prompt; use this ACR directly
--services <list> Deploy only these services (default: all)
Values: backend, mcp, frontend (comma-separated)
--tag <tag> Use a custom image tag instead of auto-generated
--dry-run Preview all steps without making any changes
--build-only Build and push images, but don't update Azure
--deploy-only Update Azure resources only (images must exist)
--skip-role-assignment Skip AcrPull role assignment (use if roles already exist)
-h, --help Show help
```

### PowerShell

```powershell
.\infra\scripts\deploy_to_azure.ps1 -ResourceGroup <name> [options]

Required:
-ResourceGroup <name> Azure Resource Group name

Options:
-Acr <name> Skip the ACR prompt; use this ACR directly
-Services <list> Deploy only these services (default: all)
Values: "backend,mcp,frontend"
-Tag <tag> Use a custom image tag instead of auto-generated
-DryRun Preview all steps without making any changes
-BuildOnly Build and push images, but don't update Azure
-DeployOnly Update Azure resources only (images must exist)
-SkipRoleAssignment Skip AcrPull role assignment (use if roles already exist)
```

---

## Examples

```bash
# Deploy all services (default)
bash infra/scripts/deploy_to_azure.sh --resource-group rg-macae-dev

# Deploy only the frontend
bash infra/scripts/deploy_to_azure.sh --resource-group rg-macae-dev --services frontend

# Deploy backend and MCP with a specific ACR
bash infra/scripts/deploy_to_azure.sh --resource-group rg-macae-dev --services backend,mcp --acr myregistry

# Preview without making changes
bash infra/scripts/deploy_to_azure.sh --resource-group rg-macae-dev --dry-run

# Build images only (no Azure update)
bash infra/scripts/deploy_to_azure.sh --resource-group rg-macae-dev --build-only

# Update Azure only (images already pushed)
bash infra/scripts/deploy_to_azure.sh --resource-group rg-macae-dev --deploy-only --tag 20260506-120000-abc1234

# Skip AcrPull role assignment (roles already exist)
bash infra/scripts/deploy_to_azure.sh --resource-group rg-macae-dev --skip-role-assignment
```

```powershell
# Deploy all services (default)
.\infra\scripts\deploy_to_azure.ps1 -ResourceGroup rg-macae-dev

# Deploy only backend
.\infra\scripts\deploy_to_azure.ps1 -ResourceGroup rg-macae-dev -Services "backend"

# Dry run
.\infra\scripts\deploy_to_azure.ps1 -ResourceGroup rg-macae-dev -DryRun

# Skip AcrPull role assignment (roles already exist)
.\infra\scripts\deploy_to_azure.ps1 -ResourceGroup rg-macae-dev -SkipRoleAssignment
```

---

## ACR Selection

If `--acr` / `-Acr` is not provided, the script **always prompts first**:

```
Enter ACR name to use (or press Enter to see available ACRs / create new):
```

- **Type a name** → validates and uses that ACR directly
- **Press Enter** → discovers ACRs in the resource group:
- If one or more ACRs are found, the first one is selected automatically
- If none are found, a new Basic ACR is created in the same resource group

In all cases, `AcrPull` is assigned to the managed identities of each service.

---

## How Azure Authentication Works

The scripts use **managed identity** (not admin credentials or passwords):

- Each Container App and App Service has a user-assigned managed identity
- The script assigns the `AcrPull` role to those identities on the ACR
- `az containerapp registry set --identity <id>` wires the identity to the registry config

This means no passwords are stored anywhere.

If the role assignment step fails (e.g. your account lacks `Microsoft.Authorization/roleAssignments/write`), ask a subscription Owner to grant `User Access Administrator` on the resource group. Once roles are already in place you can skip this step on subsequent runs with `--skip-role-assignment` / `-SkipRoleAssignment`.

---

## Rollback

At the end of each run, the summary prints ready-to-run rollback commands, e.g.:

```bash
az containerapp update --name ca-macae --resource-group rg-macae-dev --image myacr.azurecr.io/macaebackend:20260505-120000-abc1234
```
Loading
Loading