A complete, self-contained example demonstrating OnDemand microservice development patterns, Azure Functions implementation, comprehensive CI/CD pipelines, and integration with Core infrastructure.
OndSample is a fully functional reference implementation that showcases OnDemand standards and best practices for building cloud-native microservices. This example is designed to be self-contained, portable, and suitable for learning without the complexity of production-level frameworks.
The backend is implemented as an Azure Functions application, providing:
- .NET 8 Isolated Worker Process - Modern isolated process model for improved performance and independence from the host runtime
- HTTP-triggered functions - RESTful API endpoints for creating and retrieving greetings with OpenAPI documentation
- Service Bus-triggered functions - React to Organization lifecycle events (deletion) from Core Service Bus
- Azure Storage integration - Azure Table Storage for persistent data storage with managed identity authentication
- Azure Key Vault integration - Secure storage and retrieval of secrets and configuration values
- Cross-module communication - Service-to-service calls using OnDemandId Sample Service Principal (standard OnDemand approach)
- Blue/green deployment strategy - Staging and production slot configuration for zero-downtime deployments
- Azure Functions best practices - User-assigned managed identity for zero-credential authentication to Azure resources, Key Vault-based secret management, and dependency injection pattern for service lifetime management
For detailed architecture, code organization, and development workflow, see DEVELOPMENT.md.
The microservice exposes its functionality through a well-defined API:
- API Management integration - Endpoints published to the shared OnDemand API Management instance utilizing API global policy for handling rate limiting, authentication/authorization, and other security measures
- OpenAPI specification - Complete swagger documentation for all endpoints
- RESTful design - Standard HTTP methods (GET, POST) with JSON payloads
For API testing and interactive exploration, see POSTMAN.md.
OndSample demonstrates OnDemand-compliant YAML pipelines covering the complete Software Development Lifecycle (SDLC):
- PR Pipeline (
pr.yaml) - Build validation, ARM template validation, unit test execution on every pull request - CI Pipeline (
ci.yaml) - Artifact production, versioning, deployment to CI environment, acceptance test execution on merge to develop - ExtDev Pipeline (
extdev.yaml) - Multi-region deployment (US + EU) with manual triggers and version selection - Standalone Acceptance Test Pipeline (
at.yaml) - Independent test execution against any environment
All pipelines follow the OnDemand standard practice of artifact-based deployment - binaries are built once in CI, published to Azure Artifacts feed, and deployed across all environments without rebuilding.
For complete pipeline structure, versioning strategy, and deployment workflows, see CI-CD.md.
This example demonstrates key integration patterns used across OnDemand modules:
- Core Service Bus consumption - Listen to and process Organization deletion messages from Core infrastructure
- Message-driven architecture - Service Bus triggered functions react to events from other modules
- Fanout topic pattern - Subscribe to module-specific topics for organization lifecycle events
- API operation policy based on Global API Core policy - Allows accessing claims in the incoming token and applying RBAC based on the effective-permissions claim
- Service Principal distinction - The same mechanism allows distinguishing calls with OnDemand Service SP to allow specific operations for such SPs
For RBAC configuration details, see RBAC-Setup.md.
- Event Grid publishing - Publish audit trail events to OnDemand shared Event Grid topic for compliance tracking
- Standardized event schema - Events follow OnDemand audit schema for consistency
- Managed Identity authentication - No credentials needed for Event Grid publishing
The example implements the standard OnDemand environment progression:
- PR - Pull request validation in isolated environment (
pr-ond-sample) - CI - Continuous integration environment for develop branch (
ci-ond-sample) - ExtDev - Extended development environment with multi-region support (
extdev-sample-westus2,extdev-sample-northeurope) - PreProd/Prod - Production-ready configurations with parameter files included
Each environment has dedicated:
- Azure DevOps environment with approvals and checks
- Resource groups with consistent naming conventions
- Parameter files for ARM template deployment
- Key Vault secrets for environment-specific configuration
OndSample follows OnDemand standard artifact management:
Artifact Production (CI Pipeline):
- Build and package Function App binaries
- Publish NuGet package to Azure Artifacts feed (
<designated ADO artifactory feed>) - Version with semantic versioning (e.g.,
Quest.OnDemand.OndSample.Functions.1.0.45) - Tag artifact as pipeline artifact for initial tracking
- Tag successful builds with version (e.g.,
sample_1.0.45) and stability markers (e.g.,stable)
Artifact Consumption (Deployment Stages):
- ExtDev and higher environments discover artifacts from Azure Artifacts feed by version tag
- Download exact binaries that were tested in CI - no rebuilding
- Successfully deployed artifacts are tagged with environment tags (e.g.,
extdev,preprod,prod) - Enable traceability: which artifact versions are deployed where
Benefits:
- Deploy identical binaries across all environments
- Support rollback to previous tagged versions
- Artifact versioning and traceability for compliance
- Separation of build and deployment concerns
For detailed pipeline mechanics and artifact flow, see CI-CD.md.
The example includes a complete deployment infrastructure:
- ARM Templates - Infrastructure-as-code for Function App, Storage Account, Key Vault with RBAC, and all required Azure resources
- PowerShell orchestration -
Deploy.ps1script handles parameter validation, resource provisioning, APIM configuration, and binary deployment - Environment-specific parameters - JSON parameter files for dev, extdev, preprod, and production environments
- Multi-region support - US (westus2) and EU (northeurope) deployment configurations with identical infrastructure
Deployment Strategy:
- Whenever possible, utilize ARM template deployment for declarative infrastructure management
- Reserve PowerShell scripts for complex scenarios like APIM configuration, secret retrieval, and orchestration
- Bicep conversion - ARM templates are planned to be converted to Bicep in the future for improved authoring experience
Key Features:
- Managed Identity configuration for zero-credential access
- Key Vault integration for secure secret storage
- APIM endpoint registration with OpenAPI specification
- Slot deployment support (staging/production)
For complete deployment guide, ARM template structure, and parameter configuration, see Deployment.md.
Comprehensive test coverage with multiple test types:
-
Unit Tests:
- Function endpoint tests - HTTP trigger validation
- Storage layer tests - Azure Table Storage operations
- Client library tests - Business logic validation
- Executed in PR and CI pipelines on every build
-
Acceptance Tests (SpecFlow-based):
- End-to-end scenario validation with real Azure resources
- Environment-specific configuration via Key Vault secrets
- Executed in CI and ExtDev pipelines after deployment
- Standalone pipeline (
at.yaml) for on-demand test execution
For test execution, coverage reports, and test development, see TESTING.md.
- Postman Collection - Pre-configured requests for interactive API exploration
- Environment-specific configurations - Separate Postman environments for extdev, preprod, prod
- Common workflows - Established request sequences for typical scenarios
- Newman automation support - Collection can be integrated into CI/CD pipelines
For Postman setup and usage, see POSTMAN.md.
OndSample/
├── README.md # This file - overview and documentation index
├── DEVELOPMENT.md # Development guide and architecture patterns
├── TESTING.md # Testing strategy and execution guide
├── POSTMAN.md # Postman collection and API testing guide
├── CI-CD.md # CI/CD pipelines and artifact management
├── Deployment.md # Deployment guide and ARM templates
├── Architecture.md # Deployment architecture and Core integration
├── RBAC-Setup.md # Security and RBAC configuration
│
├── OndSample.Functions/ # Azure Functions application
│ ├── EntryPoints/ # HTTP and Service Bus triggered functions
│ ├── Logic/ # Business logic and Core API integration
│ ├── Storage/ # Azure Table Storage repositories
│ ├── DataTypes/Models/ # Request/response DTOs
│ ├── Program.cs # Dependency injection configuration
│ ├── host.json # Function host settings
│ └── Deployment/ # ARM templates, PowerShell scripts, YAML pipelines
│ ├── Deploy.ps1 # Main deployment orchestration script
│ ├── azuredeploy.json # Function App ARM template
│ ├── azuredeploystorage.json # Storage & Key Vault ARM template
│ ├── pr.yaml # Pull request validation pipeline
│ ├── ci.yaml # Continuous integration pipeline
│ ├── extdev.yaml # ExtDev deployment pipeline
│ ├── at.yaml # Standalone acceptance test pipeline
│ ├── APIM/ # API Management policies and swagger
│ │ ├── swagger.json # OpenAPI specification
│ │ ├── createGreeting.xml # POST operation policy
│ │ └── getGreeting.xml # GET operation policy
│ └── Validation/ # ARM template validation scripts
│
├── OndSample.Functions.Tests/ # Function endpoint unit tests
│
├── OndSample.AcceptanceTests/ # End-to-end acceptance tests (SpecFlow)
│
├── Postman/ # Postman collection and environments
│ ├── OndSample.postman_collection.json
│ └── OndSample.postman_environment.json
│
└── ../../Shared/ # Self-contained shared libraries
├── AzureStorageLibrary/ # Table Storage base classes
├── AzureStorageLibrary.Tests/ # Storage tests (13 tests)
├── SharedClientLibrary/ # Core exceptions and contracts
├── SharedTestLibrary/ # Test utilities and mocks
├── OndSample.ClientLibrary/ # Service-specific business logic
└── OndSample.ClientLibrary.Tests/ # Client library tests (6 tests)
Complete documentation set for all aspects of this example:
| Document | Purpose |
|---|---|
| DEVELOPMENT.md | Code organization, adding features, architecture patterns, development workflow |
| TESTING.md | Unit tests, acceptance tests, smoke tests, test execution, code coverage |
| POSTMAN.md | API testing with Postman, collection workflows, Newman automation |
| CI-CD.md | Pipeline structure, deployment stages, artifact management, versioning |
| Deployment.md | ARM templates, deployment scripts, Key Vault configuration, RBAC setup |
| Architecture.md | Deployment architecture, resource naming, managed identity setup, Core integration |
| RBAC-Setup.md | Role assignments, security model, group memberships, access control |
| Backend Integration Steps (Confluence Guide) | Supplemental integration guidance – contains additional useful background info |
- .NET 8.0 SDK or later
- Visual Studio 2022 or VS Code with C# Dev Kit
- Azure Functions Core Tools (for local debugging)
- Azurite (for local storage emulation)
- Azure PowerShell Module (for deployment)
- ReqnRoll Visual Studio Extension (BDD feature authoring; enables rich editing, navigation, step definition discovery, and test runner integration for
.featurefiles used in acceptance tests) – install from VS Marketplace: https://marketplace.visualstudio.com/items?itemName=reqnroll.Reqnroll
# Navigate to solution directory
cd Microservices-Examples/OndSample/OndSample.Functions
# Restore packages and build
dotnet build OndSample.Functions.sln
# Run all tests (29 tests)
dotnet test OndSample.Functions.slnExpected Output:
Passed! - Failed: 0, Passed: 29, Skipped: 0, Total: 29
-
Start Azurite (storage emulator):
azurite --silent --location c:\azurite --debug c:\azurite\debug.log
-
Open in Visual Studio:
- Open
OndSample.Functions.sln - Press
F5to start debugging - Functions host starts on
http://localhost:7071
- Open
-
Test endpoint:
$headers = @{ "Organization-Id" = "12345678-1234-1234-1234-123456789012" "Request-Id" = (New-Guid).ToString() "User-Email" = "test@example.com" } Invoke-RestMethod -Uri "http://localhost:7071/api/sample/v1.0/greetings/$(New-Guid)" ` -Headers $headers -Method Get
See DEVELOPMENT.md for detailed development workflow.
Creates a new greeting in Azure Table Storage.
Request:
POST /sample/v1.0/greetings
Authorization: Bearer {token}
Organization-Id: {organizationId} # Optional - extracted from token if not provided
Content-Type: application/json
{
"message": "Hello from OndSample!",
"createdBy": "user@example.com"
}Retrieves a greeting by ID from Azure Table Storage.
Request:
GET /sample/v1.0/greetings/{greetingId}
Authorization: Bearer {token}
Organization-Id: {organizationId} # Optional - extracted from token if not providedSee POSTMAN.md for complete API documentation and testing guide.
HTTP Request → APIM (Policy & Auth) → Function (Endpoint)
→ ClientLibrary (Business Logic) → AzureStorageLibrary (Data Access)
→ Azure Table Storage
Core Service Bus (Organization Deleted) → Service Bus Trigger
→ Function (Event Handler) → Storage (Delete Organization Data)
→ Event Grid (Publish Audit Event)
Function App (User-Assigned MI) → Storage Account (RBAC: Storage Table Data Contributor)
→ Key Vault (RBAC: Key Vault Secrets User)
→ Service Bus (RBAC: Azure Service Bus Data Receiver)
→ Event Grid (RBAC: EventGrid Data Sender)
→ Application Insights (Connection String from KV)
See Architecture.md for complete deployment architecture.
- Build service artifacts
- Build acceptance test artifacts
- Validate ARM templates
- Run unit tests
- Build and package artifacts
- Publish to Azure Artifacts feed (
<designated ADO artifactory feed>) - Tag with version (e.g.,
sample_1.0.100) - Deploy to
ci-ond-sampleenvironment - Run acceptance tests
- Tag build as
stableon success
- Discover artifacts from Azure Artifacts by
stabletag - Deploy to US (westus2) and EU (northeurope) regions in parallel
- Run acceptance tests
- Tag artifacts with
extdevon success
See CI-CD.md for complete pipeline documentation.
Choose your path based on what you want to accomplish:
- For Development & Code Changes: Start with DEVELOPMENT.md
- For Running Tests: See TESTING.md
- For API Testing & Exploration: Use POSTMAN.md
- For Understanding Deployment: Reference Deployment.md and Architecture.md
- For CI/CD Pipeline Setup: Follow CI-CD.md
- For Security & Access Control: Review RBAC-Setup.md
-- Questions about code? Check DEVELOPMENT.md -- Testing issues? See TESTING.md -- Deployment problems? Review Architecture.md and Deployment.md -- Pipeline failures? Consult CI-CD.md
- Need help? Contact the Core team or create an issue
This sample represents OnDemand best practices for microservice development, testing, deployment, and CI/CD integration. Use it as a reference for building new OnDemand microservices.