Just a note before kicking off: If you are comfortable with VSCode ,Github, installation of PS modules and connecting to Azure via PowerShell I would advise skimming the Getting Started section, cloning the working source code from here, and picking up from section 4. If you are not that confident it is worth grabbing a coffee and working through each section in sequence. Its a long one but I hope as a reader you get some value out of the detail.
Introduction
Over the last couple of months I have been getting to grips with Windows Package Manager (aka Winget).
It faces a far more challenging application landscape than its Linux based counterparts, and while it is still a little immature as a technology, it has a lot of potential. I believe it is the future of application deployment and management on Windows and I hope that it gets the attention and adoption that it deserves.
If you have no idea what Winget is I would recommend having a read of two earlier articles I have covered on the topic as this one will be a little more technical.
- An Introduction to Windows Package Manager (aka Winget)
- An Introduction to Winget Private Repositories
As I mentioned in a previous post if you are considering introducing Winget to your environment you may face governance issues (control over the software distribution process), or technical limitation (compatibility problems with specific enterprise software or systems) In these scenarios you may want to consider hosting a private Winget repository to address those challenges.
The good news is that there is a project that provides a reference implementation for creating a REST based private package source for the Winget client. Details can be found here.
The bad news is that it can be a bit of a challenge to get everything set up without a bit of troubleshooting. For those interested in the nuts and bolts: the issue log provided by a helpful, since deleted Gihub account covers the highlights with the summary below:
- Errors are widely suppressed making it non-obvious why things might not be working
- Errors that are not suppressed have little context into what’s failing and why
- Template files are missing from the expected default path, and the build process does not copy them to the expected path
- Azure Functions .zip file is not in the expected default path, and the build process does not create it
- Parameter generation is missing expected values for the Azure Function template
- ASP template is missing entirely which blocks the script from completing successfully
- KeyVault creation keys only off the -Name parameter value which may conflict globally
Note: The Functions .zip file issue caught me out when completing this write up, I have left the troubleshooting steps in rather than fixing in place as I felt it would be useful to assisit in understanding how the deployment works
I like to think I am a reasonably competent but this particular challenge found those skills wanting. Luckily I was able to find some backup!
Every story needs a hero this role was filled by Gunnar Óttarsson founder and CTO of Well Advised, Gunnar and his team know Azure inside out, I learned so much working with him and if you need an Azure Infrastructure and Dev-Ops experts I could not recommend them enough.
It is Gunnar’s fork of the project that addressed the most of the previously listed challenges that I am using for this walk through and all credit goes to him for helping me to get up and running.
I would also highly recommend having a read of Léon Bouquiet’s blog on the same subject, this was the best write up I have found outside of the project’s Github notes and really helped my understanding of how it all hangs together.
Getting Started
What are we Installing?
A Winget Private Repository consists of a number of Azure hosted components and the (optional) vendor source download location.
App Service Plan | A hosting plan that defines a set of resources available for web apps, APIs, and background jobs |
Application Insights | Collects various telemetry data from the app, such as request rates, response times, failure rates, dependencies (like databases and external services your app relies on), this will give you “insight” into issues with your Winget Repository |
Azure Functions | A serverless computing service that allows us to execute small bits of code, or “functions,” in response to various types of events such including HTTP requests to make REST API calls to read, update, create and delete entries on your Winget Repository |
Azure Cosmos DB | A fully managed NoSQL database service used to host your private Winget Repository application manifest data |
Key Vault | Centralizes the storage of application secrets, allowing you to control their distribution. Used in this instance |
Storage Account | Contains all storage data objects: blobs, files, queues, tables, and disks necessary for the operation of your Winget Repository |
There are two additional components to be aware of that are not part of the actual deployment of which you are likely to use when levering Winget to install from a Private Repository.
Storage Account | A separate storage account that Contains the storage data object(s): blobs or files that you may use to host application sources internally that your Winget Repository can reference for download |
Vendor Hosted Source | External Download Location that a 3rd party vendor may use to host application sources your Winget Repository can reference for download |