Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
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
189 changes: 189 additions & 0 deletions docs/AutomatedLocalSetup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# 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` |
Comment thread
Abdul-Microsoft marked this conversation as resolved.

---

## 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
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

---

## 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>
```
Comment thread
Abdul-Microsoft marked this conversation as resolved.

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)
Comment thread
Abdul-Microsoft marked this conversation as resolved.
--subscription, -s <id> Azure Subscription ID (uses current az account if omitted)
--skip-vscode Skip writing .vscode/ settings files
Comment thread
Abdul-Microsoft marked this conversation as resolved.
--skip-prereqs Skip prerequisite checks
Comment thread
Abdul-Microsoft marked this conversation as resolved.
-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):

Comment thread
Abdul-Microsoft marked this conversation as resolved.
| 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:

```bash
# Terminal 1 — Backend (port 8000)
cd src/backend
source .venv/Scripts/activate # Windows Git Bash
# source .venv/bin/activate # Linux / macOS
uvicorn app:app --reload --host 0.0.0.0 --port 8000
Comment thread
Abdul-Microsoft marked this conversation as resolved.
Outdated

# Terminal 2 — MCP Server (port 9000)
cd src/mcp_server
source .venv/Scripts/activate
python mcp_server.py

# Terminal 3 — Frontend (port 3000)
cd src/App
npm run dev
Comment thread
Abdul-Microsoft marked this conversation as resolved.
Outdated
Comment thread
Abdul-Microsoft marked this conversation as resolved.
Outdated
```

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).
197 changes: 197 additions & 0 deletions docs/DeployLocalChanges.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Deploy Local Changes to Azure

Two scripts — one for each platform — that build only the Docker images you changed, 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` |
Comment thread
Abdul-Microsoft marked this conversation as resolved.

---

## Prerequisites

| Tool | Purpose |
|---|---|
| [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) | Manage Azure resources |
| [Docker Desktop](https://www.docker.com/products/docker-desktop/) | Build and push images |
| Git | Detect which services changed |

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

---

## What It Does (in order)

1. **Checks prerequisites** — Docker, Azure CLI, Git
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. **Detects changed services** — uses `git diff` to find which of `src/backend/`, `src/mcp_server/`, `src/App/` have changed; only those services are built and deployed
5. **Generates an image tag** — auto-generates `YYYYMMDD-HHMMSS-<git-sha>` or uses your custom tag
6. **Builds & pushes images** — `docker build` + `docker push` to ACR for each changed service
7. **Updates Azure resources** — updates the Container App / App Service to the new image tag
8. **Prints a summary** with rollback commands

---

## Quick Start

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

# PowerShell (Windows)
.\infra\scripts\deploy_to_azure.ps1 -ResourceGroup <resource-group>
```
Comment thread
Abdul-Microsoft marked this conversation as resolved.

The script will:
- Auto-detect which services you changed via git
- Ask which ACR to use (or offer to create one)
- Ask for confirmation before deploying if no changes are detected

---

## All Options

### Bash

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

Comment thread
Abdul-Microsoft marked this conversation as resolved.
Required:
-g, --resource-group <name> Azure Resource Group name

Options:
--acr <name> Skip the ACR prompt; use this ACR directly
--services <list> Skip change detection; deploy only these services
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> Skip change detection; deploy only these services
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 only what changed (auto-detected)
bash infra/scripts/deploy_to_azure.sh -g rg-macae-dev

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

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

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

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

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

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

```powershell
# Deploy only what changed
.\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
```

---

## Change Detection Logic

When `--services` is not specified, the script runs `git diff` to determine what to build:

| Files changed in | Service built |
|---|---|
| `src/backend/` | backend |
| `src/mcp_server/` | mcp |
| `src/App/` | frontend |

It checks only **uncommitted changes** (staged and unstaged vs the last commit, i.e. `git diff HEAD`). Commits that are already committed but not yet pushed are intentionally excluded to avoid false positives from unrelated branch work.

If no changes are detected in any service directory, the script asks:
```
No changes detected. Deploy all services anyway? [y/N]:
```

---

## 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