It's reading notes time! It is a habit I started a long time ago, where I share a list of all the articles, blog posts, and books that catch my interest during the week.
You also read something you liked? Share it!
Cloud
It's Finally Possible To Hibernate Azure VMs (Sam Cogan) - This new feature must be such a relief for all the VM users. Make sure to read this post to know the requirements of the VM tone able to hibernate it.
It is time to share new reading notes. It is a habit I started a long time ago where I share a list of all the articles, blog posts, and books that catch my interest during the week.
If you think you may have interesting content, share it!
Host WordPress in Microsoft Azure with App Service (PaaS hosting) (Chris Pietschmann ) - When we are interested in WordPress, we are looking for a key in-hand experience. We don't want to manage code and connections and too much technical stuff. Having it hosted in PaaS Azure simplifies even more this.
Dapr 1.10 - More steps in the right direction (Mark Heath) - This is great! I'm happy to see the multi-app functionality as I was totally waiting for it. And the workflow is definitely something that interests me.
Good Monday, time to share my reading notes. Those are a curated list of all the articles, blog posts, podcast episodes, and books that caught my interest during the week and that I found interesting. It's a mix of the actuality and what I consumed.
If you think you may have interesting content, share it!
Cloud
Setup the Auto-shutdown on VM using Bicep template (Massimo Bonanni) - VMs are so useful. One of the best ways to save money is to turn them off when you are not using them. Part 6 about Bicep explains how to do it in your IaC script.
Good Monday, time to share my reading notes. Those are a curated list of all the articles, blog posts, podcast episodes, and books that caught my interest during the week and that I found interesting. It's a mix of the actuality and what I consumed.
You think you may have interesting content, share it!
Azure Virtual Machines vs App Services (Michael Shpilt) - The pros and cons of both are listed in this post with some advice. Everything you need to help you to make your choice.
Good Monday, Already time to share new reading notes. Here is a list of all the articles, and blog posts that catch my interest during the week.
If you think you may have interesting content, share it!
Suggestion of the week
How Cloudflare Broke My Build and How I Fixed It (Giorgi Dalakishvili) - Wow! That was a hard one. Like searching for a needle in a haystack. Those stories are incredibly useful as they teach how to investigate issues. Thank you so much for sharing it.
Blazor Binding, Events and Parameters (Michael Washington) - A very complete tutorial that explains it all. The complexity of the example is incremental, meaning that if it's your first contact with Blazor the bites will be just the right size all along.
Fluent UI Insights EP2: Styling (Paul Gildea) - Really interesting second episode of Fluent UI Insights. A series of video that explains the design decisions.
Windows Package Manager 1.3 (Demitrius Nelon) - Very happy to see Winget getting more apps and new features.
Podcasts
316: Hosting Websites & Web Apps for Free (Merge Conflict) - Who doesn't like getting a free website? Learn more about the option available for you in this episode. And also, why you shouldn't operate your drone on water.
Épisode 19 - Les Olympiques d'Hitler (Les Pires Moments de l'Histoire) - (In French) I love this podcast you learn stuff and for sure you will at least smile if not laugh.
Daniel Roth: Blazor Futures - Episode 204 (Azure DevOps Podcast) - Perfect episode to learn what is currently in trial, plan to be and what will stay for sure in the next release.
Already time to share new reading notes.
It is a habit I started a long time ago where I share a list of all the articles, blog posts, podcast episodes, and books that catch my interest during the week.
You think you may have interesting content, share it!
CRUD operations on PostgreSQL using C# and Npgsql (Davide Bellone) - This post is a very good tutorial about how to make a simple query with all the code and explanation required for a great start.
How to get the optimal image size for web (Joel Hans) - So many options are possible. This post explains the impacts of different contexts and provides guidance on how we could improve, or what we should look at.
Podcasts
Ximena Vengoechea On How To Hear What Really Matters (What's Essential) - Very interesting conversation. Ximena is the author of the book Listen Like You Mean It. Well... It's just get added to my to-read list.
Languishing? Here’s How to Turn it Around (Modern Mentor) - There is a name for feeling "meh"! And there are also things we can do to feel better. Very captivating, and now I want to learn more about it.
My True Crime Episode with David Mittelman (A Bit of Optimism) - When I saw the title of the episode I was a bit confused... True Crime? WHat's the connection? But it was fascinating, so much passion!
Windows Terminal Preview 1.13 Release - Windows Command Line (Kayla Cinnamon) - Amazing post, yes we learn about the new features, but we also read about the learning and experimentation of this team and collaborators involvement. Great work.
Create a Windows 10 development virtual machine (Thomas Maurer) - Great tutorial to create a dev environment.So useful when we need to create a specific context or use a different version to investigate client issues.
Visual Studio 2022 (Amanda Silver) - I'm always impressed by how new features are continuously added to VS. Such a great tool.
Miscellaneous
Why you should never quit too early ... (Donn Felker) - An inspiring post to help us persevere and time is hard. But also to try to step aside and have an open mindset.
Every Monday, I share my "reading notes". This is a curated list of all the articles, blog posts, and books that catch my interest during the week and that I found interesting. It's a mix of the actuality and what I consumed.
Game Jam Lessons Learned (Coding Blocks) - Very happy the listen to this follow episode from show 151. I've been tenting to try participating in a Game Jam. Really interesting to learn their experience and how they would do differently.
Fix for Elgato Key Light not found by Control Center (Scott Hanselman) - Sorry, but I feel happy to not be alone with those thoughts, and in that situation. My Keylight is now optional in my setup because when I need a light NOW, I don't have time to figure out issues.
Every Monday, I share my "reading notes". Those are a curated list of all the articles, blog posts, podcast episodes, and books that catch my interest during the week and that I found interesting. It's a mix of the actuality and what I consumed.
You think you may have interesting content, share it!
Cloud
2 Local machines 1 Dev VM (John Friesen) - A nice tutorial that can help us get started and understand how things work.
How to Create a Social Media Plan Template with Andrea Jones (Influencer Entrepreneurs with Jenny Melrose) - They say planning is everything, so I was happy to listen to this episode and learn more it and see if it was different depending on the platform.
Cycling Through Changes with Laura King (Wild Ideas Worth Living) - I'm a man and my "baby" is an adult now. Yet, I found that episode very interesting. Even though a lot of friends shared with me a few "challenges" that pregnancy brings... And didn't think about the training ones...
- I really like this book. In a world where we all try to get more things done to be more productive, this book talks about doing less... to be more productive. Very interesting I thought. Talking about priorities, and how to help you to find our focus.
Every Monday, I share my "reading notes". Those are the articles, blog posts, podcast episodes, and books that catch my interest during the week and that I found interesting. It's a mix of the actuality and what I consumed.
Blazor by Example - A dismissable banner (Jon Hilton) - A really interesting post that explains how to build a webpage by showing it by iterations. If you know me, you know those are my favorite.
0240 - Anthony Giretti - Le protocole gRPC (Visual Studio Talk Show) - Nice episode where they talk about gRPC and gRPC web, where it comes from, why it's different than the previous version, and how it's possible to use it with .Net. All that in French!
Azure CLI Kung-Fu Tips and Tricks (Dan Patrick) - A true story for a real warrior... This post explains how a well done Azure CLI script can save you in hard conditions.
Getting Started with Visual Studio Online – Cloud IDE (Chris Pietschmann) - Announced in May it's already there and so nice to be able to work with VSOnline that is ( this time ;) f a real Visual Studio but in the cloud.
Trying out Container Tools in Visual Studio 2019 (Scott Hanseleman) - An interesting post that shows us all the great features packed into the new update of the container tool inside VsStudio 2019. So powerful.
Podcast
Done playing Microsoft's corporate game (Software Engineering Unlocked) - Great episode with the lovely Suz (aka: noopkat) talking about her roles and experience to different enterprises.
John Sonmez - Becoming a Finisher, Part 2 (The Solo Coder Podcast) - Second part of the interview with the very prolific John. Once more the episode is very interesting.
Andrew Connell's Blog (Andrew Connell) - This nice post is the second of a series of three. It explains how to do every step but also why the author decided to do that.
Highlights from Git 2.23 ( Taylor Blau) - This was the first time I notice an update of git... It is very intriguing to see such a powerful tool evolving and see some experimental feature. It's a long post, but totally worth it.
Azure Functions using Node with Simona Cotin (.NET Rocks!) - Great show. I just switch my website following that Jam stack pattern. I was planning to use Azure Functions to add a few little twists.... I'm happy to see that I not alone thinking like that!
0230 - Alain Vezina - Le métier du DevOps (Visual Studio Talk Show) - Super épisode, très intéressant d'entendre parler du rôle de DevOps de quelqu'un qui le vie au quotidien. Merci de la suggestion, je crois, bien que je suis du pour relire The Pheonix Project.
Goal Setting Tips & Tracking KPIs (Video Pursuit Podcast) - Really interesting episode. Everybody is talking about matrix and KPI... But it's not frequent to hear about the "how". I really like how the goals are explained, achievable, but not easy... And how we should react when we don't reach them.
Avoiding Azure Functions Cold Starts (Mark Heath) - Does cold starts are affecting your solutions? Maybe not, but if they are this post lists three scenarios to reduce them as must as possible.
A really interesting book that helps to focus and keep in mind the most important. I didn't read it with a purpose of business really, but it did make me remember past experiences and it was easy to make the relationship between success and when the story was clear. Take the time to read it, do the exercises/ reflections required... it's worth it.
Most of the time when we use an Azure Devtest Lab it to Test our own application. This means that will need to install them on the virtual machines, every time. To do that, we need to create a custom artifact and add it to our formulas or to our claimable VMs. Lucky for us, creating a custom artifact is much easier than you may think. In fact, this post I will show you how easy it can be.
Goal
I want to create an artifact available from a private repository (Git from dev.azure.com in this case) that will set the timezone inside the VM.
Getting started
First, let's use a section in the Azure portal that is very useful; the Get Started section. In the portal navigate to your DevTest Lab (1), and select the Getting Started option from the left menu bar (2). In this new bar scroll down to the Lear more area and select Sample artifacts and scripts (3).
That will open the DevTestLab artifacts, scripts and samples project from Azure on Github. Open the folder Artifact, to see the list of all the usual artifacts you find in the public repo that is available by default in the portal.
Notice how all artifacts are in their own folder. When you create a new artifact, you can always come here and pick something similar to what you are trying to do. This way, you won't start from scratch. Let's open windows-vsts-download-and-run-script. An artifact is defined in the file Artifactfile.json. This file is mandatory and cannot be renamed. You can put scripts, images, or anything else you need inside this folder.
Open the Artifactfile.json file and have a look.
As you can see it's a simple JSON file. In the section (A) you will define the title, description, publisher, OS and the Icon. Note that the Icon must be accessible publicly, it could be on github, a blob storage or on a website. Section (B) is to define all the parameters you may need to install your artifact on the VM. Finally In (C) it's the command to execute.
Create the Artifact
Here is the JSON for our windows-Set-TimeZone artifact. A made it very static by not passing any parameter, but in a reel situation, a timezone parameter would be better.
Artifactfile.json
{
"$schema": "https://raw.githubusercontent.com/Azure/azure-devtestlab/master/schemas/2016-11-28/dtlArtifacts.json",
"title": "Set TimeZone to Eastern Standard Time",
"description": "Execute tzutil command on the VM set set the Time Zone",
"publisher": "FBoucher",
"tags": [
"PowerShell"
],
"iconUri": "https://raw.githubusercontent.com/Azure/azure-devtestlab/master/Artifacts/windows-run-powershell/powershell.png",
"targetOsType": "Windows",
"parameters": { },
"runCommand": {
"commandToExecute": "tzutil.exe /s \"Eastern Standard Time\""
}
}
Create an artifact repository
For this post, I'm using Git from Azure Devops (dev.azure.com) previously named VSTS, but any private repository should works. If it's not already done create a project and go to the Repos section. Create a root folder named Artifacts or something else if you prefer. Then add a new folder for your artifact. To follow the best practices you should start with the name of your artifact by the name of the targeted OS; in my case windows-Set-TimeZone. Now add the file Artifactfile.json defined previously.
Note the url of the repository, it should be easy to get it by click on the Clone button that is on the top right of the screen.
Add repository to DevTest Lab
Now we need to add this repository to our Devtest Labs. From the portal.azure.com, open the blade of your lab. From the left panel, click on Repository, then click the Add button.
It's time to use the information noted previously. This is about the Repository, not the artifact.
Use the Artifact
The only thing left is to use our artifact. You can find it while creating a VM or a formula. When you have parameters define in your Artifactfile.json, the parameters will be listed in a form completly a the left.
And if you try it, you will see that the time match the desired timezone. Here my PC is set to display with a format of 24H put it's the same... yep I'm in Eastern Standard Time.
Add it to an ARM template
Doing it with the nice interface is good when you are learning. However, we all know that no DevOps will do that manually every time. So let's add our Repository to our ARM template. If you need more detail on the deployment method, I explain it in a previous post How to be efficient with our Azure Devtest Lab deployments.
When you don't know the type or the structure of a resource, you can always go in the Resource Explorer (resources.azure.com) there will be able to find your resource and see how it's defined.
So for this post our artifactsources will look like this:
An artifactsources goes in the Resources list inside the Devtest Labs.
In an ARM template you have the main node Resources (A), then you will have the Lab node (B). Inside this node, you should see second resources list (C), where the Virtual Network is defined. The artifactsources should go there.
Then when you declare your formula, you just need to reference this repository, exactly like the public one.
Introduction to Azure Durable Functions (Maxime Rouiller) - This is a great post that explains what are durable functions and shows a simple case to gives context.
The Five Dysfunctions of a Team: A Leadership Fable (Patrick Lencioni) - I really enjoyed this book. The fact the first the material was passed as a story adds a lot of perspective and to our comprehension. In the last chapter the author return to the theories and gives more details. I completely devour that book; I'm looking forward to reading more.
Miscellaneous
paddling.com (Wayne Horodowich) - I could not agree more.
1575 Coding on Twitch with Jeff Fritz (Carl Franklin, Richard Campbell, Jeff Fritz) - Yep developers are also on twitch and they rock. We learn how it all started in this episode.
You have a solution that is already deployed in Azure, and you would like to reproduce it. You know that Azure Resource Manager (ARM) template could help you to do that, unfortunately, you don't know how to get started. In this post, I will share with you the best practices and how I implement them while working on ARM template.
How to Get your ARM Template
Of course, you could build your ARM template from scratch. However, there many quickstart templates available on GitHubd. Even more, you could also get Azure to generate the template for you!
If your building a new solution, go in the Azure portal (portal.azure.com) and start creating your resource as usual. But stop just before clicking on the Create button. Instead click on the link on his side named Download template and parameters. That will open a new blade where you will be able to download the template, parameters files, and a few scripts in different languages to deploy it.
If your solution is already deployed, you still have a way to get the template. Again, from the Azure portal, go to the resource group of your solution. In the left option panel, click on Automation script.
Step 1 - Use Git
Once you have your ARM template and a parameter file, move them in a folder and initialize a Git Repository. Even if it's only a local one this will give you an infinite of Ctrl-Z. Doing multiple commit along your journey to get a better and cleaner template, you will always have options to get back when your template was "functional".
A fantastic tool to edit ARM template is Visual Studio Code. It's free, it supports natively Git, and you can install great extensions to help you.
Step 2 - Validate, Validate, Validate, then Commit
az groupdeployment validate --resource-groupcloud5mins --template-file .\template.json --parameters .\parameters.json
Step 3 - Reduce the Number of Parameters
Nobody like tons of questions. Too many parameters is exactly like too many questions. So reduce them to the maximum. We cannot just delete those unwanted parameters, but they are still providing important information. Instead move them in the variables section.
You can do that in different ways, let me share mine. I start with the parameter files and bubble-up any parameter that I would like to keep. Next Cut/Paste all the unwanted parameters to a new file. Then I use the multi-cursor selection of VSCode to clean them in 2 clicks.
Once we have all parameters "converted" in variables, copy them into the variables section of the ARM template. You will need to delete the parameter equivalent from the top of the template.
Now that we have a clean list of parameters, and variables, we must fix the references to the converted parameters. To do that replace all
parameters() references by variables().
For exemple this:
parameters('networkInterfaceName')
will become that:
variables('networkInterfaceName')
Now that we have a more respectable list of parameters, we must be sure that what we expect from them is clear. To do that we have two simple feature at our disposal. The first one of course the name. Use a complete and clear name. Resist the temptation to shorten everything or use too many acronyms. The second is to use metadata description. This information will be displayed to users through the portal as tooltips.
"adminUsername": {
"type": "string",
"metadata": {
"description": "Name of Administrator user on the VM"
}
}
Step 4 - Use Use Unique String
When you deploy in Azure some names are global, and by definition need to be unique. This is why adding a suffix or a unique identifier to your named is a good practice. An excellent way to get an identifier is to use the function uniqueString(). This function will create a 64Bits hash based on the information passed in parameter.
In the example just above, we pass the identifier of the resource group and its name. It means that every time you will be deploying in the same resource group and at that location suffix will be the same. However, if your solution is deployed in multiple locations (for a disaster recovery, or another scenario), suffix will have a different value.
To use it, let's say the name of a virtual machine was passed as a parameter. Then we will create a variable and concatenate the parameter and our suffix.
Then instead of using the parameter inside your ARM template, you will be using this new variable.
Step 5 - Use Variables
One of the great strengths of using ARM template is that we can use them over and over. This is why we want to avoid anything that his static name or value. When we generated template from the Azure portal, these templates are a snapshot of that particular instances. The best way to stay structured and avoid too fixed names is to leverage variables.
When you use an ARM template generated from a "live" and already deployed solution the ARM will contains a lot of very specific information about this instance (Comments, ResourceIDs, States, etc.). When you are building a generic template don't hesitate to delete those.
You may wonder why we need the first variable RGName , since the resource group name is already available through the resourceGroup() function? Some resources, like Azure Blob Storage's name, must only contain lowercase characters. By making a variable we avoid repeating the to toLower() every time.
You can concatenate two, or more variables and/or string with the "very popular" function concat(). Sometimes, the name built by all those string is too long. You can trim it by using the function substring(stringToParse, startIndex, length). In this case, the Azure Blob Storage required a name with a maximum of 24 characters.
The best way to build a good template is to think like the people who will use it. Therefore, a developer may not know what the difference between a Standard_D2s_v3, a Standard_F8 or a Standard_H8. But will clearly know if he needs a medium, a large, or a web development VM.
That means that we will create a parameter with only specific values allowed, and base on that simple selection we will take more specific and technical decision. See the declaration of the following parameter.
"EnvironmentSize": {
"type": "string",
"defaultValue": "medium",
"allowedValues": [
"medium",
"large"
],
"metadata": {
"description": "Medium for regular development. Large for huge memory usage"
}
}
This parameter will only allowed two string "medium" or "large", anything else will return a validation error. If nothing is passed the default value will be "medium". And finally using a metadata description to make sure the purpose of the parameter is clear and well defined.
Then you define your variable (ex: TS-Size) as an object with two properties, or as many as you have allowed values. For each of these properties, you could have many other properties.
Then to use it, we just need to chained the variables and parameter. Notice how we have nested square brackets... This will use the TS-Size.medium.VMSize value by default.
I hope you will find those tips as useful, as I found they are. If you have other suggestions or recommendations, don't hesitate to add them in the comment section or reach me out.
I don't know for you, but I don't like losing time. This is why a few years ago I started using scripts to install all the software I need on my computer. Got a new laptop? N You just need to execute this script, go grab a coffee and when I'm back all my favorite (and required) softwares are all installed. On Linux, you could use apt-get, and on Windows, my current favorite is Chocolatey. Recently I needed to use more virtual machine (VM) in the cloud and I deceided that I should try using a Chocolatey script during the deployment. This way once the VM is created the softwares, I need is already installed! This post is all about my journey to get there, all scripts, issues and workarounds will be explained.
The Goal
Creating a new VM on premises applying the OS update and installing all the tools you need (like Visual Stutio IDE) will takes hours... This solution should be done under 10 minutes (~7min in my case).
Once the VM is available, it should have Visual Studio 2017 Enterprise, VSCode, Git and Node.Js installed. In fact, I would like to use the same Chocolatey script I use regularly.
In this post I will use Azure CLI, because it will works on any environment. However, PowerShell can also be use only a few command will be different. The VM will be deploy with an Azure resource Manager (ARM) template. To create and edit the ARM template I like to use VSCode, you don't need it but it's so much easier with it! I use two extension.
The first one Azure Resource Manager Snippets will help by generating the schema for our needs. In a JSON file you just need to type arm en voila! You ahave a long list of ARM template!
The second is Azure Resource Manager Tools. This extension provides language support for ARM and some validate. Very useful...
Creating the ARM Template
To Get started create a new JSon file. Then type arm and select the first option; to get an empty skeleton. Then add an extra line in resources and type again arm. This time scroll until you see arm-vm-windows.
A multi-cursor will allow you to edit the name of your VM everywhere in the file in one shot. Hit Tab to navigate automatically to the userName, and Tab again to go to the password.
Now we have a functional ARM template that we could deploy. However, let's add a few things first.
Searching the Image SKUs by Code
One of my favorite VM images for a DevBox is the one that includes Visual Studio pre-installed. One thing to know is those images are only deployable in an MSDN subscription. To specify wich image you want to use you need to pass a publisher, offer, and sku.
Here how to do it with Azure CLI commands
# List all the Publishers that contain VisualStudio (It's case sensitive)
az vm image list-publishers --location eastus --output table --query "[?contains(name,'VisualStudio')]"
# List all offers for the Publisher MicrosoftVisualStudio
az vm image list-offers --location eastus --publisher MicrosoftVisualStudio --output table
# List all availables SKUs for the Publisher MicrosoftVisualStudio with the Offer VisualStudio
az vm image list-skus --location eastus --publisher MicrosoftVisualStudio --offer VisualStudio --output table
Now that all the information is found, search in the ARM template and replace the current values by the one found. In my case, here are the new values.
Great now we have a VM with Visual Studio but our applications are still not installed. That will be done by adding the Custom Script Extension for Windows to our template. documentation page, a sample schema is there ready to be use.
The last node of your template is currently another extension. For the purpose of this blog post let's remove it. You should have something like this.
We will copy/ paste the snippet from the documentation page a change a few little things. Change the type (thank to our VSCode Extension for that catch). Update the dependencies to reflet our demo.
To use the extension your script needs to be available online. It could be in a blob storage (with some security) or just publicly available. In this case, the script is publicly available from my gist.github page. I created a variable in the variables section that contains the RAW URL of my script, and a reference to that varaibale is used in the fileUris.
The extension will download the script and then execute a function locally. Change the commandToExecute to call our script with unrestricted execution policy.
You have a timed window of ~30 minutes to execute your script. If it takes longer then that, your deployment will fail.
# First, we need a Resource Group
az group create --name frankDemo --location eastus
# ALWAYS, always validate first... you will save a lot of time
az group deployment validate --resource-group frankDemo --template-file /home/frank/Dev/DevBox/FrankDevBox.json
#Finally deploy. This script should take between 5 to 10 minutes
az group deployment create --name FrankDevBoxDemo --resource-group frankDemo --template-file /home/frank/Dev/DevBox/FrankDevBox.json --verbose
What's Next?!
We created one template; you could make it better.
Deploy from anywhere
By moving the computerName, adminUsername, adminPassword, and the script url in the parameters section, you could then put the template in a public place like GitHub. Then with use the one click deploy!
Directly from the Github page or from anywhere you just need to build a URL from those two parts: https://portal.azure.com/#create/Microsoft.Template/uri/ and the HTML Encoded URL to your template.
If my template is available at https://raw.githubusercontent.com/FBoucher/SimpleDevBox/master/azure-deploy.json then the full url become:
It's very easy to forget to turn off those VM. And whatever you are paying for them or your using the limited MSDN credit it's a really good practice to turn them down. Why not do that automatically!
That can be very simply done by adding a new resource in the template.