Introduction

You are busy developing. It is late at night. You decide to delete one of your test virtual machines and recreate it to validate your deployment procedure. You log into the Azure Portal, select a virtual machine and click DELETE.

Then you proceed to create a new virtual machine. You receive an error that a virtual machine with the same name exists. Next, your cell phone lights up with alerts. You say to yourself, what the shazam did I do?

Now it is 5 AM. You have recovered the deleted virtual machine from snapshots. You pat yourself on the back for being prepared for emergencies. You leave your home office and try to get a few hour’s sleep.

The next day, you set a goal to never allow that to happen again.

This is a true story. I was working late and made a mistake that luckily only cost me a few hours of time to recover from.

Introducing Azure Resource Locks

Azure supports locking resources at the subscription, resource group, and resource level. Implementing locks in the Azure Portal is easy. However, when I tried to lock a virtual machine using the CLI, I found the documentation lacking. It took a few tries and failures to get the parameters correct.

There are two types of locks:

  • CanNotDelete. This lock prevents deleting a resource. The resource can still be read and modified by authorized users.
  • ReadOnly. This lock prevents modifying a resource including preventing stop, start, and deletion.

Whereas RBAC grants permissions to users, locks affect all users regardless of their roles. Locks override any permissions the user might have.

Locks can be modified or removed with the permission Microsoft.Authorization/locks/*. The built-in roles Owner and User Access Administrator have this permission.

Note: I discovered that an additional lock can be applied to a resource that has the ReadOnly lock applied.

Locks are inherited. This means that if you apply a lock at the Subscription level all resources in that subscription are locked.

This article focuses on using the Azure CLI and Terraform to apply CanNotDelete locks to a virtual machine. There are other resource types related to virtual machines that you might also want to lock, such as a public IP address. Terraform supports locks with the azurerm_management_lock resource.

[Update 2021-09-30]: I added a Python program to list the locks with an Azure subscription using the Azure SDK for Python.

Azure CLI

Figuring out the CLI was the hardest part. In comparison, writing Terraform HCL was easy. My challenge was partially due to the Azure Lock documentation and partially because I am very comfortable with Azure. I made assumptions about parameters that are wrong in the context of Azure locks.

For example, the parameter –resource-name exists. The documentation states [link]:

Name or ID of the resource being locked. If an ID is given, other resource arguments should not be given.

I incorrectly assumed that the ID was the Resource ID of the virtual machine. That was a wrong assumption. By using the virtual machine resource ID, I locked the entire subscription. I still do not know why.

The second problem that I had was figuring out the Resource Type. I need to locate a document that lists these types. I switched to writing Terraform HCL to lock the virtual machine and then I used the Azure CLI command, az lock list, to see the parameters. From that, I figured out the Resource Type is Microsoft.Compute/virtualMachines.

To use the Azure CLI, collect the following information:

  • Azure Resource Group Name
  • Azure Virtual Machine Name

The final command that is the easiest to configure (Windows command syntax):

Resource Type

[Update 2021-09-23]

Resource Type is actually two items. The namespace (provider) and the type.

This command will list the providers:

This command will list the types for a provider. In this example, for Microsoft.Compute.

Similar command using jq and sort.

Truncated Output:

Terraform

If I would have started this project with Terraform, I would have figured out the options easier than using the Azure CLI.

My Terraform files are on GitHub: GitHub Gist

To use Terraform, collect the following information:

  • Azure Resource Group Name
  • Azure Virtual Machine Name

Create a working directory on your system.

Create a file named terraform.tfvars with the following content modified with the Resource Group and Virtual Machine names:

Create another file named main.tf with the main Terraform HCL

The last file contains definitions for the variables. Name this file variables.tf.

Complete the following steps to initialize, validate, and plan as preliminary steps to validate the HCL and variables:

  • terraform init
  • terraform validate
  • terraform plan

After reviewing the output from the above commands for mistakes, warnings, and errors, you are ready to lock the Azure Virtual Machine:

  • terraform apply

Run this command to remove the virtual machine lock. Do not worry, this will not delete the virtual machine. Only the lock will be deleted.

  • terraform destroy

Python program

The following example shows how to use the Azure SDK for Python to lock a virtual machine. For details on setting up the SDK environment, see my article: Azure – Setting up a Development Environment for Python

Create a requirements.txt file

The file requirements.txt declares the Python packages that are required for a program to operate correctly.

Using your favorite editor, create a file named requirments.txt with the following content:

Install dependencies

  • pip install -r requirements.txt

Create the program file

Create a file named list_locks.py

Setup environment variable

This step requires the Azure CLI to display the account Subscription ID. This is also available in the Azure Portal.

Run the following command:

  • az account show

The account information is displayed in JSON. Copy the value for “id” without the quotes.

Run the following command to set the environment variable AZURE_SUBSCRIPTION_ID. Replace the text REPLACE_ME with the id from the previous command output.

  • set AZURE_SUBSCRIPTION_ID=REPLACE_ME

Run the program

If there are any Management Locks within the subscription, a formatted table will be displayed.

Run the Python program:

  • python list_locks.py

Example output:

Summary

I hope this article inspires you to take action and protect important Azure resources. Locks are one type of method to protect resources. Strong security, backups, snapshots, etc. are also important tools.

Using the Azure Portal makes most tasks very simple. However, I find that I do not learn the low-level details only using the Azure Portal. Combining knowledge of the details of many services and tools helps broaden and deepen my command of Azure.

More Information

Photography Credits

I write free articles about technology. Recently, I learned about Pexels.com which provides free images. The image in this article is courtesy of Pixabay at Pexels.