AI Services Hub
Azure Landing Zone Infrastructure
Open Source

AI Services Hub

A shared platform for British Columbia Government teams that need secure artificial intelligence services without exposing Azure resources to the public internet. The design favours private networking, short-lived credentials, and repeatable infrastructure defined in code.

Pilot Project Disclaimer

This is an early-stage pilot. Several architecture patterns are still being validated with the platform team. The goal of this repository is to turn those lessons into a reusable starting point so other British Columbia Government teams do not have to rediscover the same constraints from scratch.

The upstream Azure AI Landing Zones reference architecture carries an archival risk, of which this project team is aware.

Where Do You Want to Start?

I'm a Tenant

My team wants to use AI services (OpenAI, Document Intelligence, PII detection, Speech) through the hub.

See Available Services →

I'm a Platform Admin

I maintain the hub infrastructure — deploying, operating, and troubleshooting the landing zone.

Go to Playbooks →

I'm Exploring

I want to understand the architecture and evaluate whether this platform fits my needs.

View Architecture →

Project Scope: Enabling AI on Azure

This is an AI Platform, Not a General Azure Onboarding Tool

The primary mission of this project is to create a secure, compliant, and reusable "paved road" for AI-specific workloads in the BC Government. It is not intended for general-purpose application hosting.

Our scope is defined by what can be provisioned and managed via Infrastructure as Code. We exclusively support services that have a mature Azure Verified Module (AVM) for Terraform. This ensures every component of the platform is repeatable, auditable, and aligned with industry best practices.

The Challenge: Microsoft's Model vs. BC Gov's Reality

A newcomer to this project might ask: "Why is this so complex? Why not just follow Microsoft's tutorials?" This project exists to answer that question. There is a fundamental disconnect between Microsoft's standard approach and the strict policy requirements of the BC Government.

Microsoft's Assumption: UI-First, Public-Friendly

Microsoft's documentation and tools (like Azure Portal and AI Studio) are designed for a user-friendly, web-based experience. This model assumes that Azure services have public endpoints so the browser-based UIs can connect to them.

BC Gov's Reality: Private-Only, Zero-Trust

BC Government security policy mandates a "zero-trust" network model. Critically, this means **no public endpoints** on any Azure PaaS services. All access must be from within a private, controlled network.

💡
This is the core problem. The "no public endpoints" policy makes the standard, UI-driven Microsoft workflow non-functional. This project implements the architecture required to operate securely within this constraint. For a full breakdown, see Microsoft vs BC Gov Comparison and ADR-008.

Our Solution: An API-First, Secure Landing Zone

This repository provides a standardized, secure-by-default environment that solves the challenges above. Instead of a UI-driven model, we provide an API-first, Infrastructure-as-Code (IaC) model.

1. Secure Private Network

A shared VNet isolates all resources. A Bastion Host and Jumpbox VM provide secure administrative access. Public GitHub Actions runners reach private endpoints via the Chisel tunnel through the Azure Proxy App Service.

See ADR-001: Shared Landing Zone and CI/CD Runner Costs

2. Passwordless OIDC Auth

We eliminate long-lived secrets by using OpenID Connect (OIDC). GitHub Actions receives temporary, auto-expiring tokens from Azure for each deployment, dramatically improving security.

See ADR-002: OIDC Authentication

3. Reusable IaC Modules

We use Microsoft's official Azure Verified Modules (AVM) to define infrastructure. This provides a library of tested, maintained, and reusable components for anyone to consume.

See ADR-009: Why AVMs

Flexible Access Methods

Private endpoints block data plane access from the public internet. We provide four interchangeable access methods - enable only what you need.

Control Plane (Always Works)

Creating/configuring resources via ARM API (management.azure.com). OIDC authentication works from anywhere.

Examples: Create Key Vault, deploy VMs, assign RBAC roles

Data Plane (Requires VNet Access)

Accessing data inside resources (blocked by private endpoints). Needs network path into VNet.

Examples: Read Key Vault secrets, write Storage blobs, query databases

GitHub Runners

Control plane only

Self-Hosted

Full access (in VNet)

Bastion + Jumpbox

Admin access

Chisel Tunnel

Local dev access

ADR-011: Control vs Data Plane | Choose Your Method | Architecture Diagram

What Can You Run Here?

This landing zone is optimized for modern AI/ML workloads that require secure compute and private data access.

Azure AI Foundry

Access many models (OpenAI, Meta, Mistral) and cognitive services through a unified, secure platform.

Open Source Models

Host private weights (Llama 3, Mistral) on secure VMs using Ollama or vLLM.

RAG & Data Apps

Vector databases and Streamlit/Gradio apps for rapid internal prototyping.

I want to...

Set up Authentication

Configure OIDC trust between GitHub and Azure.

Deploy Infrastructure

Deploy VNet, Bastion, and Jumpbox modules.

Fix a Problem

Troubleshoot state locks, auth failures, or rollbacks.

Network Allocation (License Plate: da4cf6)

Confirmed Dec 11, 2025 - Platform Services Team

4x /24
Prod (= /22)
2x /24
Test (= /23)
1x /24
Dev
1x /24
Tools

See FAQ for pending questions about Canada East non-routable ranges.

Documentation Library

ADRs

Architecture decisions and why things are built this way.

Start Here →

FAQ

Common questions, pending decisions, and contact info.

View FAQ →

OIDC Setup

Complete guide to passwordless authentication setup.

View Guide →

TF Reference

Auto-generated variable & output docs for all modules.

View Reference →

Workflows

CI/CD pipeline automation details.

View Workflows →

Diagrams

Interactive architecture and flow visualizations.

View Diagrams →

Playbooks

Operational runbooks for Day 2 maintenance.

View Playbooks →

TF Reference

Auto-generated variable and output docs.

View Reference →

Quick Start

Get Started in 3 Steps

1

Run Setup Script

Configure OIDC trust between GitHub and Azure (once per environment)

2

Add Workflow

Copy the deploy.yml workflow and backend.tf to your repo

3

Push & Deploy

Push to main and watch Terraform deploy automatically

Step 1: Initial Setup

Run this one-time command to create the Azure identity and trust relationship:

./initial-setup/initial-azure-setup.sh \
    -g "YOUR-RESOURCE-GROUP" \
    -n "your-app-identity" \
    -r "bcgov/your-repo" \
    -e "dev" \
    --create-storage --create-github-secrets

Key Features

Secure by Default

  • OIDC federated credentials
  • No stored secrets
  • Environment isolation
  • Least privilege access

Azure Native

  • Managed identities
  • Azure Bastion access
  • Blob storage for state
  • NSG security rules

Automated

  • GitOps workflow
  • Auto VM shutdown
  • Scheduled cleanup
  • On-demand resources

Contributing

All changes follow the project's Developer SDLC — branch, PR, merge to main, promote to prod. This documentation is built automatically from the docs/ folder. To add or update pages:

  1. Create a feature branch and edit files in docs/_pages/
  2. Run ./docs/build.sh to test locally
  3. Open a PR — lint checks and Terraform plan run automatically
  4. Merge to main — GitHub Actions deploys to GitHub Pages automatically

See Workflows for the full SDLC flow, branching patterns (stacked PRs, release PRs), and release process.