This guide covers setting up a development environment and deploying InvokeHub to Azure.
- .NET 6 SDK
- Azure Functions Core Tools v4
- Git
- PowerShell 5.1+
- Visual Studio 2022 or VS Code (recommended)
- Azure CLI
- Azure subscription
- PowerShell 5.1+
git clone https://github.com/yourusername/invokehub.git
cd invokehubRun the automated setup script:
./scripts/setup-dev.ps1Or set up manually:
# Copy settings template
cp local.settings.json.template local.settings.json
# Edit local.settings.json with your values
# Restore packages
dotnet restore
# Build project
dotnet buildOption A - Use Azurite (Recommended):
# Install Azurite
npm install -g azurite
# Start Azurite
azurite --silent --location ./.azuriteOption B - Use Real Azure Storage:
- Create a storage account in Azure
- Update
AzureWebJobsStorageinlocal.settings.jsonwith connection string
Edit local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"API_KEY": "dev-test-key-12345",
"BlobContainerName": "powershell-scripts",
"MAX_SCRIPT_SIZE_KB": "1024",
"RATE_LIMIT_SECONDS": "1"
}
}# Start Azure Functions
func start
# You should see:
# Functions:
# GetMenu: [GET] http://localhost:7071/api/menu
# GetScript: [GET] http://localhost:7071/api/script
# ...# Test health endpoint
Invoke-RestMethod http://localhost:7071/api/health
# Test with the client
irm http://localhost:7071/api/loader | iexCreate a test script in your blob container:
- Use Azure Storage Explorer
- Connect to Azurite or your Azure Storage
- Create container
powershell-scripts - Upload
.ps1files
Use the automated deployment script:
# Basic deployment
./scripts/deploy.ps1 -ResourceGroupName "rg-invokehub" -Location "westeurope"
# With custom parameters
./scripts/deploy.ps1 `
-ResourceGroupName "rg-invokehub-prod" `
-Location "westeurope" `
-FunctionAppName "my-invokehub" `
-ApiKey "my-secure-key-here"The script will:
- ✅ Create all Azure resources
- ✅ Configure settings
- ✅ Deploy the code
- ✅ Test the deployment
- ✅ Output connection details
If you prefer manual deployment:
# Variables
$rg = "rg-invokehub"
$location = "westeurope"
$storage = "stinvokehub$(Get-Random -Maximum 9999)"
$functionApp = "invokehub-api"
# Create resource group
az group create --name $rg --location $location
# Create storage account
az storage account create `
--name $storage `
--resource-group $rg `
--location $location `
--sku Standard_LRS
# Create function app
az functionapp create `
--name $functionApp `
--resource-group $rg `
--storage-account $storage `
--consumption-plan-location $location `
--runtime dotnet `
--runtime-version 6 `
--functions-version 4# Generate secure API key
$apiKey = [System.Guid]::NewGuid().ToString()
# Configure settings
az functionapp config appsettings set `
--name $functionApp `
--resource-group $rg `
--settings `
"API_KEY=$apiKey" `
"BlobContainerName=powershell-scripts" `
"MAX_SCRIPT_SIZE_KB=1024"# Build project
dotnet publish -c Release -o ./publish
# Create deployment package
Compress-Archive -Path ./publish/* -DestinationPath deploy.zip -Force
# Deploy to Azure
az functionapp deployment source config-zip `
--resource-group $rg `
--name $functionApp `
--src deploy.zip# Get storage connection string
$connString = az storage account show-connection-string `
--name $storage `
--resource-group $rg `
--query connectionString -o tsv
# Create container
az storage container create `
--name "powershell-scripts" `
--connection-string $connString# Create App Insights
az monitor app-insights component create `
--app "$functionApp-insights" `
--location $location `
--resource-group $rg
# Connect to Function App
$key = az monitor app-insights component show `
--app "$functionApp-insights" `
--resource-group $rg `
--query instrumentationKey -o tsv
az functionapp config appsettings set `
--name $functionApp `
--resource-group $rg `
--settings "APPINSIGHTS_INSTRUMENTATIONKEY=$key"# Upload scripts to blob storage
az storage blob upload-batch `
--destination "powershell-scripts" `
--source "./my-scripts" `
--pattern "*.ps1" `
--connection-string $connString# Check health
Invoke-RestMethod "https://$functionApp.azurewebsites.net/api/health"
# Test with client
irm "https://$functionApp.azurewebsites.net/api/loader?key=$apiKey" | iex# Rebuild and redeploy
dotnet publish -c Release -o ./publish
Compress-Archive -Path ./publish/* -DestinationPath deploy.zip -Force
az functionapp deployment source config-zip `
--resource-group $rg `
--name $functionApp `
--src deploy.zip# Update settings
az functionapp config appsettings set `
--name $functionApp `
--resource-group $rg `
--settings "NEW_SETTING=value"# Run all tests
dotnet test
# Run with coverage
dotnet test /p:CollectCoverage=true./scripts/test-deployment.ps1 `
-ApiUrl "https://your-api.azurewebsites.net/api" `
-ApiKey "your-key"InvokeHub/
├── Api/ # HTTP endpoints
├── Services/ # Business logic
├── Security/ # Security components
├── Models/ # Data models
├── Utilities/ # Helper classes
├── PowerShell/ # Embedded PS scripts
├── Configuration.cs # Central configuration
├── Startup.cs # DI setup
├── host.json # Azure Functions config
└── InvokeHub.csproj # Project file
- Set breakpoints in Visual Studio/VS Code
- Press F5 to start debugging
- Use Postman or curl to test endpoints
# Watch for changes
dotnet watch --project . run_logger.LogInformation("Processing script: {Path}", scriptPath);
_logger.LogError(ex, "Error loading script");$headers = @{ "X-API-Key" = "dev-test-key-12345" }
Invoke-RestMethod http://localhost:7071/api/menu -Headers $headers- Check if port 7071 is already in use
- Verify .NET 6 SDK is installed
- Ensure Azurite is running (if using local storage)
- Verify connection string format
- Check if Azurite is running
- Ensure container exists
# Clean and rebuild
dotnet clean
dotnet restore
dotnet buildSee Contributing Guide for:
- Code style guidelines
- Pull request process
- Testing requirements
- Branch naming conventions