Any time I discuss more advanced Azure topics, I always have a few people that reach out to learn how to get started with Azure. I definitely understand. The platform has lots of choices and offers, and it can be very overwhelming. For some, it creates cognitive overload and overwhelms them. It’s a lot.
There are too many options and it’s too much to learn! How do I get started? How did you do it?
Building a learning roadmap may seem complex and challenging, but we can apply the same basic principles we use for developing a project: small, iterative cycles.
How I got started
In truth, I got lucky. When Azure started, it was just a handful of core services. It was not nearly as well integrated as it is today, and the DevOps story was far more painful. There were a few core services provided by Microsoft on “Windows Azure”:
- Azure SQL Database
- A managed database service which measured its performance in DTU (Database Transaction Units), a blend of CPU, memory, and storage performance that are purchased together.
- Azure Cloud Services
- A Windows Server virtual machine whose operating system was managed and updated by Microsoft. This was divided into two roles: Web and Worker. The Web Role exposed an HTTP(s) application using a fully configurable instance of IIS (Internet Information Server). The Worker Role was intended for processes or applications that did not utilize IIS. For many years, these formed the infrastructure behind Azure App Services. Although you could remote into the instances for troubleshooting, they utilized idempotent packages which were unpacked and configured each time the VM was replaced or restarted. You needed at least two instances to ensure availability.
- Azure Storage
- Provided block and page blob storage, storage-based queues, and tables (key-value NoSQL data storage).
- Azure Service Bus
- An enterprise-grade message broker, queue, and relay service. It supported ordered messaging, peeking, dead-lettering, and transactions.
- Azure Virtual Machines
- Added later, this provided a more configurable virtual machine experience.
- Azure Active Directory
- Provided a modern cloud-scale identity provider.
As you can see, there was a lot less to know! Instead, you focused on mastering these building block services (along with some design patterns for scaling). Architecture books from this time period often covered these services and patterns in depth. In fact, I highly recommend the older Microsoft certification guides from this time period! Some of the patterns – such as sharding messages across multiple Service Bus instances – would later become their own managed services (in this case, Event Hub).
Fun fact – because these services predated the rise of Kubernetes, Microsoft build its own orchestrator service called “Service Fabric”. Similar to Kubernetes, it ran across multiple VMs and helped ensure availability. Azure SQL (and many others) were built on top of this framework.
The rise of ARM
The legacy services were built on a framework called Azure Service Manager. It was a surprisingly good v1 release, but it had a large number of limitations. The Azure portal was originally Silverlight-based, constructed as a series of plugins that downloaded for each service.
Recognizing the limitations, Microsoft revised the architecture:
- A modern web frontend (codenamed Ibiza) using Vue.js and “micro-frontends”. Each team owned a single-page application (SPA) UI, and the portal dynamically integrated approved applications.
- A standardized REST-based interface for deploying and managing services. These are coordinated together by the Azure Resource Manager, which is responsible for orchestrating requests to multiple resources. Yes, I’m oversimplifying this. 😄
- An API-first driven model that relied on the REST endpoints.
- A JSON format which encapsulated the key parts of the REST calls for creating resources (“ARM Templates”). This enabled infrastructure-as-code deployments.
To understand why my experience was important, there’s a few important things to understand about Azure:
- The modern Azure services are all built using the same infrastructure, the core (“Ring 0”) services. This includes the services above and Azure Cosmos DB. Generally speaking, most services are not “bare-metal” deployments.
- Each service is often a different team, and some of those teams are surprisingly small. Which ones? You can sometimes gauge this by how often they can release new features.
- Azure service teams have access to deploy the SPA frontend and REST endpoints using Azure’s DNS namespaces. This is what makes them “first party” services. Beyond that, they are just Azure applications built on top of core Azure services.
- Each service team must provide a value (and generally return a profit) in order to justify their existence. That means they must be solving a specific customer pain point or providing a specific value.
- Each team pays for licenses and services just like you. Windows isn’t free, and neither are the Azure Services. As a result, their decisions are similar to ones you and your company would face.
Taken together, this means that every other service is built on one or more of the Ring 0 services. Aside from the ability to get whitelisted into the domain services, the additional services are designed to provide platform-as-a-service (PaaS) offerings or to tackle specific issues at cloud scale. For example:
- Azure SQL Data Warehouse (now Synapse) was originally built on top of a collection of Azure SQL Database instances. How do you know? The documentation detailed how many DTU’s a given size provided.
- Azure App Services originated on top of Worker Roles. You could see this in Application Insights – each instance name started with “RD” (Red Dog, the original code name for Azure) and a hexadecimal sequence. Cloud Services (roles) were the only services that followed that pattern.
- Azure AD B2C was build using Azure Active Directory as an implementation detail and backend. This is documented.
In short, understanding those original core services means that you automatically understand more about how these service offerings work. It also makes it easier to understand some of their limitations.
Given all of that, I recommend first understanding the core services and their features. By understanding the underlying features that support other services, it makes Azure easier to understand. You can also identify limitations that may not be fully documented.
Next, understand the specific problem the new service was trying to solve. Most services are very good at providing a solution to a specific scenario, while being less than ideal for other situations. For example, Azure SQL Hyperscale is outstanding for querying and working with large datasets with high concurrency. It’s far less performant in analyzing or querying a data lake. By comparison, Azure Synapse is designed to convert files on the lake into queryable tables; it trades off support for high query concurrency to achieve this. Understanding the problem the service is solving makes it easier to identify when to use the service.
Keep it simple
As a final thought, our end goal with most cloud systems is simple: achieve resiliency and scale with the least possible effort. You often gain an economy of scale (and reduced management) by building on top of PaaS offerings. There are many complex architectures documented that utilize lots of Azure services together. For example, the Modern Data Warehouse (MDW) pattern. Just because you can do it doesn’t mean you should!
Remember the saying, “everything should be as simple as it can be, but not simpler.” In essence, find the simplest architecture which requires the least work to maintain while meeting your service-level objectives. If you have a website with 1,000 concurrent users, a simple Azure App Service and Azure SQL Database may support both transactional workloads and reporting adequately. A full MDW implementation would be expensive (and overkill). A simple database already does quite a bit to separate overlapping reads and writes!
As you add services, you add complexity and increase costs. In addition, each new service creates a potential point of failure that must be considered. As you discover problems meeting service objectives, then it may make sense to evolve the architecture and use additional services. For example, if you’re deploying to VMs, you may be seeing higher costs. Moving to Azure Functions, Azure Containers, or App Services may make deployments simpler and lower operating costs. As the user loads increase, architectures that support higher concurrency may be needed. Keep the solution as simple as possible and add these services as they are needed.
So, simply put, keep it simple and focus on the basics. Start with mastering the core services (along with Azure App Services, then Functions). From there, pick one service that might support your future needs and understand:
- What core services could they be using?
- What problem was the service designed to solve (how was it intended to be used)?
- What are the limitations of the service?
- How is the service different from other services you’ve learned about?
- Does the service enable a new design pattern?
Over time, you’ll build a broad understanding of the platform. Along the way, you’ll begin to see the architectural patterns used by those teams (especially the single responsibility principle). Before you know it, you’ll have a deep knowledge of Azure.