Microsoft Azure - First steps

Posted in automation on October 5, 2016 by Adrian Wyssmann ‐ 17 min read

Working for my current employer, I have an MSDN subscription and access to Microsoft azure. I also have a nice amount of credits to spend, so it's good opportunity to get warm with Azure.

But before starting with Microsoft azure, it might be good to understand the different entities Azure offers. As always a good starting point is the official documentation. At this point I don’t need to know all resources but the most common ones. My goal is to setup a could environment with a Jenkins instance (master) and 2 connected Jenkins slaves.

Environment setup

Also important is the following important note which I have seen in the Azure documentation as of

Before you work with Azure resources, it’s important to understand that Azure currently has two deployment models: Azure Resource Manager and classic. Make sure you understand deployment models and tools before you work with any Azure resource. You can view the documentation for different tools by clicking the tabs at the top of this article.

Preparation

The easiest way to work with Azure is using the WebPortal, but working with Linux, I want to try the cli client. On Arch Linux you can find the cli client in the AUR repsoitory. After installing there are two things to do:

  1. As recommended we will switch the cli to Resource Manager mode by running azure config mode arm

  2. Enable auto complete for azure

    [me@archlinuc ~]$ azure --completion >> ~/azure.completion.sh echo 'source ~/azure.completion.sh'>> ~/.bash_profile
    

Resource Groups

The first resource you need is a resource group. Resource groups are containers which holds Azure resources (VMs, web apps, virtual networks, …) and which you can manage as a group. This includes resource allocation as well as access control. Resource groups can be created via the portal or the Powershell/cli. A group needs a name and a location and optionally also tags. The location specify where where that metadata is stored, which is an an important compliance aspect. For my private use it does not really matter, but I prefer westeurope.

[me@archlinux ~]$ azure group create ResGroup1 westeurope
 info:    Executing command group create
 + Getting resource group ResGroup1
 + Creating resource group ResGroup1
 info:    Created resource group ResGroup1
 data:    Id:                  /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1
 data:    Name:                ResGroup1
 data:    Location:            westeurope
 data:    Provisioning State:  Succeeded
 data:    Tags: test
 data:

Let’s check it:

[adrian@archlinux ~]$ azure group list
 info:    Executing command group list
 + Listing resource groups
 data:    Name       Location    Provisioning State  Tags:
 data:    ---------  ----------  ------------------  -----
 data:    ResGroup1  westeurope  Succeeded           test
 info:    group list command OK

It’s also visible in the azure portal:

New Azure Resource Group

Virtual networks (VNet)

Virtual networks are logically isolated networks within the cloud and can be fully controlled by you. Not only that they are fully isolated, but they also provide a lot of features like accessibility trough public Internet, name resolution, security mechanisms to secure incoming and outgoing traffic. The VNets can be interconnected with each other and also to your on-premises network. The azure infrastructure plays the role of the router which makes this possible. It is recommended to plan your virtual network with care and it is highly recommended to read trough Article “Plan and design Azure Virtual Networks”

Some important aspects to consider for VNets, found at Virtual networks FAQ:

  • Default routers cannot be pinged in a VNet
  • VNet supports TCP, UCP and ICMP
  • You can use public IP address ranges and any IP address range defined in RFC 1918.
  • All services within a VNet can connect to the internet.
  • VNets do NOT support multicast or broadcast
  • VNets are Layer-3 overlays. Azure does not support any Layer-2 semantics and therefore do not support VLANs to Azure
  • You can use User Defined Routing (UDR). For more information about UDR, visit User Defined Routes and IP Forwarding.

However, as drawn above, I have very simple setup with a single network with only few host addresses. Therefore I have chosen 111.111.111.0/24. Now let’s create this.

[me@archlinux ~]$ azure network vnet create --name vnet1 --tags test --resource-group ResGroup1 --location westeurope -a 111.111.111.0/24
 info:    Executing command network vnet create
 + Looking up the virtual network "vnet1"
 + Creating virtual network "vnet1"
 data:    Id                              : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1/providers/Microsoft.Network/virtualNetworks/vnet1
 data:    Name                            : vnet1
 data:    Type                            : Microsoft.Network/virtualNetworks
 data:    Location                        : westeurope
 data:    Provisioning state              : Succeeded
 data:    Address prefixes:
 data:      111.111.111.0/24
 info:    network vnet create command OK

For now this is all I need. Further configuration may come later if needed.

Virtual Machines

Yeah, we know what virtual machines are (I hope at least) so I will not bother with this topic too much. You can create Windows or Linux VMs or event containers. Checkout the related documentation

Based on my idea above I want to setup 3 machines

  • master: Jenkins Master (Ubuntu)
  • node1: Jenkins Slave on Windows
  • node2: Jenkins Slave on Linux (Ubuntu)

Let’s create our master. Unfortunately the command only asks for some required parameters and not all required, so the command will fail

[me@archlinux ~]$ azure vm create
 info:    Executing command vm create
 Resource group name:  ResGroup1
 Virtual machine name:  master
 Location name:  westeurope
 Operating system Type:  linux
 + Looking up the VM "master"
 error:   image-urn or os-disk-vhd parameter is required to create a VM
 error:   Error information has been recorded to /home/swtd/.azure/azure.err
 error:   vm create command failed

We need to provide either a virtual disk (vhd) with an already installed system or we create a vm based on an image. Azure marketplace already offers a lot of images or you can build and use your own image. I will use an image from the Marketplace as I want to use a standard Ubuntu 16.04 LTS. Therefore let’s check if Canonical is one of the available publishers in my region

[me@archlinux ~]$ azure vm image list-publishers --location westeurope| grep -i canonical
 data:    Canonical                                                                           westeurope

Yes, so let’s check the images they provide. It is distinguished between offer and SKU - Stock-Keeping-Units i.e. unique identifiers for each distinct product and service. I understand offers as “Products” and the SKU as “flavors”.

[me@archlinux ~]$ azure vm image list-offers -l westeurope -p Canonical
info:    Executing command vm image list-offers
+ Getting virtual machine image offers (Publisher: "Canonical" Location:"westeurope")
data:    Publisher  Offer                      Location
data:    ---------  -------------------------  ----------
data:    Canonical  Ubuntu15.04Snappy          westeurope
data:    Canonical  Ubuntu15.04SnappyDocker    westeurope
data:    Canonical  UbunturollingSnappy        westeurope
data:    Canonical  UbuntuServer               westeurope
data:    Canonical  Ubuntu_Snappy_Core         westeurope
data:    Canonical  Ubuntu_Snappy_Core_Docker  westeurope
info:    vm image list-offers command OK

[adrian@archlinux ~]$ azure vm image list-skus -l westeurope -p Canonical -o UbuntuServer
info:    Executing command vm image list-skus
+ Getting virtual machine image skus (Publisher:"Canonical" Offer:"UbuntuServer" Location:"westeurope")
data:    Publisher  Offer         sku                Location
data:    ---------  ------------  -----------------  ----------
data:    Canonical  UbuntuServer  12.04.2-LTS        westeurope
data:    Canonical  UbuntuServer  12.04.3-LTS        westeurope
...
data:    Canonical  UbuntuServer  16.04-beta         westeurope
data:    Canonical  UbuntuServer  16.04.0-DAILY-LTS  westeurope
data:    Canonical  UbuntuServer  16.04.0-LTS        westeurope
data:    Canonical  UbuntuServer  16.10-DAILY        westeurope
info:    vm image list-skus command OK

Ok, here we go, let’s install Ubuntu 16.04.0-LTS. But for this we need to now the image-urn, which is not shown above. So let’s run another command

[me@archlinux ~]$ azure vm image list -l westeurope -p Canonical -o UbuntuServer | grep -i 16.04.0-LTS
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201604203  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201604203
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201605161  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201605161
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201606100  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201606100
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201606270  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201606270
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201607210  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201607210
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201608150  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201608150
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201608250  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201608250
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201608300  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201608300
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201609071  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201609071
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201609210  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201609210
data:    Canonical  UbuntuServer  16.04.0-LTS        Linux  16.04.201609220  westeurope  Canonical:UbuntuServer:16.04.0-LTS:16.04.201609220

Let’s use the latest update. We use the resource group previously created.

[me@archlinux]$ azure vm create --resource-group ResGroup1 -n master -l westeurope -y linux --image-urn Canonical:UbuntuServer:16.04.0-LTS:16.04.201609220
info:    Executing command vm create
+ Looking up the VM "master"
Enter username:  adrian
Enter password for adrian: *********
Confirm password: *********
info:    Using the VM Size "Standard_DS1"
info:    The [OS, Data] Disk or image configuration requires storage account
+ Retrieving storage accounts
info:    Could not find any storage accounts in the region "westeurope", trying to create new one
+ Creating storage account "clic073d5e0f8b392ac14751" in "westeurope"
+ Looking up the storage account clic073d5e0f8b392ac14751
error:   Either NIC Id or NIC name is required
error:   Error information has been recorded to /home/swtd/.azure/azure.err
error:   vm create command failed

As you can see, the command fails cause we are missing a NIC. We also see, that a storage account has been created. I will come to that later.

NICs (Network Interfaces) and Subnets

That an VM can communicate with other resources it needs a network interface. The network interface is associated to a subnet. Currently I don’t have neither one of them. Therefore, let’s first create the subnet. Remember that I have a vnet 111.111.111.0/24 and I don’t really need to further divide this, so I just use the whole as my subnet

[me@archlinux ~]$ azure network vnet subnet create
info:    Executing command network vnet subnet create
Resource group name:  ResGroup1
Virtual network name:  vnet1
Subnet name:  vnet1-sub1
Address prefix:  111.111.111.0/24
+ Looking up the virtual network "vnet1"
+ Looking up the subnet "vnet1-sub1"
+ Creating subnet "vnet1-sub1"
data:    Id                              : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/vnet1-sub1
data:    Name                            : vnet1-sub1
data:    Provisioning state              : Succeeded
data:    Address prefix                  : 111.111.111.0/24
info:    network vnet subnet create command OK

Now I should be able to create my network interface

[me@archlinux ~]$ azure network nic create -n nicmaster -g ResGroup1 -l westeurope --subnet-name vnet1-sub1
info:    Executing command network nic create
+ Looking up the network interface "nicmaster"
+ Creating network interface "nicmaster"
error:   Subnet reference is required for ipconfiguration /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1/providers/Microsoft.Network/networkInterfaces/nicmaster/ipConfigurations/default-ip-config.
error:   Error information has been recorded to /home/swtd/.azure/azure.err
error:   network nic create command failed

It seems I need a subnet. So let’s first understand what is a subnet

Subnets

According to https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-overview/#subnets:

Subnet is a range of IP addresses in the VNet, you can divide a VNet into multiple subnets for organization and security. VMs and PaaS role instances deployed to subnets (same or different) within a VNet can communicate with each other without any extra configuration. You can also configure route tables and NSGs to a subnet.

In addition Virtual Networks FAQ gives answer to some important questions

  • There is no limit on the number of subnets you use within a VNet. All the subnets must be fully contained in the virtual network address space and should not overlap with one another.
  • Azure reserves some IP addresses within each subnet. The first and last IP addresses of the subnets are reserved for protocol conformance, along with 3 more addresses used for Azure services.
  • The smallest subnet we support is a /29 and the largest is a /8 (using CIDR subnet definitions).

So I need a subnet for my vnet1 and as I do not need to divide my vnet1 in further subnets, I create a subnet using the whole range of my vnet1

[me@archlinux~]$ azure network vnet subnet create ResGroup1 vnet1 sub1
info:    Executing command network vnet subnet create
Address prefix:  111.111.111.0/24
+ Looking up the virtual network "vnet1"
+ Looking up the subnet "sub1"
+ Creating subnet "sub1"
data:    Id                              : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/sub1
data:    Name                            : sub1
data:    Provisioning state              : Succeeded
data:    Address prefix                  : 111.111.111.0/24
info:    network vnet subnet create command OK

Now I can provide the subnet-id as parameter when creating the nic

[me@archlinux ~]$ azure network nic create -n nicmaster -g ResGroup1 -l westeurope --subnet-id /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/vnet1-sub1
info:    Executing command network nic create
+ Looking up the network interface "nicmaster"
+ Creating network interface "nicmaster"
data:    Id                              : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1/providers/Microsoft.Network/networkInterfaces/nicmaster
data:    Name                            : nicmaster
data:    Type                            : Microsoft.Network/networkInterfaces
data:    Location                        : westeurope
data:    Provisioning state              : Succeeded
data:    Internal domain name suffix     : lbiu5q0vqeau1dttbvswk3czcb.ax.internal.cloudapp.net
data:    Enable IP forwarding            : false
data:    IP configurations:
data:      Name                          : default-ip-config
data:      Primary                       : true
data:      Provisioning state            : Succeeded
data:      Private IP address            : 111.111.111.4
data:      Private IP version            : IPv4
data:      Private IP allocation method  : Dynamic
data:      Subnet                        : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/vnet1-sub1
data:
info:    network nic create command OK

As you can see, the nicmaster has a dynamic ip allocation but I actually want a fixed ip. So I have to change that. Let’s first show my ip configuration.

[me@archlinux~]$ azure network nic ip-config list ResGroup1 nicmaster
info:    Executing command network nic ip-config list
+ Looking up the network interface "nicmaster"                                 
data:    Name               Provisioning state  Primary  Private IP allocation  Private IP version  Private IP address  Subnet      Public IP
data:    -----------------  ------------------  -------  ---------------------  ------------------  ------------------  ----------  ---------
data:    default-ip-config  Succeeded           true     Dynamic                IPv4                111.111.111.4       vnet1-sub1           
info:    network nic ip-config list command OK

You can see that I have a configuration called “default-ip-config” which was created automatically. As the output of the command reveals, you might have multiple ip configurations per NIC. You may find more information about this here: https://azure.microsoft.com/en-us/documentation/articles/virtual-network-multiple-ip-addresses-powershell/. I only have one configuration, the default one, which I want to change. But as the first and the last address are reserved, I will use 111.111.111.10 as static ip instead:

[me@archlinux ~]$ azure network nic ip-config set ResGroup1 nicmaster default-ip-config -a 111.111.111.10
info:    Executing command network nic ip-config set
+ Looking up the network interface "nicmaster"                                 
+ Updating network interface "nicmaster"                                       
data:    Id                              : /subscriptions/ad8e1a7b-65f0-464d-833a-79fd4d1610ed/resourceGroups/ResGroup1/providers/Microsoft.Network/networkInterfaces/nicmaster
data:    Name                            : nicmaster
data:    Type                            : Microsoft.Network/networkInterfaces
data:    Location                        : westeurope
data:    Provisioning state              : Succeeded
data:    MAC address                     : 00-0D-3A-24-97-A1
data:    Internal domain name suffix     : lbiu5q0vqeau1dttbvswk3czcb.ax.internal.cloudapp.net
data:    Enable IP forwarding            : false
data:    Virtual machine                 : /subscriptions/ad8e1a7b-65f0-464d-833a-79fd4d1610ed/resourceGroups/ResGroup1/providers/Microsoft.Compute/virtualMachines/master
data:    IP configurations:
data:      Name                          : default-ip-config
data:      Primary                       : true
data:      Provisioning state            : Succeeded
data:      Private IP address            : 111.111.111.10
data:      Private IP version            : IPv4
data:      Private IP allocation method  : Static
data:      Subnet                        : /subscriptions/ad8e1a7b-65f0-464d-833a-79fd4d1610ed/resourceGroups/ResGroup1/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/vnet1-sub1
data:     
info:    network nic ip-config set command OK

Virtual Maschine (again)

After I have done the necessary configuration for the NIC, I try to create the vm again:

[me@archlinux ~]$azure vm create --resource-group ResGroup1 -n master -l westeurope -y linux --image-urn Canonical:UbuntuServer:16.04.0-LTS:16.04.201609220 --nic-name nicmaster --admin-password <password> --admin-username adrian
info:    Executing command vm create
+ Looking up the VM "master"
info:    Using the VM Size "Standard_DS1"
info:    The [OS, Data] Disk or image configuration requires storage account
+ Retrieving storage accounts
info:    Could not find any storage accounts in the region "westeurope", trying to create new one
+ Creating storage account "cli50a82ef6474bdb2314752" in "westeurope"
+ Looking up the storage account cli50a82ef6474bdb2314752
+ Looking up the NIC "nicmaster"
info:    Found an existing NIC "nicmaster"
info:    Found an IP configuration with virtual network subnet id "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/ResGroup1/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/vnet1-sub1" in the NIC "nicmaster"
info:    This is an NIC without publicIP configured
info:    The storage URI 'https://cli50a82ef6474bdb2314752.blob.core.windows.net/' will be used for boot diagnostics settings, and it can be overwritten by the parameter input of '--boot-diagnostics-storage-uri'.
+ Creating VM "master"
info:    vm create command OK

Two things you may have observed in the log above. First, another storage account has been created. Not nice, but this could have been probably avoided, specifying storage parameters to the vm create command. Second, the NIC “nicmaster” does not have a publicIP configured, but this is no big deal for now. Let’s check in the portal what I have created so far:

Azure Resources in Portal

Storage Accounts

As already mentioned above, when you create (or try to create) a vm, a storage account is created. A storage account gives you access to the Azure Storage service like Tables, Queues, Files, Blobs and Azure virtual machine disks. As always, checkout for details in the official documentation.

Azure Storage Concepts (c) Microsoft

The storage account list can be queried in order to see more details. It usually has an unique name and is associated to a Resource Group and a location. As the storage account was implicitly created it took the same location as the vm we create earlier.

[me@archlinux~]$ azure storage account list
info:    Executing command storage account list
+ Getting storage accounts                                                     
data:    Name                      SKU Name      SKU Tier  Access Tier  Kind     Encrypted Service  Location    Resource Group
data:    ------------------------  ------------  --------  -----------  -------  -----------------  ----------  --------------
data:    cli50a82ef6474bdb2314752  Standard_LRS  Standard               Storage                     westeurope  resgroup1     
data:    clic073d5e0f8b392ac14751  Standard_LRS  Standard               Storage                     westeurope  resgroup1     
info:    storage account list command OK

We can even dig further and get more details:

[me@archlinux ~]$  azure storage account show cli50a82ef6474bdb2314752 -g ResGroup1
info:    Executing command storage account show
+ Getting storage account
data:    Name: cli50a82ef6474bdb2314752
data:    Url: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/resgroup1/providers/Microsoft.Storage/storageAccounts/cli50a82ef6474bdb2314752
data:    Type: Microsoft.Storage/storageAccounts
data:    SKU Name: Standard_LRS
data:    SKU Tier: Standard
data:    Kind: Storage
data:    Resource Group: resgroup1
data:    Location: westeurope
data:    Provisioning State: Succeeded
data:    Primary Location: westeurope
data:    Primary Status: available
data:    Secondary Location: undefined
data:    Creation Time: Thu, 29 Sep 2016 12:46:12 GMT
data:    Primary Endpoints: blob https://cli50a82ef6474bdb2314752.blob.core.windows.net/
data:    Primary Endpoints: queue https://cli50a82ef6474bdb2314752.queue.core.windows.net/
data:    Primary Endpoints: table https://cli50a82ef6474bdb2314752.table.core.windows.net/
data:    Primary Endpoints: file https://cli50a82ef6474bdb2314752.file.core.windows.net/
info:    storage account show command OK

So how the storage is used then. When quering the disks using the disk command for the vm there is actually no disk shown.

[me@archlinux ~]$ azure vm disk list ResGroup1 master
info:    Executing command vm disk list
+ Looking up the VM "master"
warn:    No data disks found
info:    vm disk list command OK

This is cause the disk command only queries for data disks. But what actually was created was an os disk as the documentation reveals:

Just like any other computer, virtual machines in Azure use disks as a place to store an operating system, applications, and data. All Azure virtual machines have at least two disks – a Linux operating system disk (in the case of a Linux VM) and a temporary disk. The operating system disk is created from an image, and both the operating system disk and the image are actually virtual hard disks (VHDs) stored in an Azure storage account. Virtual machines also can have one or more data disks, that are also stored as VHDs. This article is also available for Windows virtual machines.

Later we can read

The VHDs used in Azure are .vhd files stored as page blobs in a standard or premium storage account in Azure. For details about page blobs, see Understanding block blobs and page blobs.

Before we continues, remember the picture above, where you can see that blobs are stored in containers. So let’s query to see whether we have also a container for the recently created storage account.

[me@archlinux ~]$ azure storage container list
info:    Executing command storage container list
error:   Please set the storage account parameters or one of the following two environment variables to use the storage command.
  1. AZURE_STORAGE_CONNECTION_STRING
  2. AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY

We have to set some environment variables. The AZURE_STORAGE_ACCOUNT we already have, but we are missing the access key. Access keys are provided for each storage account and can be easily queried.

[me@archlinux~]$ azure storage account keys list cli50a82ef6474bdb2314752 -g ResGroup1
info:    Executing command storage account keys list
+ Getting storage account keys                                                 
data:    Name  Key                                                                                       Permissions
data:    ----  ----------------------------------------------------------------------------------------  -----------
data:    key1  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  Full       
data:    key2  yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy  Full       
info:    storage account keys list command OK

So we need to set the necessary environment variables and then we can query the container.

[me@archlinux ~]$ export AZURE_STORAGE_ACCOUNT=cli50a82ef6474bdb2314752
[me@archlinux ~]$ AZURE_STORAGE_ACCESS_KEY=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
[me@archlinux ~]$ azure storage container list
info:    Executing command storage container list
+ Getting storage containers                                                   
data:    Name                                                         Public Access  Last Modified                
data:    -----------------------------------------------------------  -------------  -----------------------------
data:    bootdiagnostics-master-564ba2fd-5beb-4635-8d64-13fdad5b0ba6  Off            Fri, 30 Sep 2016 14:02:44 GMT
data:    vhds                                                         Off            Fri, 30 Sep 2016 14:02:45 GMT
info:    storage container list command OK

So we have actually two containers. The first one - bootdiagnostics - contains boot diagnostics data, an option which is enabled by default for newly created VMs. The bootdiagnostics can be easily seen in the Azure portal but I did not yet check how to handle (read) the boot log from cli. The second container is called vhds and contains the actual OS disk

[me@archlinux ~]$ azure storage blob list vhds
info:    Executing command storage blob list
+ Getting blobs in container vhds                                              
data:    Name                                                Blob Type  Length       Content Type              Last Modified                  Snapshot Time
data:    --------------------------------------------------  ---------  -----------  ------------------------  -----------------------------  -------------
data:    cli50a82ef6474bdb23-os-1475244126973.vhd            PageBlob   31457280512  application/octet-stream  Wed, 05 Oct 2016 06:52:17 GMT               
data:    master.564ba2fd-5beb-4635-8d64-13fdad5b0ba6.status  BlockBlob  246          application/octet-stream  Wed, 05 Oct 2016 06:51:59 GMT               
info:    storage blob list command OK

Status and Next Steps

So I have created my first resources and my first vm is up and running.

master boot log
Jenkins Setup in Azure Details

I also have a better picture of the setup with the different azure resources. But as you can see, I’m not yet done and there are some more steps ahead of me

  • Connect to the VM
  • Create missing VMs node1 and node2
  • Deploy Jenkins and Jenkins-Slaves

Conclusion (so far)

Just starting to create your resources ad-hoc is fine for just playing around. But when you want to use Azure in your company environment, carefully think about the main resources and plan them carefully in advance.

  1. Resource groups: They serve as a container for your resources and enable managing them as a group e.g. for access permissions. Plan the carefully according to your resource needs and your company structure.
  2. Virtual Networks: Think about what isolated networks you need, how they shall or shall not be inter-connected and also connected to your on-premise network. Do also not forget to think about the regional location of your network resources and network security groups.
  3. Storage: Think about your storage needs and distribution of the storage among locations
  4. Keep in mind the prices - especially for VMs and storage - and think carefully what do you really need. The higher the resources, the higher the prices.