dumpster.town existence
Posts About
by awt

The preamble or, why I’m even bothering to whine about Azure

I somewhat recently gained the interest to begin working on this site again. In my initial attempts to begin writing a blog I decided that I’d like to try out Azure as I have experience working with AWS from my job and decided that it was time that I give Azure a fair shake, after having dismissed the entirety of this “Cloud” bullshit as stupid originally. So in this endeavor I researched what it would take to host a static website on Azure (since I’m not interested in hosting anything with dynamic JavaScript content). These are my findings or nitpicks on the bits of Azure the I ended up interacting with on my journey to misery.

A poor approach to IAM

Azure’s approach to IAM is at the very least, not what I’m used. I’m putting this statement upfront to make my bias clear, I was introduced to a comprehensive IAM system by AWS and it’s at least at this moment the system I prefer. Technically I’ve worked with ACL systems devised for Garry’s Mod admin systems and designed my own for the same purpose, in addition I’m familiar with the Unix filesystem permission model. I’ve also worked with various other systems but my understanding of those I’m not confident enough in to really compare them in a fair way.

Here’s an overview of the Azure authorization model from my perspective. Azure itself is composed of two separate grand services, the Azure resources themselves (or Azure proper as I’ll refer to it) and Azure Active Directory (AD). This split between Azure itself and Azure AD seems to have occurred so that Microsoft could carry over the legacy of their traditional on-prem AD software into the cloud, providing AD as a completely bespoke separate service from Azure proper likely made the sell easier to make.

This is where the complications start, from a newcomer’s perspective this distinction is not obvious and immediately causes confusion. When I started I was under the impression that all authentication and authorization would happen under Azure AD, but it does not. There are Authorizations you can provide through AD itself but it appears to only be related to AD and does not cross into the realm of Azure proper. Azure AD does provide authentication for Azure proper though and that makes the distinction unclear and leads you at least initially to believe that AD would be providing authorization. In actuality Azure only uses the principals provided by AD to identify entities. You use the AD provided principals to tie roles to them, which provide entities the permissions to perform operations. There are a number of predefined roles that Microsoft provides for you by default, covering what seems like a decent number of regular uses-cases.

Initially for me understanding how roles applied to principals was a bit confusing as the application is hierarchal in nature and that wasn’t clear to me from the get go. Azure tiers all of it’s resources like this, starting at the Subscription level into Resources themselves and working it’s way down into the finer and finer grained objects like Storage Containers and more. This make sense to limit access to narrow ranges of resources and operations following the principal of least privilege but falls apart when you find out that not every sub-resource offers IAM controls. The solution to this is to split off this access control into what’s referred to as a Condition, a bespoke DSL to express complex access control situations. This whole interaction is very detached from what the experience should be where every resource can have it’s access limited with the same interface. Azure seems to initially drive you to apply access with it’s hierarchically defined roles since conditions are a part the role itself you cannot get away with using the builtin roles to configure fine grained policies making them useless.

This whole interaction is not as it should be, comparing this to AWS’s IAM the situation is laughable. Within AWS controlling access to sub-resources is as simple as specifying a glob that matches whichever resource you’d like to control access to. Why Microsoft didn’t just adopt a similar scheme is unknown to me.

Within the other systems I’ve used this also compares to be baffling, Unix permissions are available at every level of the file system hierarchy and within the Garry’s Mod systems I’ve used the hierarchy is flattened so that this isn’t even a concern, where generally the scheme is a user is assigned to a group which is a set of authorizations which generally lack controls to limit theses authorizations to particular resources.

A lack of complete documentation

In quite a few places the Azure documentation is either lacking in detail, such as failing to enumerate specific allowable values for a specific field or in some places the it’s stratified in some fashion where important bits are stored away in wordy guides and not left to be within a reference where it would be much easier to parse.

The particular instance of this that I ran into was related to Azure Key Vault, where the input that Key Vault expects for certificates is very particular. I was only able to find one blog post that made any mention of any limitation and that seems to have been from the author’s own experience rather than any knowledge provided by the documentation. This author’s note wasn’t even complete probably because they never encountered the same issue but not only is Key Vault’s input picky it’s also sticky, if one uploads a certificate in PKCS#12 format and then attempts to upload another certificate version formatted another format say PEM you will be given an error in return. Neither limitation as far as I can tell is mentioned in the documentation or even warned about in any guide.

Azure Functions are over-complicated

The minimal configuration of Azure Functions is way beyond what is reasonable. For comparison, since I feel that AWS does it better, Lambda’s only require that you provision one resource, the Lambda itself. In contrast Azure Functions require configuration of multiple resources that initially seems pointlessly complicated.

I’ll admit that I likely made this part of the process a bit more complicated for myself since I didn’t want to use the provided Azure tooling and instead used Terraform to setup all my resources (to keep everything defined in version control). Regardless of that this process sincerely seemed more complicated that it needs to be.

In order to setup a single Azure Function a few resources need to be defined in your Azure subscription, obviously the requisite Azure AD must be available (which it is by default) in addition to at least a single resource group, an app service plan, a storage account, at least one storage container, an application insights instance and finally a “function app”. This is compared to AWS where it requires a single lambda resource and a single IAM role.

Once you have all these things setup properly which I’ll get into, then and only then can you begin to deploy your code to the “function app” instance. This is an ordeal in itself. With Terraform this process is not too difficult, you must package your code in appropriate way for Azure to recognize it, the complication comes from how you must configure it. At least for me it was not clear how one defines where an application’s runtime is stored and what the trade-offs are. There are various limitations to the different “app service plans” that Azure provides and for me the most obvious choice is a NodeJS application on Linux. Although this apparently has it’s limitations.

Once you decide on your pairing of runtime and operating system (which I would argue should not be necessary for a “serverless” application…) you’re free to struggle with the necessary format your “application” must take shape in. If you’re not using the bespoke Azure tooling this is a matter of peeking at examples others have provided. To me it was not initially clear that an Azure Function is actually composed of multiple functions. A limitation that seems very silly to me is the fact that one function entrypoint can only handle one type of input event and that it’s impossible for you to configure this otherwise. In my scenario I wished to have my function run on a daily timer with the possibility to manually trigger events in order to test certain scenarios, and while you can do this with a purely timer triggered function you have no option to specify different input arguments without reconfiguring the function’s environment every time, which to say the least is very inconvenient. The solutions to this is to split your “function app” into multiple separate “functions” which share a common core that gets invoked with a different facade, which while not an all too uncommon pattern in software design seems fairly stupid when the facility is right there to allow input of different event types into a single function handler (just like AWS lambdas).

When I had this ordeal sorted out, iterating on my Azure “Function App” wasn’t all too bad, I’m not personally a big fan of the interface that Microsoft provides, to me it seems slow and bad, but it was functional enough to let me get my task done albeit at a very slow pace compared to what I’m used to. Some of this probably could be mitigated by having tested my code locally but as it was this was not feasible in my case since I was also simultaneously testing Azure IAM that I cannot simulate locally (as far as I’m aware).

Misery

In summary, I’m now miserable and this is permanently irrecoverable.

I’m also not an AWS stan

I also want to point out that I’m not a huge fan of AWS either, while I may prefer some of the AWS environment for some of it’s merits like anything else that exists in this world AWS is imperfect. There are problems hiding in tiny cobweb corners and even more glaring frustrations like the entirety of AWS Cognito Identity Pools and it’s extremely confusing naming. I’m actually not even a big fan of cloud providers in general and find that I prefer not to relinquish control of any of my digital assets if I don’t have to. For this website in particular since it’s essentially just a bunch of plain HTML it’s easy to take my shit and leave so I’m not too concerned over where it’s hosted.

Update - 2023-08-24

As of 2023-08-24 I’ve switched to Netlify which has been a decently pleasant experience so far. As for Azure I would advise against using it for anything that isn’t a large corpo enterprise project. There are far too many rough edges and bizarre design choices to justify hosting a small personal site with Azure.