This post was originally published here

Microsoft Azure isn’t a platform. Like every other public cloud, it’s an environment and set of components you’ll use to construct your platform. It’s more like an operating system that you build on, versus some integrated product you just start using. And that’s exciting. Which platform will you create? Let’s look at what a software platform is, how I landed on 295,680 unique configurations — 10,036,224,000 configurations if you add a handful of popular 3rd party products — and the implications of all this.

What’s a software platform?

Let’s not overthink this. When I refer to a software platform, I’m thinking of the technologies that come together to help you deploy, run, and manage software. This applies whether we’re talking about stuff in your data center or in the public cloud. It applies to serverless systems or good ol’ virtual machines.

I made a map of the non-negotiable capabilities. One way or another, you’re stitching these things together. You need an app runtime (e.g. VMs, FaaS, containers), databases, app deployment tools, infrastructure/config management, identity systems, networking, monitoring, and more. Pretty much all your running systems depend on this combination of things.

How many platform combinations are there in Microsoft Azure?

I’m not picking on Microsoft here; you face the same decision points in every cloud. Each customer realistically, each tenant in your account chooses among the various services to assemble the platform they want. Let’s first talk about only using Microsoft’s first-party services. So, assume you aren’t using any other commercial or OSS products to build and run your systems. Unlikely, but hey, work with me here.

For math purposes, let’s calculate unique combinations by assuming your platform uses one thing from each category. The exception? App runtimes and databases. I think it’s more likely you’re using at least a pair of runtimes (e.g. Azure App Service AND Azure Kubernetes Service, or, Windows VMs AND Linux VMs), and a pair of databases. You may be using more, but I’m being conservative.

295,680 unique platforms you can build on Azure using only native services. Ok, that’s a lot. Now that said, I suspect it’s VERY unlikely you’ll only use native cloud services to build and run software. You might love using Terraform to deploy infrastructure. Or MongoDB Atlas for a managed MongoDB environment. Kong may offer your API gateway of choice. Maybe Prometheus is your standard for monitoring. And don’t forget about all the cool managed services like Twilio, Auth0, or Algolia. The innovation outside of any one cloud will always be greater than the innovation within that cloud. You want in on some of that action! So what happens if I add just a few leading non-Azure services to your platform?

Yowza. 10 billion platform combinations. You can argue with my math or approach, but hopefully you get my point.

And again, this really isn’t about any particular cloud. You can end up in the same place on AWS, Digital Ocean, or Alibaba. It’s simply the result of all the amazing choices we have today.

Who cares?

If you’re working at a small company, or simply an individual using cloud services, this doesn’t really matter. You’ll choose the components that help you deliver software best, and go with it.

Where this gets interesting is in the enterprise. You’ve got many distinct business units, lots of existing technology in use, and different approaches to using cloud computing. Done poorly, your cloud environment stands to be less secure, harder to maintain, and more chaotic than anything you have today. Done well, your cloud environment will accelerate time-to-market and lower your infrastructure costs so that you can spend more time building software your customers love.

My advice? Decide on your tenancy model up-front, and purposely limit your choices.

In the public cloud, you can separate user pools (“tenants”) in at least three different ways:

  1. Everyone in one account. Some companies start this way, and use role-based access or other in-account mechanisms (e.g. resource groups) to silo individual groups or apps. On the positive side, this model is easier to audit and developers can easily share access to services. Challenges here include a bigger blast radius for mistakes, and greater likelihood of broad processes (e.g. provisioning or policy changes) that slow individuals down.
  2. Separate-but-equal sub accounts. I’ve seen some large companies use child accounts or subscriptions for each individual tenant. Each tenant’s account is set up in the same way, with access to the same services. Every tenant owns their own resources, but they operate a standard “platform.” On the plus side, this makes it easier to troubleshoot problems across the org, and enforce a consistent security profile. It also makes engineer rotation easier, since each team has the same stack. On the downside, this model doesn’t account for unique needs of each team and may force suboptimal tech choices in the name of consistency.
  3. Independent sub accounts. A few weeks ago, I watched my friend Brian Chambers explain that each of 30 software teams at Chick-fil-A has their own AWS account, with a recommended configuration that tenants can use, modify, or ignore. Here, every tenant can do their own thing. One of the benefits is that each group can cater their platform to their needs. If a team wants to go entirely serverless, awesome. Another may be all in on Kubernetes. The downside of this model is that you can’t centralize things like security patching, and you can end up with snowflake environments that increase your costs over time.

Finally, it’s wise to purposely limit choices. I wrote about this topic last month. Facing too many choices can paralyze you, and all that choice adds only incremental benefits. For mature categories like databases, pick two and stop there. If it’s an emerging space, offer more freedom until commoditization happens. Give your teams some freedom to build their platform on the public cloud, but put some guardrails in place.