Cloud-Init for VMs in private and public Clouds

Initialize VMs in a vSphere private Cloud using Cloud-Init

Cloud-Init Datasource for VMware GuestInfo is deprecated

The Web is full of explanations, how to use „Cloud-Init Datasource for VMware GuestInfo“ but https://github.com/vmware-archive/cloud-init-vmware-guestinfo it is deprecated.

It is now integrated natively into Cloud-Init

Cloud-Init 21.3 has been released https://discourse.ubuntu.com/t/release-of-cloud-init-21-3/23857 which integrates this software.

New name:

I’d expect it to be in the current Ubuntu 21.10 (Impish Indri) https://cloud-images.ubuntu.com/impish/current/ – the release notes for 21.10 don’t specify the exact version.

Ubuntu 20.04 (Focal Fossa) is still at cloud-init 20.1-10 according to https://wiki.ubuntu.com/FocalFossa/ReleaseNotes which is too old.

Prepare a VM-Template

Unfortunately Ubuntu provides the „cloud“-images in OVA-Format.

Create VM-Template from OVA

Deploy

  • impish-server-cloudimg-amd64.ova

as

  • VM
  • keep all settings set to default

Customize VM

  • disable (or remove) the „Serial“-port
  • disable vApp-Properties
    • those would break the cloud-init process later on
    • VM=>Configure
    • Settings=>vApp-Options
    • disable [ ] vApp-Properties

Convert to Template

  • VM-Template „ubuntu-impish-21.10-cloudimg“.

Clone a VM from this VM-Template

This shouldn’t be done manually, I’d suggest using terraform

Verify that Cloud-Init 21.3 is available and the „VMware“-Datasource is included

Cloud-Init Version

Release 21.3 is available:

ubuntu@ubuntu:~$ cloud-init --version
/usr/bin/cloud-init 21.3-1-g6803368d-0ubuntu3

Check the Cloud-Init Datasource

Datasource „vmware“ is included:

ubuntu@ubuntu:~$ cloud-id
vmware

Microsoft Certified: Azure Solutions Architect Expert

Certification Path

According to https://docs.microsoft.com/en-us/learn/certifications/azure-solutions-architect/ two exams

are required.

Online Training

Online Training, free of charge – sponsored by Microsoft – is available: Surprisingly the same 9 modules for both exams, i’ve been putting them in a slightly different order:

  • Infrastructure
    • 4 Modules
  • Operations
  • Applications
    • 3 Modules
  • Migration
    • sharing a common module with
  • Business Continuity / Recovery
Azure Solutions Architect Expert – Training modules

AZ303 Instructor-Led Training

The official Microsoft Instructor-Led Training for AZ303 is made up of 15 Modules:

  1. Azure Active Directory
  2. Hybrid Identities
  3. Networking
  4. VMs
  5. Load Balancing and Network Security
  6. Storage Accounts
  7. NoSQL Databases
  8. Azure SQL Databases
  9. Automate Deployment and Configuration of Resources
  10. Azure Governance Solutions
  11. Security for Applications
  12. Manage Workloads in Azure
  13. Container-Based Applications
  14. Implement an Application Infrastructure
  15. Cloud Infrastructure Monitoring

Exam 303 – What might be the required skills?

The free training – 9 Modules for both AZ303 and AZ304 – the paid training for AZ303: 15 Modules:

  • how to map the 15 AZ303-Modules into the 9 AZ303/AZ304-Modules?

Azure Regions on Request

According to https://docs.microsoft.com/en-us/azure/best-practices-availability-paired-regions there is a Regional-Pair to „Germany West Central“ called „Germany North“ which is missing at https://azure.microsoft.com/en-us/global-infrastructure/geographies since access is restricted to support specific customer scenarios, for example in-country disaster recovery. These regions are available only upon request by creating a new support request in the Azure portal

Germany North could be found in the list (https://azure.microsoft.com/en-us/global-infrastructure/geographies/#new-regions) so it might be coming soon for general availability.

List available Azure-Locations

C:\RH> az account list-locations --query "[].{name:name}" -o table
Name
-------------------
eastus
eastus2
southcentralus
westus2
australiaeast
southeastasia
northeurope
uksouth
westeurope
centralus
northcentralus
westus
southafricanorth
centralindia
eastasia
japaneast
jioindiawest
koreacentral
canadacentral
francecentral
germanywestcentral
norwayeast
switzerlandnorth
uaenorth
brazilsouth
centralusstage
eastusstage
eastus2stage
northcentralusstage
southcentralusstage
westusstage
westus2stage
asia
asiapacific
australia
brazil
canada
europe
global
india
japan
uk
unitedstates
eastasiastage
southeastasiastage
centraluseuap
eastus2euap
westcentralus
westus3
southafricawest
australiacentral
australiacentral2
australiasoutheast
japanwest
koreasouth
southindia
westindia
canadaeast
francesouth
germanynorth
norwaywest
switzerlandwest
ukwest
uaecentral
brazilsoutheast

Azure-CLI: Download File from Fileshare

ronald@Azure:~$ az storage file list -s FILESHARE -o table
Name               Content Length    Type    Last Modified
-----------------  ----------------  ------  ---------------
DEMO.TXT           9                 file

ronald@Azure:~$ az storage file download -s FILESHARE -p DEMO.TXT
Finished[#############################################################]  100.0000%
{
  "content": null,
  "metadata": {},
  "name": "DEMO.TXT",
  "properties": {
    "contentLength": 9,
    "contentRange": "bytes 0-8/9",
    "contentSettings": {
      "cacheControl": null,
      "contentDisposition": null,
      "contentEncoding": null,
      "contentLanguage": null,
      "contentType": "application/octet-stream"
    },
    "copy": {
      "completionTime": null,
      "id": null,
      "progress": null,
      "source": null,
      "status": null,
      "statusDescription": null
    },
    "etag": "\"0x8D8EB06203D00A5\"",
    "lastModified": "2021-03-19T18:38:01+00:00",
    "serverEncrypted": true
  }
}

ronald@Azure:~$ cat DEMO.TXT
RONRONRON

Azure: Storage-Account

Create a Storage-Account

az storage account create \
  --resource-group RGTEST \
  --name $STORAGE_ACCOUNT_NAME \
  --sku Standard_LRS \
  --location westeurope

retrieve connection string

AZURE_STORAGE_CONNECTION_STRING=$(az storage account show-connection-string \
  --resource-group RGTEST \
  --name $STORAGE_ACCOUNT_NAME \
  --output tsv)

ronald@Azure:~$ echo $AZURE_STORAGE_CONNECTION_STRING
DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=mystorageaccount4108;AccountKey=HlLklNRxLsKRzLw28Tc8W+0MDPv2RON/Stic8Lu1ryu0XiLDizlZRVnpAVwoSkzA==

Retrieve the Storage_key

ronald@Azure:~$ STORAGE_KEY=$(az storage account keys list \
>   --resource-group RGTEST \
>   --account-name $STORAGE_ACCOUNT_NAME \
>   --query "[0].value" \
>   --output tsv)
ronald@Azure:~$ echo $STORAGE_KEY
HlLklNRxLsKRzLw28Tc8W+0MDPv2RONAVwoSkzA==

create a file-share:

az storage share create --name TESTSHARE

Azure CLI: Default-Values for config-Session

In most cases, at least some parameters for a set of CLI-Commands remain the same. Setting those as „default“ saves time and reduces human error.

For example, specify your location and ressource-group exactly one time and never repeat it:

ronald@Azure:~$ az configure --defaults group=RG-TEST location=westeurope

Disclaimer

Since i’m trying to get rid of Evernote, too anoying too often, i’ll start to document non-private-stuff here.

RG_NAME=RG_TEST
LOCATION_NAME=westeurope
az group create --resource-group $RG_NAME --location $LOCATION_NAME

az configure --defaults group=$RG_NAME location=$LOCATION_NAME

Create Cosmos-DB and retrieve Connection-String

Retrieve the Conection-String of the Endpoint:

ronald@Azure:~$ COSMOS_DB_ENDPOINT=$(az cosmosdb create \
>   --resource-group RGTEST \
>   --name $COSMOS_DB_NAME \
>   --query documentEndpoint \
>   --output tsv)

ronald@Azure:~$ echo $COSMOS_DB_ENDPOINT
https://aci-cosmos-db-4711.documents.azure.com:443/

Disclaimer

Since i’m trying to get rid of Evernote, too anoying too often, i’ll start to document non-private-stuff here.

ronald@Azure:~$ COSMOS_DB_MASTERKEY=$(az cosmosdb keys list \
>   --resource-group RGTEST \
>   --name $COSMOS_DB_NAME \
>   --query primaryMasterKey \
>   --output tsv)
ronald@Azure:~$ echo $COSMOS_DB_MASTERKEY
nVcsc0lq5troD9XgUl5RRONXUpaxX0pkK06qmDItkvXAUrRONyJHaasial3G8dajcc6tn6Y12i2D29tKP99CUw==

Disclaimer

Since i’m trying to get rid of Evernote, too anoying too often, i’ll start to document non-private-stuff here.

Azure – Pricing API

This is a really nice feature – the Azure Pricing REST-API:

https://docs.microsoft.com/en-us/rest/api/cost-management/retail-prices/azure-retail-prices

It pulls a structured JSON-Dataset for (not only) Virtual Machines out of the Azure-Webshop.

For example – the following filter:
https://prices.azure.com/api/retail/prices?$filter=serviceName eq ‚Virtual Machines‘ and priceType eq ‚Consumption‘ and endswith(armRegionName, ‚europe‘) and (startswith(skuName, ‚D‘) or startswith(skuName, ‚E‘) or startswith(skuName, ‚F‘) or startswith(skuName, ‚M‘)) and endswith(skuName,‘ Spot‘)
displays the price for only

  • „VMs“

with specific properties:

  • no Reservation
  • in „.*europe“-Locations
  • with Types „D.*“ or „E.*“ or „F.*“ or „M.*“
  • Spot-Intances

but – if you don’t want „Spot“ Instances, you’d guess this filter-Statement: https://prices.azure.com/api/retail/prices?$filter=serviceName eq ‚Virtual Machines‘ and priceType eq ‚Consumption‘ and endswith(armRegionName, ‚europe‘) and (startswith(skuName, ‚D‘) or startswith(skuName, ‚E‘) or startswith(skuName, ‚F‘) or startswith(skuName, ‚M‘)) and not endswith(skuName,‘ Spot‘)

to end with … and not endswith(skuName,‘ Spot‘) according to https://docs.microsoft.com/en-us/azure/search/search-query-odata-logical-operators but this breaks the call – the API returns :

{"Error":{"Code":"BadRequest","Message":"Invalid OData parameters supplied"}}