Azure Subscription Vending – What We Built, Why We Did It, and How It Scales
Azure Subscription Vending – What We Built, Why We Did It, and How It Scales
We didn’t plan to build a subscription vending machine.
Honestly, we were just trying to help one team get their own Azure subscription for a new project. Simple enough. But by the time we set up IAM, applied the right policies, configured budget alerts, enabled Defender, and double-checked tags… we realized something.
We were doing the same setup again.
And again.
And again.
And of course, sometimes we forgot something. One time we forgot the region restriction policy. Another time, we gave full access when we meant read-only. Another time, we skipped tagging because “we’d do it later” (we didn’t).
That’s when it clicked: this isn’t just about creating subscriptions. This is about governance, security, and scale. And if we didn’t automate it now, we’d pay for it later.
So we built our own vending machine.
So… What is Subscription Vending?
Here’s how I’d explain it to a teammate:
“Imagine every time someone requests an Azure subscription, they get one that’s already locked down, tagged, monitored, budgeted, and compliant — and it happens automatically.”
That’s subscription vending.
It’s the combination of creating a subscription + applying a landing zone setup to it — all through automation.
Why Did We Need It?
Let me paint you a picture.
We had:
-
- Teams creating stuff in the same shared subscription
-
- No consistent tags
-
- Random budgets (or none)
-
- Confusing RBAC setups — sometimes everyone had Contributor, even interns 😬
-
- No easy way to audit who did what
We were slowing things down by being the gatekeepers. And worse, we couldn’t guarantee every subscription was secure or compliant.
We had to fix two things:
-
- Speed – so teams could get what they need quickly
-
- Consistency – so every subscription met our standards
How We Built It (No Fancy Tools, Just Smart Choices)
We didn’t buy a tool. We used what we already had:
-
- Power Apps → so teams can request new environments
-
- Azure DevOps Pipelines → to automate the setup
-
- Terraform → to actually deploy resources
-
- PowerShell scripts → to stitch everything together
Let’s say the data team needs a new subscription for a production workload. They fill out a form like this:
-
- Project name:
data-platform-prod
- Project name:
-
- Expected budget: ₹80,000/month
-
- Tags: project, owner, environment
-
- Admin group:
data-admins@company.com
- Admin group:
-
- Networking: Yes, needs VNet + NSG
That form gets converted into a JSON config file like this:
{
"name": "data-platform-prod",
"budget": 80000,
"tags": {
"project": "data-platform",
"environment": "Prod",
"owner": "data-team"
},
"IAM": {
"groupAdmins": ["data-admins@company.com"]
},
"networking": {
"required": true,
"vnetName": "vnet-data",
"addressPrefix": ["10.20.0.0/16"]
}
}
Boom. That JSON file triggers the pipeline. Terraform takes it from there.
What Does Terraform Actually Do?
Here’s the behind-the-scenes magic:
-
- It moves the subscription under the right management group
-
- Applies Azure Policies (like: only deploy in
westeurope
, require tags, deny public IPs)
- Applies Azure Policies (like: only deploy in
-
- Enables Defender for Cloud
-
- Creates a budget and alert thresholds (70%, 95%, 100%)
-
- Assigns RBAC roles to the specified group
-
- If networking is requested, it builds:
-
* * VNet
-
*
-
* * Subnets
-
*
-
* * NSGs with deny-all rules
-
*
-
* * Peering to our Virtual WAN if needed
-
*
All of this runs with zero manual clicks. Just submit, wait 15–20 minutes, and your environment is ready.
What Our Code Looks Like (No BS, Real Example)
Here’s how we keep our Terraform code clean:
/terraform/
├── subscription/
│ ├── rbac.tf
│ ├── policy.tf
│ ├── budget.tf
└── networking/
├── vnet.tf
├── nsg.tf
We split it this way so we don’t touch everything for every change. Need to update NSG rules? Just run the networking pipeline. Want to add a new policy? Modify policy.tf
, redeploy that piece. No downtime. No chaos.
Where Does This Really Help?
Let’s talk scale.
We now support:
-
- Multiple teams
-
- Multiple environments (Dev, QA, Prod)
-
- Even multiple Azure tenants
And each subscription is created:
-
- With the same policies
-
- With the same tagging standards
-
- With budgets and alerts from day one
-
- With PIM-enabled RBAC
-
- Without anyone opening the portal
Platform team isn’t the blocker anymore. Teams are empowered to move fast. And we’re confident every subscription is compliant.
Final Thoughts (And a Bit of Honesty)
This didn’t happen overnight. Our first version only handled RBAC and tags. No budget. No Defender. Networking was manual. But we kept adding to it—bit by bit.
And now? It works.
We can onboard a new team and give them a secure subscription in minutes. No surprises. No skipped steps. No “oh we forgot to block public IPs” moments.
If you’re just starting, don’t over-engineer it. Pick one thing—maybe automate tagging or RBAC. Then grow it into a full vending machine. Just like we did.
And hey, if you’re already doing something like this, I’d love to hear how you’re approaching it. We’re still learning too.