Infra in Azure for Developers - The Why
Published Jan 03 2024 10:37 AM 2,738 Views
Iron Contributor

A few weeks back I wrote a little getting started intro to infrastructure in Azure aimed at developers, looking at features like Azure Dev Box and Azure Deployment Environments. Regardless of what you think about those Azure services a common question from developers when it comes to infra is "why" - which is what we will look closer at today.

 

Why?Why?

 

Even with all the rage about serverless compute models developers understand why infrastructure is required. Even if it's called the cloud your workload doesn't run in thin air. So it is probably more precise to say it is about "why should I care" or "why should I understand infrastructure". After all a developer is allowed to be all about that code.

 

I mentioned both the Azure Developer CLI and .NET Aspire in my last post as well. Both promising utilities in my opinion and the goal of those seems to be related to the handling of infra for developers. (Aspire is technically primarily an enabler for other parts of the developer experience currently.) Thing is that the demos and samples are somewhat happy-pathing things. I checked out the tutorial for using the Aspire starter app with azd: https://learn.microsoft.com/en-us/dotnet/aspire/deployment/azure/aca-deployment-azd-in-depth?tabs=wi...

 

It works as expected. So, I thought I would take a look at the new eShop reference app: https://github.com/dotnet/eshop.

 

It comes with Aspire "pre-installed". Great!

eShop AspireeShop Aspire

 

Let's deploy it to Azure with azd and see what we get:

eShop azdeShop azd

 

Ehh.. RabbitMQ something? Turns out that RabbitMQ isn't supported in azd alongside the first preview of Aspire.

 

Aspire is in a preview and is being updated - no worries. Same with azd - no worries. And the intent here is not to say these tools should not be used. Most likely it will just take some time before everything is supported the way we want it to be. But without being able to dive into infra bits this leaves you waiting for MS teams to update their templates. Or what if you want to use an alternative to RabbitMQ? Well, that also requires you to understand how to remove or replace the necessary pieces.

 

Infra code

Going back to the Aspire azd Walkthrough. It didn't just do magic behind the scenes - it created fairly clean Bicep for us. Even without studying Bicep in details you are probably able to infer the basics here:

 

 

 

@description('The location used for all deployed resources')
param location string = resourceGroup().location

@description('Tags that will be applied to all resources')
param tags object = {}

var resourceToken = uniqueString(resourceGroup().id)

resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: 'mi-${resourceToken}'
  location: location
  tags: tags
}

resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
  name: replace('acr-${resourceToken}', '-', '')
  location: location
  sku: {
    name: 'Basic'
  }
  tags: tags
}

 

 

 

This is obviously a good thing, but it highlights another piece of the "why". Now, I don't always understand every single line of code if I have some scaffolded css or JavaScript, but I usually understand the gist of it. Correspondingly you should have some sort of understanding of the Bicep code that gets checked in. You can't just bring in secret sauce with no one knowing the recipe.

 

On the topic of black boxes - how do we know this Bicep follows best practices in Azure? I trust I'm not running a Container Registry with anonymous access and web apps over plain http after applying this code. The actual best practices run deeper than that though - so for the fun of it I took a look in the Defender for Cloud dashboard after deploying the solution:

Aspire DefenderAspire Defender

 

This is actually not bad, but as for the recommendations it helps to understand a thing or two about infra before you start closing them. As a tip - if you as a developer proactively start handling these before some security guy points them out to you will gain kudos. Remember - you can't always solve them all, but you need to understand them and explain why you can't fix them if that is the case.

 

Design patterns

If your application relies on sorting mililions of elements you probably know already that bubble sort is a horrible algorithm. And hopefully you have also learned that if you interact with a SQL Server you should re-use the connection instead of "newing up" every time. These are minor implementation details, but some of these techniques evolve into what we call design patterns or architectural styles. For instance it's common to use the Backend for Frontend (BFF) pattern these days to separate the UI and the logic. Or maybe you're implementing a competing consumer pattern for processing events in your app. As a community we have learned over the years and use these to solve common challenges.

 

But have you given thought to the infra-related side to your design patterns? For instance, one of the traits of a microservices based infrastructure is that you will probably see an increase in network traffic compared to a classic monolith. (Since the different services use HTTP or GRPC to communicate between each other instead of some in-memory technique.) Maybe it's not even the different services but a call to an external service bus. Within a cluster this is often not a problem since everything runs on a separate subnet/virtual network depending on your config. When traffic crosses out of the cluster however NAT will often be used. Calls to the service bus - out of cluster. Third-party API - out of cluster. And what happens when you create a ton of connections through NAT? You run out of ports. Is that something a developer usually thinks about? Your network people are probably very familiar with such issues and may even be able to help you if you understand the context good enough to describe what seems to be happening. (Maybe you can even solve it without involving them.)

 

Or how about looking up values through an API? Is there perhaps a throttling mechanism there that puts a limit on what you're trying to do? Maybe a cache could boost the performance? Your code simply does not rely purely on code you produce.

 

Coding challenges solved with infra

This is where things gets interesting. We're used to some programming challenges being compute-bound. Sometimes you need more RAM, or CPU, or both - you just can't optimize your code to run on less hardware even if you are the best code monkey on the block. That's ok - Azure is fairly gentle in that department.

 

There's other kinds of challenges though. How easy is it to switch out components your code relies on? How do you ensure you don't duplicate pieces of code for integration with cloud services? One solution for parts of this problem is Dapr (https://dapr.io). This is not a post on why a concept like Dapr is great or how it works, but thing is - unsurprisingly Dapr needs to be configured to work with your apps. And you know where you can place that? As part of your infra. Understanding how to do this in a good way may improve the code you write and make it easier for you.

 

Networking

Have you ever had a problem where you find yourself wondering why the bits don't travel from A to B like you expect? Of course you have - everyone has run into network issues. If you sit on your phone surfing the web and everything suddenly stops working it's a fair assumption to blame someone else and just wait it out. If your application has problems shuffling the bits back and forth it could be due to you as a developer forgetting something. Oh, you hard-coded an IP address that suddenly changed? Or you rely on some arkane port being open but there's a firewall between you didn't think about.

 

Thing is that networking is hard. As a developer there's things in this area you should not need to know. Configuring an ExpressRoute connection has a different target audience than developers. Far too often I see devs and infra people agree that it might be a networking problem while not agreeing on whose end the problem lies. Disregarding problems for a moment - if a service you want to use has a prereq for a /24 subnet - is that a foreign language or something you can translate into an IP range? Basic understanding of networking can make things easier.

 

These are just a few examples of why developers should care about the infrastructure and invest some time in understanding it. To be clear - I am not saying developers should read up on every infra detail in Azure. It is perfectly fine do have someone else set up a hub and spoke network infra. It is perfectly fine to have someone else curate virtual machine templates that align with your organization's security policies. And it is entirely acceptable that not every developer on the team knows the intricacies of external ingress in Kubernetes. After all - developers need time for doing actual coding as well.

 

That being said - since I gave examples of "why" here it is only fair that I follow up with the what and how :smile: Keep watching this space for the next installment.

Co-Authors
Version history
Last update:
‎Jan 03 2024 10:38 AM
Updated by: