Event-driven · Zero-touch provisioning · Extensible · Retry strategies

Subscription Vending
on Autopilot

A FastAPI microservice that automatically provisions new Azure subscriptions the moment they are created — no manual steps, no drift.

View on GitHub Live Demo Architecture
Python 3.12 FastAPI Azure Event Grid Hatchling

From subscription creation to fully configured — automatically

The service hooks into Azure Event Grid. When a new subscription is created via the Azure portal or IaC, a Microsoft.Resources.ResourceActionSuccess event fires and triggers the provisioning workflow.

Azure Portal / IaC
subscription create
Azure Event Grid
Subscriptions topic
POST /webhook/
ITL Vending Service
Dispatcher
none / queue / dead_letter
Steps 0 – 6
provisioning workflow
200 OK
always returns success

7 deterministic steps, run every time

Steps are independent of each other. A failure in one step does not block the others. The service always returns 200 OK to Event Grid to prevent retry storms.

Step 0
Read Subscription Tags
Reads metadata tags on the new subscription to parameterise all subsequent steps — management group target, budget limits, owner e-mail, AKS flag, and ServiceNow ticket reference.
itl-environment, itl-budget, itl-owner
Step 1
Move to Management Group
Moves the subscription to the target management group determined by the itl-environment tag and the configurable environment-to-MG mapping, ensuring correct policy inheritance from day one.
azure-mgmt-managementgroups
Step 2
Attach Foundation Initiative
Assigns the ITL Foundation Policy Initiative to the subscription via the ITL Authorization service, applying baseline compliance and security posture.
Authorization service
Step 3
Create RBAC Role Assignments
Assigns Owner, Contributor, Security Reader, and Cost Management Reader roles to principals configured via environment variables, granting the right teams immediate access.
VENDING_*_OBJECT_ID env vars
Step 4
Assign Azure Policies
Applies the default set of Azure Policy definitions at subscription scope — covering tagging, allowed regions, VM SKUs, and security baselines.
azure-mgmt-resource
Step 5
Create Budget Alert
Provisions a cost budget and email alert when the itl-budget tag is present. Keeps teams informed before they hit their spending limit.
itl-budget tag required
Step 6
Publish Outbound Event
Fires a completion event to a downstream Event Grid topic once all steps have run, enabling downstream automation such as ITSM ticket creation or Slack notifications.
VENDING_EVENT_GRID_TOPIC_ENDPOINT

Built for reliability and observability

Designed to run unattended in production, with sensible defaults and full visibility into every provisioning run.

Configurable retry strategies
Choose between none (inline, always 200), dead_letter (500 on failure for Event Grid retry), or queue (async Storage Queue worker). Switch with a single env var.
Manual replay endpoint
Re-trigger provisioning for any subscription via POST /webhook/replay without a real Event Grid event. Idempotent, supports dry-run, and optionally protected by a shared secret.
Event-driven trigger
Hooks into Azure Event Grid using Microsoft.Resources.ResourceActionSuccess — no polling, no cron jobs.
No silent data loss
Step failures are logged and included in the structured response. The retry strategy decides the HTTP status code — none always returns 200, dead_letter returns 500 on failure so Event Grid retries, queue offloads async.
Tag-driven configuration
All provisioning behaviour is controlled via subscription tags — no code changes needed for new subscriptions.
Auto-discovered extensions
Drop a .py file in extensions/ and it self-registers at startup. Built-in extensions include webhook notify, API notify, ServiceNow gate check, and ServiceNow feedback — all activated by env vars alone.
Managed Identity auth
Uses azure-identity — no secrets in environment variables. Supports Managed Identity, Workload Identity, and service principal credentials transparently.
Preflight dry-run
Call POST /webhook/preflight to validate all gate checks and simulate every provisioning step against a real subscription — zero Azure mutations, full plan output returned.
Queue monitoring & management
The /jobs/* API exposes live queue stats, message peek, job lookup, DLQ purge, and direct enqueue — all accessible via the vending jobs CLI or a remote API call.
Config inspection
GET /config returns all active settings with secrets automatically redacted. Pair with vending config validate to verify connectivity and required fields in any environment.
Full-featured CLI
The vending CLI covers every operation — provision, preflight, enqueue, job lookup, DLQ purge, config show/validate — all with --remote for live environments and --verbose for timing output.

Standard Python, Azure-native SDKs

No proprietary frameworks. Swap any Azure SDK call for your own implementation without touching the webhook logic.

Python ≥ 3.12 FastAPI ≥ 0.111 Pydantic v2 uvicorn azure-identity azure-mgmt-managementgroups azure-mgmt-authorization azure-mgmt-resource azure-mgmt-subscription azure-mgmt-consumption azure-eventgrid azure-storage-queue httpx click ≥ 8.1 hatchling pytest + pytest-asyncio