Project Summary¶
This page summarizes the work done across the Hinze Technologies repositories.
SampleBlazor.Web¶
Repository: konradhinze/sampleblazor
A sample Blazor WebAssembly application that serves as the first containerized workload deployed on the Hinze Technologies Azure infrastructure.
What It Is¶
SampleBlazor.Web is a client-side Blazor WebAssembly application built on .NET 10. It includes the default Blazor template pages (Home, Counter, Weather) and is served as a static site via nginx inside a Docker container.
What Was Done¶
- Created the Blazor WebAssembly project using the standard .NET Blazor template with interactive WebAssembly render mode
- Dockerized the application with a multi-stage Dockerfile:
- Build stage: .NET SDK 10.0 restores, builds, and publishes the app
- Runtime stage: nginx Alpine serves the static
wwwrootoutput on port 80
- Set up the Azure DevOps pipeline (
azure-pipelines.yml) to:- Install .NET SDK 10.0
- Publish the Blazor app in Release configuration
- Build and tag the Docker image as
acrht.azurecr.io/sampleblazorweb:{BuildId} - Push the image to Azure Container Registry (
acrht) - Deploy the container app using the
container-pipeline.ymltemplate from azure-templates
- Deployed as a Container App (
ca-sampleblazorweb-ht-dev) in the dev environment, accessible via the Application Gateway atsampleblazorweb.dev.hinze-technologies.com
Tech Stack¶
| Component | Technology |
|---|---|
| Framework | .NET 10 Blazor WebAssembly |
| Web Server | nginx Alpine |
| Container Registry | Azure Container Registry (acrht) |
| Hosting | Azure Container Apps |
| CI/CD | Azure DevOps Pipelines |
Infrastructure¶
Repository: konradhinze/infrastructure
Contains the Azure DevOps pipeline definitions that deploy the shared and environment-specific Azure infrastructure for Hinze Technologies.
What Was Done¶
- Created
global-pipeline.yml— Deploys global shared services (ACR, Managed Identity, Log Analytics, App Insights, Global Key Vault) torg-ht-globalusing theglobal-pipeline.ymltemplate from azure-templates - Created
global-dev.yaml— Deploys dev environment infrastructure (VNet, Container Apps Environment, Application Gateway WAF v2, Private Endpoints, DNS Zones, Environment Key Vault) torg-ht-devusing theenvironment-pipeline.ymltemplate from azure-templates
Both pipelines:
- Reference the
konradhinze/azure-templatesrepository as a template source - Use the
HinzeTechnologiesPlaygroundAzure service connection - Are configured with prefix
htand regionnortheurope - Trigger on pushes to the
mainbranch
Pipeline Configuration¶
| Pipeline File | Template Used | Target Resource Group | What It Deploys |
|---|---|---|---|
global-pipeline.yml |
global-pipeline.yml@azure-templates |
rg-ht-global |
ACR, Managed Identity, Log Analytics, App Insights, Global KV |
global-dev.yaml |
environment-pipeline.yml@azure-templates |
rg-ht-dev |
VNet, NSGs, CAE, App Gateway, Private Endpoints, DNS, Env KV |
Key Variables¶
| Variable | Value | Description |
|---|---|---|
prefix |
ht |
Resource naming prefix |
location |
northeurope |
Azure region |
azureServiceConnection |
HinzeTechnologiesPlayground |
Azure DevOps service connection |
domainName |
dev.hinze-technologies.com |
Custom domain for host-based routing (dev only) |
Azure Templates¶
Repository: konradhinze/azure-templates
A library of reusable Bicep modules and Azure DevOps pipeline templates that provide the building blocks for the entire infrastructure.
What Was Done¶
Bicep Modules (_modules/)¶
-
global.bicep— Shared services deployed once per project:- Azure Container Registry (Basic SKU, public access enabled)
- User-Assigned Managed Identity (used by all container apps for ACR pull and Key Vault access)
- Log Analytics Workspace (PerGB2018 pricing, 30-day retention)
- Application Insights (Web type, linked to Log Analytics)
- Global Key Vault (Standard, RBAC-enabled, soft delete)
- RBAC role assignment: Managed Identity gets Key Vault Secrets User on Global KV
-
global.environment.bicep— Environment-specific infrastructure deployed per environment:- Virtual Network (10.0.0.0/16) with three subnets:
snet-containerapps(10.0.0.0/23) — delegated to Container Appssnet-privateendpoints(10.0.4.0/24) — for Private Endpointssnet-appgw(10.0.8.0/24) — for Application Gateway
- Three Network Security Groups with environment-appropriate rules
- Container Apps Environment (internal, VNet-integrated, Log Analytics-connected)
- Private DNS Zone for the Container Apps default domain
- Application Gateway WAF v2 with:
- Public IP (Standard, Static)
- Host-based routing for container apps (
{appName}.{domainName}) - HTTPS backend settings with health probes
- WAF policy (OWASP 3.2, Prevention mode)
- Dynamic backend pools, listeners, and routing rules based on discovered apps
- Environment Key Vault (Standard, RBAC, private access only)
- Private Endpoints for Key Vault and Log Analytics
- Private DNS Zones with VNet links for
privatelink.vaultcore.azure.netandprivatelink.ods.opinsights.azure.com - RBAC: Managed Identity gets Key Vault Secrets User on Environment KV
- Virtual Network (10.0.0.0/16) with three subnets:
-
containers.bicep— Reusable container app module:- Deploys a single Container App with user-assigned managed identity
- External ingress on port 80 with HTTPS transport
- ACR registry authentication via managed identity
- Application Insights integration via environment variable
- Auto-scaling: 1–3 replicas based on HTTP concurrency (50 requests)
- Outputs: resource ID, FQDN, and name (saved to Key Vault for discovery)
Pipeline Templates (pipelines/)¶
global-pipeline.yml— Deploysglobal.bicepand saves outputs to Global Key Vaultenvironment-pipeline.yml— Reads global outputs from Key Vault, discovers existing container apps, deploysglobal.environment.bicepwith app routing, saves environment outputs to Environment Key Vaultcontainer-pipeline.yml— Reads global and environment secrets from Key Vault, deployscontainers.bicep, saves container app outputs (ID, FQDN, name) to Environment Key Vault for App Gateway discovery
Helper Templates (pipelines/templates/)¶
read-keyvault.yml— Reads secrets from an Azure Key Vault and sets them as pipeline variablessave-outputs-to-keyvault.yml— Saves Bicep deployment outputs as Key Vault secretsdeploy-bicep.yml— Deploys a Bicep template to a resource group
Design Patterns¶
Key Vault as State Store
Pipeline outputs are persisted in Azure Key Vault, enabling cross-pipeline data sharing. Global outputs (ACR login server, managed identity ID, etc.) are stored in the Global Key Vault (kvg-ht), while environment-specific outputs are stored in Environment Key Vaults (kv-ht-{env}).
Dynamic App Gateway Routing
The environment pipeline discovers deployed container apps by scanning Key Vault secrets (pattern: containerApp-*-name / containerApp-*-fqdn). It then passes the apps array to global.environment.bicep, which dynamically generates App Gateway backend pools, HTTP listeners, and routing rules.
Layered Deployment
Infrastructure is deployed in three layers with clear dependency ordering: Global → Environment → Applications. Each layer consumes outputs from the previous layer via Key Vault secrets.