diff --git a/samples/gh-flow/.gitignore b/samples/gh-flow/.gitignore new file mode 100644 index 00000000..9aa0044e --- /dev/null +++ b/samples/gh-flow/.gitignore @@ -0,0 +1,3 @@ +# Generated bicep files +infra/main.json +infra/main.local.json diff --git a/samples/gh-flow/LOCAL-DEVELOPMENT.md b/samples/gh-flow/LOCAL-DEVELOPMENT.md new file mode 100644 index 00000000..de847aa8 --- /dev/null +++ b/samples/gh-flow/LOCAL-DEVELOPMENT.md @@ -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 \ No newline at end of file diff --git a/samples/gh-flow/docs/github-flow-getting-started.md b/samples/gh-flow/docs/github-flow-getting-started.md index ebfb1682..f4f04198 100644 --- a/samples/gh-flow/docs/github-flow-getting-started.md +++ b/samples/gh-flow/docs/github-flow-getting-started.md @@ -102,6 +102,8 @@ 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 @@ -109,10 +111,31 @@ 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) diff --git a/samples/gh-flow/infra/main.local.bicep b/samples/gh-flow/infra/main.local.bicep new file mode 100644 index 00000000..194acd06 --- /dev/null +++ b/samples/gh-flow/infra/main.local.bicep @@ -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 \ No newline at end of file diff --git a/samples/gh-flow/infra/main.local.parameters.json b/samples/gh-flow/infra/main.local.parameters.json new file mode 100644 index 00000000..8f7787be --- /dev/null +++ b/samples/gh-flow/infra/main.local.parameters.json @@ -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}" + } + } +} \ No newline at end of file diff --git a/samples/gh-flow/provision-local.sh b/samples/gh-flow/provision-local.sh new file mode 100755 index 00000000..d7cb4156 --- /dev/null +++ b/samples/gh-flow/provision-local.sh @@ -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 " + 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" \ No newline at end of file