Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.git
.github
.azure
.venv
__pycache__
*.pyc
*.pyo
*.pyd
*.log
*.db
.env
local.settings.json
bin
obj
artifacts
example_code
priv-folder
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ __pycache__
# Azure App Service artifacts
.env
.pem
.azure

# Generated Bicep parameters (contains secrets from preprovision)
deploy/bicep/main.parameters.json

# Configured custom script extensions, powershell scripts, and linux scripts
priv-*
Expand Down
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,32 @@ Given that AVD acts as a pass-through in this solution, starting with **light to

## Getting Started

*(Instructions on deployment, configuration, and usage will be provided here.)*
The supported deployment entrypoint for this repository is in `deploy/`.

While we work on more detailed instructions, you can deploy the web apps from VS Code or running az web deploy. You can deploy function using VS Code. To support managed identity versus using SAS keys, there are a number of permissions that must be applied, please use the RBAC section to facility implementing them. We will release detailed instructions with video guidance over the coming weeks.
For the full deployment walkthrough, see [deploy/DEPLOYMENT.md](deploy/DEPLOYMENT.md).

That guide covers:

- prerequisites and required permissions
- azd environment values and defaults
- how `azd up` prompts for subscription and deployment region when not pre-set
- Entra app and group bootstrap behavior
- SSH key reuse, prompt, and auto-generation behavior
- what `preprovision`, Bicep provisioning, and `postprovision` each do
- SQL bootstrap, Linux host SQL registration, and validation steps
- troubleshooting and rerun paths

Quick start from the repository root:

```powershell
cd .\deploy
azd env new <environment-name>
azd up
```

The deployment defaults the App Service plan to Premium v3 `P2mv3`, which provides the minimum supported baseline of 4 vCPUs and 32 GB memory for the frontend, API, and task apps.

Before running `azd up`, review the detailed guide and set any environment-specific values you need, especially networking, host counts, VM sizes, App Service plan sizing, and SQL firewall access. The deployment scripts under `deploy/` now handle the Entra bootstrap, SSH key flow, App Service health checks on `/health`, Application Insights wiring for the frontend and API, post-provision role assignment, container image builds, SQL initialization, and Linux host SQL registration used by this solution.

## Contributing

Expand Down
20 changes: 20 additions & 0 deletions api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM python:3.11-slim

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV WEBSITES_PORT=8000

WORKDIR /app

RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential curl freetds-dev gcc \
&& rm -rf /var/lib/apt/lists/*

COPY api/requirements.txt ./requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

COPY api/ ./

EXPOSE 8000

CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
28 changes: 26 additions & 2 deletions api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
import logging
import re

from azure.monitor.opentelemetry import configure_azure_monitor

connection_string = os.environ.get('APPLICATIONINSIGHTS_CONNECTION_STRING')
if connection_string:
configure_azure_monitor(connection_string=connection_string, logger_name='linuxbroker.api')

from flask import Flask, jsonify, request
from azure.identity import DefaultAzureCredential
from azure.mgmt.compute import ComputeManagementClient
Expand All @@ -31,7 +37,25 @@
# Logging Configuration

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger = logging.getLogger('linuxbroker.api')


@app.route('/health', methods=['GET'])
def health():
conn = get_db_connection()
if not conn:
return jsonify({'status': 'unhealthy'}), 503

try:
cursor = conn.cursor()
cursor.execute('SELECT 1')
cursor.fetchone()
return jsonify({'status': 'healthy', 'version': app.config['VERSION']}), 200
except Exception as e:
logger.error("Health check failed: %s", e)
return jsonify({'status': 'unhealthy'}), 503
finally:
conn.close()

# ===============================
# Functions
Expand Down Expand Up @@ -433,7 +457,7 @@ def get_all_vms():
conn.close()

if not rows:
return "No VMs found.", 404
return jsonify([]), 200

return jsonify(rows), 200

Expand Down
1 change: 1 addition & 0 deletions api/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Flask==2.2.2
gunicorn
Werkzeug==2.2.2
pyodbc==4.0.35
azure-monitor-opentelemetry==1.8.7
azure-identity==1.17.1
azure-mgmt-compute==33.0.0
pyjwt==2.9.0
Expand Down
41 changes: 0 additions & 41 deletions bicep/AVD/README.md

This file was deleted.

20 changes: 0 additions & 20 deletions bicep/AVD/main.bicepparam

This file was deleted.

37 changes: 0 additions & 37 deletions bicep/Linux/README.md

This file was deleted.

17 changes: 0 additions & 17 deletions bicep/Linux/main.bicepparam

This file was deleted.

25 changes: 22 additions & 3 deletions custom_script_extensions/Configure-RHEL7-Host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

# Installs and configures the necessary packages for Linux Broker for AVD Access on RHEL 7

LINUXBROKER_API_BASE_URL="${1:-}"
LINUXBROKER_API_CLIENT_ID="${2:-}"

if [ -z "$LINUXBROKER_API_BASE_URL" ] || [ -z "$LINUXBROKER_API_CLIENT_ID" ]; then
echo "Linux Broker API base URL and client ID are required."
exit 1
fi

case "$LINUXBROKER_API_BASE_URL" in
https://*) ;;
*)
echo "Linux Broker API base URL must start with https://"
exit 1
;;
esac

LINUXBROKER_API_BASE_URL="${LINUXBROKER_API_BASE_URL%/}"

# ===============================
# Variables

Expand All @@ -28,8 +46,8 @@ CURRENT_USERS_DETAILS="$output_directory/xrdp-loggedin-users.txt"

CRON_SCHEDULE="0 * * * *"

YOUR_LINUXBROKER_API_CLIENT_ID="my_actual_client_id"
YOUR_LINUXBROKER_API_URL="my.actual.linuxbroker.api.url"
YOUR_LINUXBROKER_API_CLIENT_ID="$LINUXBROKER_API_CLIENT_ID"
YOUR_LINUXBROKER_API_BASE_URL="$LINUXBROKER_API_BASE_URL"

# ===============================
# Execution
Expand Down Expand Up @@ -122,7 +140,8 @@ echo "Downloading release-session.sh..."
sudo wget -O "$SCRIPT_PATH" "$release_session_url"

sudo sed -i "s|YOUR_LINUX_BROKER_API_CLIENT_ID|$YOUR_LINUXBROKER_API_CLIENT_ID|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_URL|$YOUR_LINUXBROKER_API_URL|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_BASE_URL|$YOUR_LINUXBROKER_API_BASE_URL|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_URL|$YOUR_LINUXBROKER_API_BASE_URL|g" "$SCRIPT_PATH"

echo "Downloading xrdp-who-xnc.sh..."
sudo wget -O "$output_directory/xrdp-who-xnc.sh" "$xrdp_who_xnc_url"
Expand Down
25 changes: 22 additions & 3 deletions custom_script_extensions/Configure-RHEL8-Host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

# Installs and configures the necessary packages for Linux Broker for AVD Access on RHEL 8

LINUXBROKER_API_BASE_URL="${1:-}"
LINUXBROKER_API_CLIENT_ID="${2:-}"

if [ -z "$LINUXBROKER_API_BASE_URL" ] || [ -z "$LINUXBROKER_API_CLIENT_ID" ]; then
echo "Linux Broker API base URL and client ID are required."
exit 1
fi

case "$LINUXBROKER_API_BASE_URL" in
https://*) ;;
*)
echo "Linux Broker API base URL must start with https://"
exit 1
;;
esac

LINUXBROKER_API_BASE_URL="${LINUXBROKER_API_BASE_URL%/}"

# ===============================
# Variables

Expand Down Expand Up @@ -50,8 +68,8 @@ CURRENT_USERS_DETAILS="$output_directory/xrdp-loggedin-users.txt"

CRON_SCHEDULE="0 * * * *"

YOUR_LINUXBROKER_API_CLIENT_ID="my_actual_client_id"
YOUR_LINUXBROKER_API_URL="my.actual.linuxbroker.api.url"
YOUR_LINUXBROKER_API_CLIENT_ID="$LINUXBROKER_API_CLIENT_ID"
YOUR_LINUXBROKER_API_BASE_URL="$LINUXBROKER_API_BASE_URL"

# ===============================
# Execution
Expand Down Expand Up @@ -145,7 +163,8 @@ echo "Downloading release-session.sh..."
sudo wget -O "$SCRIPT_PATH" "$release_session_url"

sudo sed -i "s|YOUR_LINUX_BROKER_API_CLIENT_ID|$YOUR_LINUXBROKER_API_CLIENT_ID|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_URL|$YOUR_LINUXBROKER_API_URL|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_BASE_URL|$YOUR_LINUXBROKER_API_BASE_URL|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_URL|$YOUR_LINUXBROKER_API_BASE_URL|g" "$SCRIPT_PATH"

echo "Downloading xrdp-who-xorg.sh..."
sudo wget -O "$output_directory/xrdp-who-xorg.sh" "$xrdp_who_xorg_url"
Expand Down
22 changes: 19 additions & 3 deletions custom_script_extensions/Configure-RHEL9-Host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

# Installs and configures the necessary packages for Linux Broker for AVD Access on RHEL 9

LINUXBROKER_API_BASE_URL="${1:-}"
LINUXBROKER_API_CLIENT_ID="${2:-}"

if [[ -z "$LINUXBROKER_API_BASE_URL" || -z "$LINUXBROKER_API_CLIENT_ID" ]]; then
echo "Linux Broker API base URL and client ID are required."
exit 1
fi

if [[ "$LINUXBROKER_API_BASE_URL" != https://* ]]; then
echo "Linux Broker API base URL must start with https://"
exit 1
fi

LINUXBROKER_API_BASE_URL="${LINUXBROKER_API_BASE_URL%/}"

# ===============================
# Variables

Expand All @@ -28,8 +43,8 @@ CURRENT_USERS_DETAILS="$output_directory/xrdp-loggedin-users.txt"

CRON_SCHEDULE="0 * * * *"

YOUR_LINUXBROKER_API_CLIENT_ID="my_actual_client_id"
YOUR_LINUXBROKER_API_URL="my.actual.linuxbroker.api.url"
YOUR_LINUXBROKER_API_CLIENT_ID="$LINUXBROKER_API_CLIENT_ID"
YOUR_LINUXBROKER_API_BASE_URL="$LINUXBROKER_API_BASE_URL"

# ===============================
# Execution
Expand Down Expand Up @@ -134,7 +149,8 @@ echo "Downloading release-session.sh..."
sudo wget -O "$SCRIPT_PATH" "$release_session_url"

sudo sed -i "s|YOUR_LINUX_BROKER_API_CLIENT_ID|$YOUR_LINUXBROKER_API_CLIENT_ID|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_URL|$YOUR_LINUXBROKER_API_URL|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_BASE_URL|$YOUR_LINUXBROKER_API_BASE_URL|g" "$SCRIPT_PATH"
sudo sed -i "s|YOUR_LINUX_BROKER_API_URL|$YOUR_LINUXBROKER_API_BASE_URL|g" "$SCRIPT_PATH"

echo "Downloading xrdp-who-xnc.sh..."
sudo wget -O "$output_directory/xrdp-who-xnc.sh" "$xrdp_who_xnc_url"
Expand Down
Loading
Loading