Infrastruktur ist Code

DevOps: Cloud-Automatisierung mit dem Azure Resource Manager
Kommentare

Software statt Hardware: Es ist nicht so lange her, da verschwanden kleine Armeen an Administratoren in den Tiefen der Rechenzentren, um dort für größere IT-Projekte Netzwerke zu installieren, Server anzuschließen, virtuelle Maschinen aufzusetzen, Cluster zu konfigurieren und vieles mehr. Alle diese Dinge in Form physischer Geräte und Kabelverbindungen zu installieren, ist in der Praxis mittlerweile angesichts des Umfangs und der Komplexität moderner Serverumgebungen undenkbar. Das Resultat wäre in Sachen Installation und Wartung viel zu träge und teuer.

Softwaresysteme bestehen in der Praxis schon lange nicht mehr aus einem einzelnen Server mit einer Hand voll Clients. Ausfallsichere Cluster sind heute der Normalfall, nicht die Ausnahme. Automatisch skalierende Webserverfarmen kümmern sich um Web Services. Riesige Storage-Cluster bieten die notwendige Speicherkapazität. Verteilte Netzwerkstrukturen mit Firewalls, Load Balancern und VPN-Gateways verbinden die Server und sichern sie gegen unerlaubten Zugriff. Es ist eine Herausforderung für Administratoren, diese Komplexität zu meistern. Neue Werkzeuge sind notwendig, um die Cloud-Infrastrukturen aufzubauen und zu warten. Die Azure-Cloud von Microsoft hat durch Einführung des Azure Resource Manager (ARM) in dieser Hinsicht beeindruckende Schritte nach vorne gemacht. Werfen Sie mit mir einen Blick auf dieses neue Tool, das die Arbeit von DevOps-Teams in Azure massiv beeinflussen wird.

In der Cloud hat sich die Situation radikal verändert. Heutige Cloud-Rechenzentren sind „Software-driven“. Herumklicken in einem Verwaltungsportal, etwas Geduld, und schon sind selbst komplexe Infrastrukturen zur Verwendung bereit. In DevOps-Teams wurde selbst das manuelle Klicken im Portal durch Scripts in PowerShell, Bash und Co. automatisiert, damit Infrastrukturen wiederholbar aufgebaut werden können. Dadurch wurden ganz neue Szenarien und Geschäftsmodelle möglich. Hier einige Beispiele:

  • Global agierende Firmen können standardisierte IT-Umgebungen problemlos in vielen Rechenzentren auf der ganzen Welt installieren.
  • In Multi-Tenant-Systemen können die Initialkosten zum Aufsetzen einer Tenant-Umgebung radikal gesenkt werden.
  • Betriebskosten für Testsysteme werden gesenkt, da komplexe Testumgebungen automatisiert auf- und nach Verwendung rasch wieder abgebaut werden können.
  • Fehler werden vermieden, da schon in der Entwicklung bei Bedarf produktionsgleiche Serverumgebungen installiert werden.

Schnell und überall: Datenzugriff mit Entity Framework Core 2.0

Dr. Holger Schwichtenberg (www.IT-Visions.de/5Minds IT-Solutions)

C# 7.0 – Neues im Detail

Christian Nagel (CN innovation)

Auch Microsoft hat diesem Trend in Azure von Anfang an Rechnung getragen. Egal, ob unter Windows mit Azure PowerShell oder unter Mac OS und Linux mit Azure CLI, man kann seit Langem fast alle Azure-bezogenen Aufgaben automatisieren.

Der nächste Schritt

Wenn in Azure sowieso schon alles automatisierbar ist, wozu eine vollkommen neue Plattform für Automatisierung? Der Grund dafür liegt im starken Wachstum der Azure-Plattform und der darauf betriebenen Systeme. Das ursprüngliche Azure Service Management ist entstanden, als Azure aus einer Hand voll Rechenzentren und einer überschaubaren Menge an Services bestanden hat. Typische Cloud-Lösungen in Azure hatten typischerweise wenige Komponenten. Multi-Region Deployments waren möglich, aber selten.

Azure hat sich seit seinem Erscheinen stark verändert. Heute besteht Azure aus 24 Data-Center-Regionen verteilt über die ganze Welt. Im September 2015 hat Microsoft bekanntgegeben, dass man über 90 000 neue Azure Subscriptions pro Monat verzeichnet hat. Die Anzahl der SQL-Datenbankcluster in Azure überschritt die 1,5-Millionen-Marke. In Azure Active Directory waren über 475 Millionen Benutzerkonten gespeichert. Will man als Azure-Neuling jedes der gebotenen Services nur einmal ausprobieren, muss man sich dafür viele Tage Zeit nehmen, so umfangreich ist das Angebot mittlerweile. Im Rahmen von Partnerschaften stehen mittlerweile auch Drittanbieterservices in Azure zur Verfügung.

Mit dem Wachstum von Azure wurden auch die Anwendungen, die in Azure laufen, größer und komplexer. Mehr Komponenten pro Anwendung, komplexere Netzwerkstrukturen und höhere Anforderungen an Sicherheit und Nachvollziehbarkeit sind nur drei Beispiele für die Folgen daraus.

Azure Service Management, wie man es von den Anfangstagen von Azure kannte, ist für diese Rahmenbedingungen nicht mehr zeitgemäß. Aus diesem Grund hat Microsoft den Azure Resource Manager (ARM) entwickelt.

Das Grundkonzept von ARM

Abbildung 1 zeigt ein Architekturdiagramm von ARM. Die wichtigste Komponente ist der Resource Manager. Er nimmt Anforderungen zur Installation oder Wartung von Systemkomponenten aus dem Azure Portal (Abb. 2), von Scripts (siehe außerdem hier und hier) oder von Visual Studio entgegen. Die Anforderungen betreffen nicht nur einzelne Komponenten wie virtuelle Maschinen, Datenbankserver oder Storage-Accounts. Man kann dem Resource Manager mit einer einzelnen Anforderung die Anweisung zum Erstellen vieler Komponenten (selbst tausende sind möglich) erteilen.

Abb. 1: ARM Architekturdiagramm (Quelle: Microsoft)

Abb. 1: ARM Architekturdiagramm (Quelle: Microsoft)

Die Komponenten, die der Resource Manager erstellt, werden in Verwaltungseinheiten zusammengefasst, die man Resource Groups nennt. Typischerweise fasst man die Komponenten einer Anwendungsumgebung (z. B. Buchhaltung Produktivumgebung, CRM-Testumgebung etc.) zu einer Resource Group zusammen.

Abb. 2: Auswahl des Resource Manager im neuen Azure-Portal

Abb. 2: Auswahl des Resource Manager im neuen Azure-Portal

Der Resource Manager orchestriert im Hintergrund Web Services, die die einzelnen Azure-Dienste anbieten (in Abbildung 1 als Provider Rest Points bezeichnet). Beispiele dafür sind Azure Compute (z. B. virtuelle Maschinen), Azure App Services (z. B. Web-Apps), Azure SQL Database, Azure Networking, Azure Storage etc. Die Provider Rest Points müssen nicht zwangsläufig von Microsoft kommen. Auch Drittanbieterdienste, die in Azure betrieben werden, stehen dem Resource Manager zur Verfügung.

Eine weitere Besonderheit des Resource Manager ist die Role-based Security. Administratoren können Rollen zugeordnet werden, und diese Rollen haben dann definierte Rechte in Resource Groups. Ein Administrator kann also in einer Resource Group „Buchhaltung“ alle Rechte haben, in der Resource Group „CRM“ jedoch die Konfiguration nur ansehen können. Natürlich bildet das Azure Active Directory die Grundlage für die Authentifizierung, damit man beispielsweise Single Sign-on und Multi-Factor-Authentication verwenden kann.

Der Resource Manager steht heute nur in Azure zur Verfügung. Microsoft hat aber angekündigt, dass er in zukünftigen Versionen auch in Private-Clouds, also lokalen Rechenzentren, zur Verfügung stehen wird. Konkrete Angaben dazu fehlen aber noch.

ARM-Templates

Wie oben erwähnt, bestehen Cloud-Anwendungen heute aus vielen verschiedenen Komponenten. Will man das Anlegen der Komponenten automatisieren, schreibt man Scripts. Diese Möglichkeit gibt es auch bei ARM. Listing 1 zeigt auszugsweise ein ARM-PowerShell-Script, mit dem man eine virtuelle Maschine in Azure inklusive deren Voraussetzungen wie Storage-Account, Netzwerk etc. anlegen kann. Interessierte finden den kompletten Sourcecode des Scripts auf GitHub. Wie man sieht, sind nur wenige Zeilen Scriptcode notwendig, um die gestellte Aufgabe zu lösen.

Listing 1
$rg = "RG-Simple-VM-Imp"
$location = "northeurope"
$storName = "devopscon15imp"
$ipName = "SimpleVMPublicIP"
...
New-AzureRmResourceGroup -Name $rg -Location $location
$storAcc = New-AzureRmStorageAccount -Name $storName -ResourceGroupName $rg ...
$ipAddress = New-AzureRmPublicIpAddress -Name $ipName -ResourceGroupName $rg ...
$subnet = New-AzureRmVirtualNetworkSubnetConfig -ResourceGroupName $rg ...
$nic = New-AzureRmNetworkInterface -ResourceGroupName $rg -Name $nicName ...
$cred = Get-Credential -UserName "rainer" -Message "Password for new VM"
$vmConfig = New-AzureRmVMConfig -VMName $vmName -VMSize $vmSize |
  Set-AzureRmVMOperatingSystem -Windows -ComputerName $vmName ... |
  Set-AzureRmVMSourceImage -PublisherName $imagePublisher ... |
  Set-AzureRmVMOSDisk -Name "osDisk" -Caching ReadWrite ... |
  Add-AzureRmVMNetworkInterface -Id $nic.Id
New-AzureRmVM -ResourceGroupName $rg -Location $location -VM $vmConfig

Der in Listing 1 gezeigte Ansatz mit Scripts ist gangbar für kleine überschaubare Infrastrukturen. Wenn es jedoch darum geht, eine größere Anzahl an Komponenten zu deployen, ist es schwierig, die Laufzeit durch Parallelisierung zu optimieren. Als Scriptautor muss man sich selbst um das parallele Anlegen voneinander unabhängiger Systemkomponenten kümmern – keine leichte Aufgabe. Scripts sind außerdem eine gewisse Hürde, wenn in einem Team noch keine PowerShell-Kenntnisse vorhanden sind.

Aus diesem Grund hat Microsoft für ARM eine neue, JSON-basierende Sprache zum Ressourcenmanagement entwickelt: ARM-Templates. ARM-Templates sind deklarativ. Das bedeutet, dass man die gewünschte Infrastruktur inklusive der Abhängigkeiten der Komponenten untereinander beschreibt, ohne sich um die Details des Deployment-Algorithmus zu kümmern. Das Ableiten des Algorithmus inklusive Parallelisierung, Schleifen, Fehlerbehandlung etc. übernimmt der Resource Manager.

ARM-Templates sind außerdem idempotent. Führt man sie mehrfach aus, geht nichts kaputt. Ressourcen, die schon vorhanden sind, werden nicht verändert. Nur neue Ressourcen werden angelegt bzw. neue Konfigurationseinstellungen angewandt.

Struktur von ARM-Templates

Ein ARM-Template besteht auf oberster Ebene aus folgenden Teilen:

  1. Verweis auf das JSON Schema und Versionsnummer.
  2. Parameters: Parameter sind Platzhalter im ARM-Template. Anstatt ihre Werte fix im Templatecode zu hinterlegen, können sie beim Deployment des Templates in einer Parameterdatei angegeben werden. Anwendungsbeispiele für Parameter sind Benutzernamen, Ressourcennamen, gewünschte Betriebssystemversion einer VM, Data-Center-Region etc.
  3. Variables: Ähnlich wie Parameter sind Variablen Platzhalter im Template. Ihr Wert ist jedoch im Template festgelegt. Insofern sind sie für Fälle gedacht, in denen ein Wert (z. B. der Name eines virtuellen Netzwerks) mehrfach im Template benötigt wird.
  4. Resources: Dieser Abschnitt ist das Herzstück eines ARM-Templates. Hier werden alle benötigten Ressourcen definiert, Abhängigkeiten festgelegt etc.
  5. Outputs: Dieser letzte Abschnitt des Templates dient dazu, die Rückgabewerte des Templates zu definieren. Das ist besonders wichtig, da Templates auf andere Templates verweisen können und man dadurch Struktur in große Projekte bringen kann.

Listing 2 zeigt auszugsweise ein ARM-Template, das inhaltlich vergleichbar mit dem PowerShell-Script aus Listing 1 ist. Interessierte finden den kompletten Sourcecode des Scripts auf GitHub. Achten Sie beim Durchsehen besonders auf die Verwendung von Parametern und Variablen sowie die Definition von Abhängigkeiten der Ressourcen untereinander.

Listing 2
{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "newStorageAccountName": {
      "type": "string",
      "metadata": {
        "description": "Unique DNS Name for the Storage Account for VMs."
      }
    },
    "windowsOSVersion": {
      "type": "string",
      "defaultValue": "2012-R2-Datacenter",
      "allowedValues": [
        "2008-R2-SP1",
        "2012-Datacenter",
        "2012-R2-Datacenter"
      ],
      "metadata": {
        "description": "The Windows version for the VM."
      }
    },
    ...
  },
  "variables": {
    "location": "northeurope",
    "imagePublisher": "MicrosoftWindowsServer",
    ...
    "vnetID": "[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
    "subnetRef": "[concat(variables('vnetID'), '/subnets/', variables('subnetName'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[parameters('newStorageAccountName')]",
      "apiVersion": "2015-05-01-preview",
      "location": "[variables('location')]",
      "tags": { "Topic": "Windows Developer Samples", "Category": "Samples" },
      "properties": {
        "accountType": "[variables('storageAccountType')]"
      }
    },
    {
      "apiVersion": "2015-05-01-preview",
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "[variables('publicIPAddressName')]",
      "location": "[variables('location')]",
      "tags": { "Topic": "Windows Developer Samples", "Category": "Samples" },
      "properties": {
        "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
        "dnsSettings": {
          "domainNameLabel": "[parameters('dnsNameForPublicIP')]"
        }
      }
    },
    ...
    {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[variables('vmName')]",
      "location": "[variables('location')]",
      "tags": { "Topic": "Windows Developer Samples", "Category": "Samples" },
      "dependsOn": [
        "[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]",
        "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[variables('vmSize')]"
        },
        "osProfile": {
          "computerName": "[variables('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "[variables('imagePublisher')]",
            "offer": "[variables('imageOffer')]",
            "sku": "[parameters('windowsOSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "name": "osdisk",
            "vhd": {
              "uri": "[concat('http://', parameters('newStorageAccountName'), '.blob.core.windows.net/', variables('vmStorageAccountContainerName'), '/', variables('OSDiskName'), '.vhd')]"
            },
            "caching": "ReadWrite",
            "createOption": "FromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
            }
          ]
        },
        "diagnosticsProfile": {
          "bootDiagnostics": {
             "enabled": "true",
             "storageUri": "[concat('http://', parameters('newStorageAccountName'), '.blob.core.windows.net')]"
          }
        }
      }
    }
  ]
}

Nicht nur IaaS, auch PaaS

Schlussfolgern Sie aus den gezeigten Listings nicht, dass ARM-Templates nur etwas für Infrastructure as a Service (IaaS), also VMs und verbundene Technologien, sind. Sie können mit ARM-Templates auch ohne weitere PaaS-Komponenten wie Azure SQL Database Cluster, Azure App Service Web Apps etc. deployen. Es würde den Rahmen dieses Artikels sprengen, für alle diese Dinge Beispiele abzudrucken. Interessierte finden aber ein Beispiel für ein ARM-Template mit PaaS in meinem GitHub Repository.

Grenzen von ARM

ARM ist dazu da, die Infrastruktur für Cloudlösungen aufzubauen und zu konfigurieren. Es ist nicht Aufgabe von ARM, eventuell notwendige Konfigurationen innerhalb virtueller Maschinen vorzunehmen. Dafür greift ARM auf externe Scripts (PowerShell DSC unter Windows und Shell-Scripts unter Linux) zurück. Listing 3 und Listing 4 zeigen zwei Beispiele. Das erste verwendet PowerShell DSC, um in einem Windows Server IIS mit Web Deploy einzurichten. Das zweite konfiguriert einen Reverse-Proxy mithilfe des Linux-Service nginx. Interessierte finden die kompletten Beispiele hier und hier.

Listing 3
...
{
  "apiVersion": "2015-06-15",
  "type": "Microsoft.Compute/virtualMachines",
  "name": "[variables('windowsVmName')]",
  ...
},
{
  "type": "Microsoft.Compute/virtualMachines/extensions",
  "name": "[concat(variables('windowsVmName'),'/Microsoft.Powershell.DSC')]",
  "apiVersion": "2015-05-01-preview",
  "location": "[parameters('location')]",
  "dependsOn": [
  "[resourceId('Microsoft.Compute/virtualMachines',  variables('windowsVmName'))]"
  ],
  "properties": {
  "publisher": "Microsoft.Powershell",
  "type": "DSC",
  "typeHandlerVersion": "2.8",
  "settings": {
    "ModulesUrl": "https://raw.githubusercontent.com/rstropek/.../IisDSC.zip",
    "ConfigurationFunction": "IisDSC.ps1\\IisDSC"
  }
  }
}
Listing 4
{
  "apiVersion": "2015-05-01-preview",
  "type": "Microsoft.Compute/virtualMachines",
  "name": "[variables('nginxVmName')]",
  ...
},
{
  "type": "Microsoft.Compute/virtualMachines/extensions",
  "name": "[concat(variables('nginxVmName'),'/newuserscript')]",
  "apiVersion": "2015-05-01-preview",
  "location": "[parameters('location')]",
  "dependsOn": [
  "[concat('Microsoft.Compute/virtualMachines/', variables('nginxVmName'))]"
  ],
  "properties": {
  "publisher": "Microsoft.OSTCExtensions",
  "type": "CustomScriptForLinux",
  "typeHandlerVersion": "1.2",
  "settings": {
    "fileUris": [
    "https://raw.githubusercontent.com/rstropek/.../setupReverseProxy.sh"
    ],
    "commandToExecute": "sh setupReverseProxy.sh"
  }
  }
}

Entwickeln von ARM-Templates

Die angenehmste Entwicklungsumgebung für ARM-Templates ist Visual Studio 2015. Wenn man das Azure-SDK für Visual Studio installiert, erhält man den neuen Projekttyp Azure Resource Group. Wählt man diesen aus, kann man aus einer Liste an Vorlagen wählen, die von virtuellen Maschinen (Windows und Linux) bis hin zu PaaS-Services wie Azure Web Sites reichen. Für die weitere Bearbeitung der Templates bietet Visual Studio IntelliSense für die ARM-Template-Sprache sowie Assistenten zum Hinzufügen zusätzlicher Ressourcen (Abb. 3).

Abb. 3: ARM-Template in Visual Studio 2015

Abb. 3: ARM-Template in Visual Studio 2015

Eine wichtige Quelle für ARM-Template-Muster mit zugehörigen Scripts findet sich auf GitHub. Hier haben viele Azure-Expertinnen und Experten Beispiele zusammengetragen, die man als Ausgangspunkt für eigene Projekte, zum Lernen von Best Practices oder zum direkten Verwenden nutzen kann.

Der dritte Tipp, den ich zum Einstieg in ARM noch geben möchte, ist der Hinweis auf den Azure Resource Explorer (Abb. 4). Es handelt sich dabei um eine Webseite, mit der Sie Ihre existierenden Resource Groups relativ einfach in ARM-Templates oder PowerShell-Scripts umwandeln können. Zugegeben, die Scripts brauchen noch einiges an Nacharbeit. Sie sind aber ein guter Startpunkt, wenn man zum Beispiel manuell angelegte Ressourcen im Nachhinein in Scripts umwandeln möchte.

Abb. 4: Azure Resource Explorer

Abb. 4: Azure Resource Explorer

Fazit

Automatisierung spielt in der Cloud eine große Rolle. Schließlich will man IT-Infrastrukturen stabil wiederholbar anlegen können, um zum Beispiel neue Data Center Regions auszurollen, Testumgebungen einzurichten, neue Tenants an Bord zu bringen und vieles mehr. ARM und insbesondere ARM-Templates sind ein hervorragendes Werkzeug dafür. Ohne tiefgehendes PowerShell-Know-how zu benötigen, beschreibt man die Komponenten, die sein Softwaresystem voraussetzt. Der Resource Manager orchestriert auf dieser Basis die zugrunde liegenden Azure-Dienste, damit die gewünschte IT-Infrastruktur so effizient wie möglich deployt wird.

Die Entwicklung von ARM-Templates wird in Visual Studio durch Projekttypen und IntelliSense unterstützt. Außerdem stellt Microsoft eine umfangreiche Beispielsammlung auf GitHub zur Verfügung, auf der man bei der Entwicklung eigener Templates aufbauen kann. Trotzdem bleiben aber in der Praxis noch einige Ecken und Kanten, die Microsoft noch glätten muss. Zu oft findet man Azure-Dienste, für die weder Visual Studio einen Assistenten noch GitHub ein Beispiel bereithalten. Dann heißt es experimentieren und andere Azure-Poweruser um Rat zu fragen.

Alles in allem sind ARM und ARM-Templates eine große Verbesserung für Azure. Die Plattform wird durch sie für weiteres Wachstum bereit – sowohl auf Seiten von Microsoft als auch auf Kundenseite.

Windows Developer

Windows DeveloperDieser Artikel ist im Windows Developer erschienen. Windows Developer informiert umfassend und herstellerneutral über neue Trends und Möglichkeiten der Software- und Systementwicklung rund um Microsoft-Technologien.

Natürlich können Sie den Windows Developer über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist der Windows Developer ferner im Abonnement oder als Einzelheft erhältlich.

Aufmacherbild: electric background von Shutterstock / Urheberrecht: winui

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -