0 Comments Posted in:

I'm a huge fan of the Azure CLI - I've blogged about it and created a Pluralsight course on getting started with it.

I often use the Azure CLI to quickly try out various Azure resources like Web Apps or Cosmos DB databases. After playing for a while with them, I then delete the resource group I've put them in to clean up and stop paying.

Deleting is especially important when you experiment with expensive resources like a multi-node Service Fabric or AKS cluster. Forgetting to clean up after yourself could be an expensive mistake.

Enter "Noel's grab bag of Azure CLI goodies", an awesome extension to the Azure CLI created by Noel Bundick which adds a "self-destruct" mode along with a bunch of other handy functions.

Installing the extension

To install the extension, simply follow the instructions on GitHub, and use the az extension add command pointing at the latest version (0.0.12 at the time of writing this). You can then see it in the list of installed extensions with az extension list

# to install v0.0.12:
az extension add --source https://github.com/noelbundick/azure-cli-extension-noelbundick/releases/download/v0.0.12/noelbundick-0.0.12-py2.py3-none-any.whl

# to see the list of installed extensions
az extension list -o table

There is a one-time setup action needed for self-destruct, which will create a service principal with contributor rights that is used by the logic app that implements the self-destruct action.

az self-destruct configure
# OUTPUT (no these are not my real credentials!):
# Creating a service principal with `Contributor` rights over the entire subscription
# Retrying role assignment creation: 1/36
# {
#   "client-id": "c9e0fb8e-18d2-44bd-b0bc-52056965a362",
#   "client-secret": "0dbcece7-34c5-49fe-ac2e-dbab9cb310e1",
#   "tenant-id": "fc3d0620-79f6-4b16-80b4-3b486a33514e"
# }

Using self-destruct mode

To use self-destruct mode, you simply specify the --self-destruct flag on any resource you create with az <whatever> create. A good level to set this at is a resource group so you can create multiple resources that will get deleted together.

In this example, I'm creating a resource group called experiment that will self-destruct in 30 minutes, and then putting an App Service Plan inside it so there is something to be deleted inside the group.

$resGroup = "experiment"
# can use 1d, 6h, 2h30m etc
az group create -n $resGroup -l westeurope --self-destruct 30m

# create something to get deleted
az appservice plan create -g $resGroup -n TempPlan --sku B1

Note that the extension will tag the resources you create with a self-destruct-date tag.

If we look inside our resource group, we'll see that not only is there the app service plan we created, but a Logic App. This Logic App exists solely to implement the self-destruct and is even able to delete itself when it's done which is convenient.

# see what's in the resource group (there will be logic app
az resource list -g $resGroup -o table

# Name                                                ResourceGroup    Location    Type                       Status
# --------------------------------------------------  ---------------  ----------  -------------------------  --------
# self-destruct-resourceGroups-experiment-experiment  experiment       westeurope  Microsoft.Logic/workflows
# TempPlan                                            experiment       westeurope  Microsoft.Web/serverFarms

If you want to, you can explore the Logic App in the Azure portal to see how it works Logic App

See it in action

To see what resources are scheduled for self-destruct, you can use the az self-destruct list command:

az self-destruct list -o table
# Date                        Name        ResourceGroup
# --------------------------  ----------  ---------------
# 2018-11-30 13:12:42.750344  experiment  experiment

If you've changed your mind you can disarm self-destruct mode with az self-destruct disarm or re-enable it later with a different duration using az self-destruct arm

Finally, once the timer has expired, you can check whether it worked by searching for resources in the group. If all went well, there'll be nothing to see:

az resource list -g $resGroup -o table
# Resource group 'experiment' could not be found.


The self-destruct mode extension is a great way of protecting yourself against expensive mistakes and worth considering using for all short-lived experiments. It's a superb idea, and nicely executed. The idea could be developed further, for example it could email you asking if you are still using a resource group and if you don't respond within a set period of time it deletes it, to make a sort of "dead man's switch" for Azure.

Want to learn more about the Azure CLI? Be sure to check out my Pluralsight course Azure CLI: Getting Started.


Just a quick update of a few things I'll be doing this month that you might also be interested in...

Dec 1 - Advent of Code is starting again

Regular readers of this blog will know that I'm a big fan of the Advent of Code site, which gives you daily programming puzzles that will stretch you and improve your coding skills. For each of the last three years I've blogged my answers, and I've used it as a chance to improve my LINQ, F# and JavaScript skills. I've not picked a theme for this year's solutions yet, but hopefully I'll have time to attempt them, and if possible I'll blog about how I get on.

Dec 4 - Microsoft Connect(); Online Conference

The Connect(); 2018 event is a developer-focused event which will keep you up to date with the latest news in the world of Azure and Microsoft developer tools. I'm particularly looking forward to the "Kubernetes for the klueless" session from Brendan Burns and learning more about .NET Core 3. This year there will also be some live coding sessions streamed on Twitch as part of the event.

Bonus Extra - A few sessions from the Docker EU Conference will also be streamed live on Dec 4th and 5th. A great opportunity to catch up on the latest innovations in the world of containers.

Dec 6 - Azure Durable Functions at Developer South Coast

If you're based anywhere near the South Coast of England, then you'd be more than welcome to join me at Developer South Coast where I'll be talking about how to create serverless workflows using the superb Azure Durable Functions extension.

Dec 11 - Containers on Azure at Azure Thames Valley

I'm also very privileged to have been invited to speak at the inaugural Azure Thames Valley event in Maidenhead, talking about the various options available to you for running containers in Azure (spoiler: there are lots). I'll be joined by Richard Conway, who'll be talking about Azure Cost Efficiency. Again, I'd love to meet you at this event if you're in the London area.

0 Comments Posted in:

If you're running containers in Azure, then Azure Container Registry (ACR) is a great place to store your custom container images.

But ACR can do more than store container images. It can also build them for you. This is really useful if like me, you sometimes have to work on a computer that doesn't have Docker installed.

In this post, I'll run you through the steps required to build container images using ACR, without needing Docker installed locally. And we'll also see how we can easily run the container with Azure Container Instances.


First of all, you will need access to the Azure CLI. This can either be installed locally, or you can use the excellent Azure Cloud Shell which you can access in the Azure Portal, and means you don't need anything installed locally other than web browser.

Second, you will of course need an Azure Container Registry. You can create one in the Azure portal, or you can enter the following Azure CLI commands to create a new resource group and an ACR instance.

$resourceGroup = "AcrDemo"
az group create -n $resourceGroup -l westeurope
$acrName = "acrname"
az acr create -g $resourceGroup -n $acrName --sku Basic --admin-enabled

The Basic pricing tier is fine, and you do need the --admin-enabled flag if you want to be able to retrieve login credentials, which we'll use later.

Building an image with ACR

To build an image, you will of course need a Dockerfile, and all the supporting code files it needs. I recommend setting up a multi-stage build which allows a single Dockerfile to first build your application binaries and then use them to create the final container image. An example multi-stage Dockerfile for ASP.NET Core can be found here, and you should easily be able to find examples for other popular programming frameworks.

I've got a simple ASP.NET Core web app that I used in my recent Pluralsight course on deploying containers in Azure, and we'll use that as the demo scenario. If you'd like to follow the demo steps, clone the code with Git, and change into the SampleWebApp folder which contains a multi-stage build Dockerfile.

git clone https://github.com/markheath/azure-deploy-manage-containers.git
cd azure-deploy-manage-containers/SampleWebApp

Now, from within this folder, we can build using the az acr build command, specifying the ACR instance to use with -r, the Dockerfile to use with -f and the name and tag of the image to create with -t. The final argument (.), is simply the working folder.

az acr build -r $acrname -f .\multi-stage.Dockerfile -t samplewebapp:acr .

What this will do is zip up the Dockerfile and the local files in the working folder and upload them to your Azure Container Registry so it has all the context it needs to perform the build. This works whether you're running locally on a development machine or in the Azure Cloud Shell.

While it builds, you'll see output looking something like this:

Packing source code into tar to upload...
Excluding '.gitignore' based on default ignore rules
Uploading archived source code from 'C:\Users\mheath\AppData\Local\Temp\build_archive_397dfd61aaca4a2c95bb9e4ff791fee5.tar.gz'...
Sending context (172.888 KiB) to registry: pluralsightacr...
Queued a build with ID: cb4
Waiting for agent...
2018/11/19 14:40:25 Using acb_vol_7f5af0bc-f227-499f-94a4-0e2381be50dc as the home volume
2018/11/19 14:40:25 Setting up Docker configuration...
2018/11/19 14:40:25 Successfully set up Docker configuration
2018/11/19 14:40:25 Logging in to registry: pluralsightacr.azurecr.io
2018/11/19 14:40:32 Successfully logged in
2018/11/19 14:40:32 Executing step ID: build. Working directory: '', Network: ''
2018/11/19 14:40:32 Obtaining source code and scanning for dependencies...
2018/11/19 14:40:38 Successfully obtained source code and scanned for dependencies
Sending build context to Docker daemon  1.434MB
Step 1/10 : FROM microsoft/dotnet:2.1-sdk AS build-env
Run ID: cb4 was successful after 2m4s

And that's all there is to it - just a one line command to build our container image and store it in ACR.

Managing ACR images

If we want to explore the contents of our Azure Container Registry with the Azure CLI, we can use the following commands:

# list all images in our ACR
az acr repository list -n $acrName
# show the tags for the samplewebapp repository
az acr repository show-tags -n $acrName --repository samplewebapp
# show details for the samplewebapp:acr image
az acr repository show -n $acrName -t samplewebapp:acr

When we're done, if we want to delete this image, we can also use the Azure CLI to delete it:

# n.b. prompts, showing you exactly what will be deleted
az acr repository delete -n $acrName -t samplewebapp:acr

Run our container using ACI

Obviously, if we've not got Docker installed locally, we can't run our container image easily, but Azure has us covered on that front too. With Azure Container Instances, you can easily create a new container from that image with az container create. I'm using the -e flag to set an environment variable, and opening port 80 and giving it a custom DNS prefix.

Note that we will need a credentials for the ACR to do this, so I'm using az acr credential show to get hold of the ACR password.

# get the ACR password
$password = az acr credential show -n $acrName --query "passwords[0].value"  -o tsv

# create a new ACI instance to run this container
az container create -n samplewebapp -g $resourceGroup `
            --image "$acrName.azurecr.io/samplewebapp:acr" `
            --registry-username "$acrName" `
            --registry-password "$password" `
            -e TestSetting=ACI `
            --dns-name-label samplewebapp --ports 80

It will take a minute or so to get started, but once it's up and running, we can visit our website running in a container at samplewebapp.westeurope.azurecontainer.io.

Of course, don't forget to delete this container when you've done testing it. ACI is great for short-lived experiments, but its pricing model doesn't lend itself to leaving things running long-term. You can delete the container with:

az container delete -n samplewebapp -g $resourceGroup -y


Azure Container Registry is not only a great place to host container images but with the Azure CLI it's really easy to build images with ACR, eliminating the need to have a local installation of Docker. Azure Container Instances then makes it really easy to try out your container in an easily disposable serverless environment.

If you'd like to go deeper with these topics, I've created a few related Pluralsight courses you might find helpful: