Skip to content
Draft
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
3 changes: 3 additions & 0 deletions samples/gh-flow/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Generated bicep files
infra/main.json
infra/main.local.json
63 changes: 63 additions & 0 deletions samples/gh-flow/LOCAL-DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Local Development Provisioning

This guide explains how to provision minimal Azure resources for local development of the gh-flow sample.

## Overview

When developing locally, you don't need all the Azure resources that are required for a full production deployment. The local provisioning option creates only the essential Azure resources while using containerized services for everything else.

## What gets provisioned

### Full deployment (azure.yaml + main.bicep)
- Azure Storage Account
- Application Insights & Log Analytics
- Container Apps Environment & Registry
- Qdrant deployed to Azure Container Apps
- Cosmos DB
- gh-flow Container App service

### Local development (main.local.bicep)
- Azure Storage Account (for file shares needed by Azure Container Instances)

### What you use locally instead
- **Qdrant**: Uses the containerized Qdrant running in devcontainer (`http://qdrant:6333`)
- **Application**: Runs locally via `dotnet run` or VS Code debugging
- **Database**: Can use Cosmos DB emulator or skip database-dependent features
- **Monitoring**: Local logging instead of Application Insights

## How to use

1. **Provision minimal resources:**
```bash
azd auth login
./provision-local.sh your-env-name
```

2. **Configure your appsettings.json:**
The script will output the exact values you need to add to your `appsettings.json` file.

3. **Complete your configuration:**
You still need to configure:
- GitHub App settings (AppKey, AppId, InstallationId, WebhookSecret)
- OpenAI settings (Endpoint, ApiKey, DeploymentId, etc.)

## Benefits

- **Faster provisioning**: Only creates one storage account instead of 10+ resources
- **Lower cost**: No Container Apps, Cosmos DB, or other expensive services running in Azure
- **Easier cleanup**: Minimal resources to clean up when done
- **Better for development**: Use local debugging tools and faster iteration

## When to use each option

**Use local provisioning when:**
- Developing and testing the application locally
- Working on agent logic and GitHub integration
- Don't need Azure hosting or full production environment
- Want to minimize Azure costs during development

**Use full provisioning when:**
- Deploying to production or staging
- Testing the full Azure integration
- Need the complete Container Apps deployment
- Sharing the application with others via public URL
25 changes: 24 additions & 1 deletion samples/gh-flow/docs/github-flow-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,40 @@ Let's start by logging in to Azure using
azd auth login
```

### Option 1: Full Azure Deployment

After we've logged in, we need to create a new environment provision the azure bits.

```bash
ENVIRONMENT=_name_of_your_env
azd env new $ENVIRONMENT
azd provision -e $ENVIRONMENT
```

This provisions all Azure resources including Container Apps, Cosmos DB, Qdrant on Azure, monitoring, etc.

### Option 2: Minimal Provisioning for Local Development

If you're developing locally and only need the essential Azure resources (storage account for file shares), you can use the minimal provisioning option:

```bash
./provision-local.sh your-environment-name
```

This will:
- Provision only a storage account with file shares needed for Azure Container Instances
- Skip expensive resources like Container Apps, Cosmos DB, Azure-hosted Qdrant, etc.
- Use the local bicep template (`main.local.bicep`) instead of the full template

For local development, you'll use:
- The containerized Qdrant (already running in devcontainer at `http://qdrant:6333`)
- Your local application instance
- Only the Azure storage account for file shares

After the provisioning is done, you can inspect the outputs with the following command

```bash
azd env get-values -e dev
azd env get-values -e $ENVIRONMENT
```
As the last step, we also need to [load the WAF into the vector DB](#load-the-waf-into-qdrant)

Expand Down
50 changes: 50 additions & 0 deletions samples/gh-flow/infra/main.local.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
targetScope = 'subscription'

@minLength(1)
@maxLength(64)
@description('Name of the the environment which is used to generate a short unique hash used in all resources.')
param environmentName string

@minLength(1)
@description('Primary location for all resources')
param location string

param resourceGroupName string = ''
param storageAccountName string = ''

var aciShare = 'acishare'

var abbrs = loadJsonContent('./abbreviations.json')
var resourceToken = toLower(uniqueString(subscription().id, environmentName, location))
var tags = { 'azd-env-name': environmentName }

// Organize resources in a resource group
resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
name: !empty(resourceGroupName) ? resourceGroupName : '${abbrs.resourcesResourceGroups}${environmentName}'
location: location
tags: tags
}

var actualStorageAccountName = !empty(storageAccountName) ? storageAccountName : '${abbrs.storageStorageAccounts}${resourceToken}'

// Storage account for file shares (needed for Azure Container Instances)
module storage './core/storage/storage-account.bicep' = {
name: 'storage'
scope: rg
params: {
name: actualStorageAccountName
location: location
tags: tags
fileShares: [
aciShare
]
}
}

// App outputs
output AZURE_LOCATION string = location
output AZURE_TENANT_ID string = subscription().tenantId
output AZURE_SUBSCRIPTION_ID string = subscription().subscriptionId
output AZURE_RESOURCE_GROUP_NAME string = rg.name
output AZURE_FILESHARE_NAME string = aciShare
output AZURE_FILESHARE_ACCOUNT_NAME string = actualStorageAccountName
12 changes: 12 additions & 0 deletions samples/gh-flow/infra/main.local.parameters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environmentName": {
"value": "${AZURE_ENV_NAME}"
},
"location": {
"value": "${AZURE_LOCATION}"
}
}
}
85 changes: 85 additions & 0 deletions samples/gh-flow/provision-local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/bin/bash

# Script to provision minimal Azure resources for local development

set -e

echo "=========================================="
echo "Local Development Provisioning Script"
echo "=========================================="
echo ""

# Check if azd is installed
if ! command -v azd &> /dev/null; then
echo "Error: Azure Developer CLI (azd) is not installed."
echo "Please install azd first: https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd"
echo ""
echo "Installation instructions:"
echo " https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd"
exit 1
fi

# Check if we're in the right directory
if [ ! -f "azure.yaml" ]; then
echo "Error: azure.yaml not found. Please run this script from the gh-flow sample directory."
exit 1
fi

echo "This script will provision minimal Azure resources for local development."
echo "It only creates a storage account instead of the full infrastructure."
echo ""

# Get environment name
if [ -z "$1" ]; then
echo "Usage: $0 <environment-name>"
echo ""
echo "Example: $0 my-local-dev"
exit 1
fi

ENVIRONMENT_NAME=$1

echo "Environment: $ENVIRONMENT_NAME"
echo ""

# Create environment if it doesn't exist
echo "Creating/selecting azd environment..."
azd env new $ENVIRONMENT_NAME 2>/dev/null || azd env select $ENVIRONMENT_NAME

# Override the bicep template to use the local version
echo "Configuring for local development (using main.local.bicep)..."

# Create a temporary azure.yaml that uses the local bicep
cat > azure.local.tmp.yaml << EOF
# yaml-language-server: \$schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json

name: ai-dev-team-local
infra:
provider: bicep
path: infra
module: main.local
parameters: main.local.parameters.json
EOF

# Use the temporary configuration
export AZD_CONFIG_FILE="azure.local.tmp.yaml"

# Provision the infrastructure
echo "Running azd provision with minimal configuration..."
echo ""
azd provision

# Clean up temp file
rm -f azure.local.tmp.yaml

echo ""
echo "=========================================="
echo "Local development setup complete!"
echo "=========================================="
echo ""
echo "To get your configuration values, run:"
echo " azd env get-values -e $ENVIRONMENT_NAME"
echo ""
echo "You'll need to configure your appsettings.json with values from azd env get-values."
echo ""
echo "For detailed configuration instructions, see LOCAL-DEVELOPMENT.md"