One of the things that they never discussed during my courses was the importance of debugging, error logging and how to drill down through those errors. No one seemed to mention that some guides that I would later on read as a developer, might make assumptions regarding my knowledge, the setup I had already completed and the completeness of my background knowledge.
I started as a .NET dev about a year ago while still studying for my university degree. It was strange as I had some .NET experience from way back when, but in school, I only used Java, Processing and Python. The largest projects I tackled in .NET were simple console apps that would solve some algorithm or print some text to the screen.
As such, the last year or so has been a full on deep dive in to the topic and I learned a lot. Each time I thought “this will now complete my knowledge”, I’d get slapped straight in my stupid face. And I deserved it. You can’t know everything. That’s a given. What I didn’t know though is that there will be gaps in knowledge in documentation, in notes and even in official guidance. What school never prepared me for was the amount of work I’d do debugging code and no one taught me how to either.
The thing that prompted this post is the long struggle I had going through the setup of Managed Identities for a project I’ve been working on. This post Managed Identities for Azure Resources shows the world of possibilities for managed identities. It all looks great - no need to store user secrets, no passwords, no strange connection strings - just Azure Active Directory and you’re golden.
Let me start off by saying that yes, Managed Identities (MI) can be great if you get it setup and running, but when you’re working with this for the first time, when you have no clue how authentication works on a project, when you have no clue how MI is implemented in the rest of the project and most importantly, when you do not have admin rights to managing the Azure resources you’re supposed to work with, things become extremely complex, extremely fast.
To provide an overview, something I did not get when starting this, MI eliminates the need for username and password inside connection strings for example. Please keep in mind that this discussion focuses on Azure SQL Server and accessing apps that run as Azure App Services. MI can be used to manage all kinds of resources, but my experience was limited to the above.
With that out of the way, let’s say your project connects to a database and your connection string might look like this "Server=tcp:.database.windows.net,1433;Database=;User Id=;Password=;"
.
Of course, you can set the username and password up as User Secrets for your project, meaning they won’t show in your appsettings.json file, but MI removes even that need. Your string will be "Server=tcp:.database.windows.net,1433;Database=;"
.
This is achieved through the use of Azure Active Directory (AD). Azure AD will look up the identity for a given resource and check if that identity is supposed to have access to the Azure SQL Server. To give you a basic idea of the setup, you can provide a MI to your Azure VM. This creates an entry in Azure AD with the exact name of your VM - for example “bob-vm1”.
The next step is to give this resource access to your Azure SQL Server and the database you have running here. You can create an Azure SQL Server and add a database to this easily by following this guide. With the server setup, you can now go to ‘Active Directory Admin’ and set an admin for this server. This account here will be used to connect to the SQL Server using SQL Server Management Studio for example, and create the user that will access this database.
These two guides should help you both setup the SQL server, setup your VM and connect to the server from your VM with a connection string that only contains the server address and the initial catalog or the initial database name. All seems simple right?
Except it wasn’t in my case. I didn’t have rights to add users on the database I had to work with, so it took time to figure that out and gain access. I didn’t know I could assign an MI to my VM, so it took time to figure that out, add my VM identity to the DB and try again. I didn’t know that Azure SQL Server will block any connections unless the IP from which the connection is coming is Whitelisted, so I had to do that and try again. I didn’t know that you could actually have two resources with the same name on Azure AD, which means that you CANNOT add a user to the DB unless one of the users is renamed or deleted. So I had to do that to add the app services to the DB user list and lastly, I forgot (again) that I need to whitelist the app service IP to allow this connection to occur.
Within all of this I haven’t yet spoken about debugging and I won’t in this post, but I will come back and wrap that up as well… I hope that by this point you managed to get an idea of what MI is, how to set it up locally on a small VM with a small DB and how to get that connection going. Next up, I will make some time and discuss debugging your deployed app since no one ever told me or gave me guidance so hopefully this will save someone some time in the future!