Azure CLI is a component of CI/CD or automation in the Azure ecosystem. You can use the Azure CLI to perform CRUD operations on resources on your Azure subscription. It is cross-platform, and this allows it to be used from any system that can run bash shell commands. It is also available on the Azure Cloud Shell.

This tutorial is a basic guide on how you can use the Azure CLI to create a storage account, upload a blob to this storage account, and then view the content via the public URL of this blob. To follow along, you need to have the Azure CLI and an active Azure subscription.

Table of Content

  • Authenticating with Azure
  • Basic Commands: Creating and Listing Resource Groups
  • Create the Storage Account
  • Create the Storage Account Container
  • Moving existing commands to a Script
  • Summary

Authenticating with Azure

You can authenticate with Azure by running az login.

Basic Commands: Creating and Listing Resource Groups

The most basic command you should run after logging in is

az account show

It shows the details of the currently logged in user like their tenant name, email, and subscription.

{
  "environmentName": "AzureCloud",
  "homeTenantId": "djco9u80-dcujc0ei-dujekoid02-diod",
  "id": "ckmou98id-eddjwedoi-dfcjaoii940e-dudioe",
  "isDefault": true,
  "managedByTenants": [],
  "name": "Demo Azure Subscription",
  "state": "Enabled",
  "tenantDefaultDomain": "demosub.onmicrosoft.com",
  "tenantDisplayName": "Demo Sub",
  "tenantId": "dhjodd8-due08d09d-dujcod89-8d98iujd",
  "user": {
    "name": "demosubuser@userland.service",
    "type": "user"
  }
}

Create the Resource Group

The most basic unit of organization on Azure is the resource group so it’s the first thing you’ll want to create. After creating the resource group, you can then create resources within it. The command for creating a new resource group is:

az group create --resource-group az-cli-demo-rg --location eastus

Where az-cli-demo-rg is the name of the resource group. Since the subsequent commands will be created within this resource group. It’s best to save the resource group name to a variable, then reference this variable from other commands.

LOCATION=eastus
RESOURCE_GROUP=az-cli-demo-rg
az group create --resource-group $RESOURCE_GROUP --location $LOCATION

Create the Storage Account

A storage account is a service that allows you to storage blobs and files with additional sub-services for queue storage and a simple no-sql table storage. It’s central to many cloud operations as storage is a central part of the cloud. You can create a storage account using the following command:

STORAGE_ACCOUNT=azclidemostorage$RANDOM
az storage account create --name $STORAGE_ACCOUNT --resource-group $RESOURCE_GROUP --location $LOCATION --sku Standard_LRS --allow-blob-public-access true

A storage account can be authenticated against using a SAS token, an account key, or the Azure AD current user credentials. Technically speaking, the Azure AD credentials will be used to fetch the storage key and use it for operations within the storage account. The rest of the operations in this article will require this account key so it needs to be fetched and stored to a variable. Run the command below to fetch and store the key:

STORAGE_ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP --account-name $STORAGE_ACCOUNT --query "[0].value" --output tsv)

Create the Storage Account Container

Now that the storage account has been created, you can then create a public container within the storage account.

CONTAINER_NAME=journal-entries
az storage container create --name $CONTAINER_NAME \
  --account-name $STORAGE_ACCOUNT \
  --public-access blob \
  --account-key $STORAGE_ACCOUNT_KEY

Moving existing commands to a Script

At this point, you have ran a lot of commands to achieve a task that might take less time if you go straight to the Azure portal and click click click. The beauty of scripts is their repeatability model. They allow you to run the same operations over and over again. You can move all the existing commands to a script and simply change the variables for a reusable solution. Here’s the complete script with additional commands to upload a file to the storage container and get its public URI.

#!/bin/bash

RESOURCE_GROUP=az-cli-demo-rg
LOCATION=eastus
STORAGE_ACCOUNT=az-cli-demo-storage$RANDOM
CONTAINER_NAME=journal-entries
BLOB_FILE=journal-entry-$RANDOM.txt

echo "Today, I learnt about creating stuff on Azure using azure cli and scripts" >> $BLOB_FILE

az group create --location $LOCATION --resource-group $RESOURCE_GROUP

az storage account create --name $STORAGE_ACCOUNT --resource-group $RESOURCE_GROUP --location $LOCATION --sku Standard_LRS --allow-blob-public-access true

STORAGE_ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP --account-name $STORAGE_ACCOUNT --query "[0].value" --output tsv)

az storage container create --name $CONTAINER_NAME \
  --account-name $STORAGE_ACCOUNT \
  --public-access blob \
  --account-key $STORAGE_ACCOUNT_KEY

az storage blob upload --account-name $STORAGE_ACCOUNT \
  --container-name $CONTAINER_NAME \
  --name $BLOB_FILE \
  --file $BLOB_FILE \
  --account-key $STORAGE_ACCOUNT_KEY

BLOB_URL=$(az storage blob url \
  --account-name $STORAGE_ACCOUNT \
  --container-name $CONTAINER_NAME \
  --name $BLOB_FILE \
  --account-key $STORAGE_ACCOUNT_KEY \
  --output tsv)

echo "Your journal entry can be viewed here $BLOB_URL"

Summary

In this article, you learnt about the Azure CLI and how it allows for a different model of accessing resources within Microsoft Azure. You also saw how the CLI commands can be structured into a re-usable script for a reproducible solution. While Azure CLI offers all these benefits, it doesn’t easily account for idempotency and thus, is not the perfect IaC solution. A solution that fits this use-case better is Azure Resource Manager (ARM) Templates. ARM allows you to define your infrastructure in JSON and run it repeatedly without duplication. While this solves the idempotency issue, it might not be convinient to write JSON. Azure has other options like Bicep which compiles to ARM, and Terraform which is not part of Azure, but works well to address IaC needs within the ecosystem.