I must admit that I wasn’t a big fan of Nerdio. My opinion was that everybody must learn IAC (Infrastructure as code). The simple truth is that is never going to happen. And that’s why Nerdio is so successful. So, after I visited a Nerdio workshop I decided I am going to deploy Nerdio from an IAC perspective and write a blog series about it.
I will still stay true to my beliefs that I think the best method of deployment is via Rest API. So, I have already deployed my whole AVD (Azure Virtual Desktop) environment via Bicep. For this series I am going to pretend that I must hand the environment over to system administrator who are going to use Nerdio. The goal is to configure Nerdio completely via Rest API. So, when I must do it again, I just run a script and Nerdio is configured.
Why, you might ask. Well, not every system administrator is keen on developing their own Rest API methods to deploy and maintain everything as code. Deploying everything as code and then handing over the Nerdio console to system administrators might be a good compromise. The system administrator can still maintain the environment and you are happy because everything is deployed as code.
Other parts of this series:
Deploy Nerdio from an IAC perspective (Introduction)
Link all required resources to Nerdio
Create an Image in Nerdio using PSNerdio
Enrich the image with Scripted Actions, Applications, and Schedules
Deploy dynamic hostpools using code
Deploy Nerdio
Firstly, we must deploy Nerdio. They published a deployment guide that I am simply going to follow. The goal is to only deploy Nerdio. The configuration that is needed afterwards must be done by using the Nerdio Rest API. This configuration entails importing the VNet for example.
The deployment is really straightforward, but I had to run it multiple times due to capacity issues in the West Europe region.
Also, I had to run it multiple times in North Europe also. Because of that the keyvault deployment failed:

The keyvault name was not unique. That is something Nerdio should change in their marketplace template . The “unique” name is not so unique. The problem is that if I recreate a resourcegroup with the same name as the previous deployment. The keyvault name that Nerdio deploys stays the same. Therefore, it is not unique. That is easily solvable in their deployment.
After that, I decided to delete everything again and purge the keyvault also. I want the deployment to complete fully to make sure I have everything I need to run Nerdio. The next deployment succeeded and I only needed to configure Nerdio after that.
I love that Nerdio provides a script to configure it all. It makes it all very easy to deploy:

When the configuration script completes and you refresh the URL pointing to Nerdio Manager for Enterprise, you see the following window:

I first only wanted to select the Azure Virtual Desktop checkbox but it’s also required to select a directory. I selected Entra ID.
After that, I only had to consent to the permissions manually via Entra ID. Hopefully Nerdio can automate that also. There is an API endpoint for that and if you are logged on with the appropriate permissions they should be able to do so.
Lastly, I only needed a license and Nerdio has community program. You can reach out to Nerdio to get a community license. Follow this: link.
Configure Nerdio using Rest API
My first task is to get my already deployed Azure Virtual Desktop workspaces added to Nerdio via code obviously. So, let’s figure that one out. We first must enable the Rest API interface of Nerdio. Nerdio has nicely documented this. You can find that here.
After it is activated, you can find the documentation here:

And they have documented everything in Swagger with examples, great! Let’s start with a easy one, linked resource groups:

We want to link our resource groups to Nerdio that holds our AVD workspaces, hostpools, and application groups.
At first I thought that I’m going to write a PowerShell module for this API but as I looked further in the documentation I saw that Nerdio already wrote a PowerShell module. And that holds already 462 commands:

That’s great! Love to see that. But, we first must authenticate before we can configuring the resource group.
Authenticate to Nerdio’s API
So, let’s check out that module. First things first. Authentication, let’s see how Nerdio does it.
The authentication function sits in this file(1):

It’s called “Connect-Nme”(2) and you can only use a secret to authenticate. I don’t like that. It would be better if this used a certificate. And, it also would be nice if there is an option to authenticate interactively. That will be very helpful for system administrators
Also, the documentation uses screenshots from the old UI. They will probably update this when the new UI is default but I wanted to note it.
Last point to be made is that the PowerShell function doesn’t follow best practises. Examples of that are; multiple functions in a file and no synopsis or examples. It would be nice if they followed the sampler example for PowerShell Modules. Robert Prüst wrote about it.
On line 15 you see that another function is called to set the authentication headers (Set-NmeAuthheaders) that set these variables as the authentication headers(1, 2):

At 3 you can see they just use Entra ID to authenticate. I do like that. 🙂
I looked at the permissions of the Enterprise App created by Nerdio and it has only application permissions. So, no option to authenticate interactively.

So, we just use the authentication function that is available that is secret based and mention in the documentation.
I couldn’t get this to work:

It’s successfully getting an access token as you can see in the verbose messages but it can’t complete the Test-NmeApi function:

And… I can’t really figure out why.
I am using a Mac though. So, I thought, let’s try it on Windows. And it just works:

Next, I also tried PowerShell 7 on Windows. Let’s check whether that works:

After that I thought let’s break it down some more. Let’s make the authentication really simple and let it run:

As you can see on the left hand side is the MacOS machine authenticating and getting blocked on the test api because the authentication is invalid. On the right hand side is the Windows machine doing the exact same thing and it works. Is unix as a platform getting blocked on this API or? This is weird.
It’s also not Conditional Access:

Because it is not applicable.
And both authentication requests where successful:

I think this has something to do with the API. Hopefully Nerdio can fix it.
Postman on Mac does work and if I use that access token in PowerShell it breaks again.
Link Resource Groups to Nerdio
Let’s finally link the resource group! I hear you shouting! I will perform this task on my Windows VM because I simply can’t do the API requests on my Mac somehow….
So, I just connected using Connect-Nme and after that I ran this command to link the resource groups:
New-NmeLinkedResourceGroup -SubscriptionId "dd5a4399-3766-4520-9659-b6a98bf6ba8a" -ResourceGroup "rg-infra-avd-dev-vdpool" -NmeLinkResourceGroupRequest "NmeLinkResourceGroupRequest"
And, I got this result:

I was already wondering about the “NewLinkResourceGroupRequest” parameter requesting an object since the only reference for the Github repository was the synopsis for New-NmeLinkedResourceGroup?

And the swagger documentation from Nerdio doesn’t mention it also:

Only a subscription and resource group are required?
So, I created my own Rest API request in PowerShell to get it to work:
$nerdiourl = "https://YOURNERDIOURL.azurewebsites.net"
$subscriptionid = "dd5a4399-3766-4520-9659-b6a98bf6ba8a"
$resourcegroupname = "rg-infra-avd-dev-vdpool"
$body = @"
{
"isDefault": false
}
"@
# Make the API request
$response = Invoke-RestMethod -Method Post `
-Uri "$($nerdiourl)/api/v1/resourcegroup/$($subscriptionid)/$($resourcegroupname)/linked" `
-Headers @{ "Authorization" = "Bearer $accessToken" } `
-ContentType 'application/json' `
-Body $body
$response
(I used the authentication request you saw earlier when I compared Mac running PowerShell 7 to Windows running PowerShell 7.
This was the result in PowerShell:

That worked! The resource group is linked:

And lastly, it sees my AVD workspace:

I still need to assign it, that is why there is an exclamation mark but that is for a different day. As you can imagine, the troubleshooting took some of my time today.
Conclusion
Nerdio is really making an effort to let you use their API to configure the Nerdio Environment. The documentation is great and Swagger even let’s you do the API request so you know exactly what to do to create the Rest API request in PowerShell for example.
The PowerShell module needs some love though. I might write it myself in this series. If they will fix my issue I’m having using the API on my Mac in PowerShell.
I think the most important thing is that I have shown that configuring Nerdio via Rest API is completely possible. You can deploy everything via Infra as Code (Bicep/Terraform). Import everything into Nerdio and hand it over to the system administrators. That will be the goal of the series.
Thanks! See you in the next one!