How I was able to automate my Development Environment on Azure
As a Software Developer/Engineer, I am constantly having the need to install or update various development tools and dependencies on my work or personal laptop. Every so often, my development environment would get messed up as a result of installing or updating something, or my environment would get bogged down at some point. Whenever that happens, after several minutes of cursing and groaning, I would proceed to waste several minutes, hours, or sometimes days trying to recover from it. I am sure this is not a unique story for anyone who is in this business, and I often wondered if there’s a better way.
How about backing up my state and rolling back whenever something unfortunate happens? Well, I feel I am just going to be overwhelm for doing something like that. In my mind, I start to envision the possibility of treating my own development environment just like how I treat all other environments on the cloud. Maybe I should just be able to throw away my old development environment and start with a fresh copy, a copy that is already configured to my likings? It would be as-if I have a fresh laptop whenever something bad happens or if I need to experiment with something new and I can just spin up a new environment for the time being and tear it down when I am done.
In fact, this idea is not so uncommon these days. Due to Covid, many people are starting to find themselves working from home, and organizations have started providing Windows Virtual Desktop to their employees as a solution. Behind the scene, it is another Virtual Machine(s) running. In my case, I am just going to create a Virtual Machine on Azure as I already have a Subscription. Here, I will describe how I came about with a personal solution.
ARM Template to create resources in my environment
As someone who has been working on the .NET Stack with Visual Studio and on the Windows platform, I can just pull an existing image from the Marketplace. A quick search revealed that we can choose between the Enterprise version or Community version of Visual Studio 2019.
I can simply pass in the image reference into a ARM Template which will create the Virtual Machine for me. I would also list all requirements in the ARM Template.
The ARM Template would contain my Virtual Network, Subnets, Virtual Machine Network Interface (NIC), Public IP on the NIC, Network Security Group (NSG) to apply to the Subnet where my VM resides. My NSG will only allow RDP from my network IP. I know this isn’t the most secure design, but for the purpose of my own environment, this is sufficient. If you are interested in a more secure approach, consider adding Azure Bastion.
My Virtual Machine is configured with antimalware and for cost savings purposes, I have applied a shut down schedule. Notice the 2 parameters, shutdownTimeZoneId and shutdownTime which allows you to specify your own shutdown parameters.
I am using Azure Key Vault for storing my VM login password. When creating the Azure Key Vault, I am also applying access policy so that only I can access the VM login password/ secret. Notice that I am giving myself only list, get and set permissions. This allows only my user to access to the Azure Key Vault.
The ObjectId is your Azure Active Directory user specific object Id. The following is a code snippet to get your ObjectId.
$objectId = ((az ad user list --upn (az account list | ConvertFrom-Json).user[0].name) | ConvertFrom-Json).objectId
The Azure Storage account is also created as a way to store the Powershell scripts and other files that are executed on the Virtual Machine. Take a look at the next section for more information.
I would create all my resources within a single resource group which means if I need to throw away my development environment, I can just remove the resource group itself.
Custom Script Extensions and Choco to setup my environment
Next, I need to make sure I can manage i.e. install dependent tools on the Virtual Machine. There are many approaches but one that I have used in the past is using Choco, a free Package Manager for Windows. Every software package I need is available with Choco including Docker Desktop, Azure CLI, Azure Powershell etc. With Custom Script Extension for Windows, I can install Choco with a one-liner Powershell command, and then use Choco to install the rest of the dependencies.
The following code snippet shows the command to run custom script extension. You can upload your PowerShell scripts and other files which you wish to drop into the Virtual Machine into Azure Blob Storage. The Custom Script Extension will download those files and as specified in the Powershell command, it will execute the specified Powershell script. You can assume all files downloaed to be in the same directory as where the command is executed.
Lastly, there are some configurations that apply on the user profile level (which is created when you are first logged in). For that, I can simply create a start up script that will apply the user profile specific settings, such as desktop shortcuts, and even Powershell Execution Policy. I am also interested in using alias. For example, to perform terraform, I would like to use the “tf” alias. This is applied using the $Profile environment variable which specific the location of every Powershell session script location.
Wrapping up
The full source code can be found on https://github.com/seekdavidlee/eklee-dev-env. If you are trying this out, please be sure you are the Owner of the Subscription because you need to have the ability to create a resource group at will and assign permissions to yourself.
The main script is the Deploy.ps1 script. Here’s my command for creating my own development environment. StackName is nothing more than just a name for your Dev environment. My naming convention is such that I could have a suffix in case I need to create more Dev environments. This command can be executed from CloudShell. If you intend to run it locally, be sure to have Azure CLI 2.16 installed. At the time of writing, there’s an issue with the latest version of Azure CLI 2.17.
./Deploy.ps1 -StackName ekleedev02 -UseVisualStudioCommunity
When you login for the first time, you will be prompted to login so that your Azure credentials can be persisted. Docker Desktop will also be started automatically. When you start a new Powershell session, 2 alias will also be configured for you: Terraform as “tf” and Kubectl and “k”.
I hope you have enjoyed reading this article and learned something new today.