Azure SQL per PowerShell

So, mal wieder Zeit, sich den nächsten Azure Service anzuschauen, diesmal habe ich mich für Azure SQL entschieden. Microsoft bezeichnet das ja als “eine relationale, als Dienst bereitgestellte Datenbank (Database-as-a-Service) in der Cloud”, und eigentlich ist damit alles gesagt. Einfacher ausgedrückt: Ein großer SQL-Server Cluster (ein sehr großer), den man einfach nutzen kann, ohne sich um Hochverfügbarkeit, Cluster, Updates, etc kümmern zu müssen. “aaS” eben. Also dann, los geht’s:

Wir beschränken uns hier auf das Anlegen eines Servers und einer Datenbank, und das auch auf die klassische Variante (ASM, kein ARM, ich brauch auch noch Material für einen weiteren Blogartikel…). Der Zugriff auf die Datenbank erfolgt dann meistens sowieso direkt von einem Client aus. Aber auch das schauen wir uns am Ende noch kurz an…

Einen Datenbank-Server anlegen

Die Cmdlets für Azure SQL gehören zu den längsten Cmdlets in Azure PowerShell. Vielleicht eine gute Gelegenheit, sich mal mit dem Anlegen von Aliasen zu beschäftigen…

Das erste Cmdlet legt also einen Datenbank-Server an. Wir geben (wie üblich) eine Region mit an, und dann noch einen Administrator-User und ein Passwort:

new-azuresqldatabaseserver -Location "Germany Central" -AdministratorLogin "superman" -AdministratorLoginPassword "p@ssw0rd"

Nach kurzer Zeit kommt das Ergebnis unserer Bemühungen:

new-db-server

In der ersten Spalte sehen wir den Namen unseres Servers, den brauchen wir für zukünftige Cmdlets, daher merken wir uns den. Eine Liste unserer Datenbank-Server im gleichen Format wie oben zu sehen bekommen wir auch mit Get-AzureSqlDatabaseServer, falls wir den Namen mal vergessen haben.

Firewall-Regel einrichten

Noch ist der Server nicht ansprechbar, da steht eine Firewall davor, die erst mal alles blockt. Wir könnten jetzt natürlich den Zugang von überall her aufmachen, sicherer ist aber auf jeden Fall, wenn wir nur wenige Adressen nehmen, oder gar nur eine. Wir können bei Bedarf später auch weitere hinzufügen…

Stellt sich die Frage, wie bekommen wir unsere aktuelle (öffentliche) Adresse raus? Nun, da gibt es mehrere Möglichkeiten, ich nehme immer folgende Zeile:

$ip=(Invoke-WebRequest -Uri "https://api.ipify.org").content

Noch schnell einen Namen für die Regel ausdenken, und dann kann es losgehen:

New-AzureSqlDatabaseServerFirewallRule -RuleName "MyIpAddress" -ServerName "uqmusppji1" –StartIpAddress $ip –EndIpAddress $ip

Indem wir StartIPAddress und EndIPAddressgleich setzen, beschränken wir den Zugang auf diese eine IP-Adresse. Um weitere Dinge wie Ports oder Protokoll müssen wir uns nicht kümmern.

Wir sind jetzt bereit, uns zu unserem Azure SQL Datenbankserver zu verbinden.

Zum Datenbank-Server verbinden

Als erstes speichern wir unser Login mal in einer Variablen, Username und Passwort haben wir bei der Erstellung ja selbst angegeben.

$cred=Get-Credential

Ähnlich wie bei Storage erzeugen wir uns einen Kontext für den Zugriff auf den Server:

$context=New-AzureSqlDatabaseServerContext -ServerName "uqmusppji1" -Credential $cred

Wenn wir jetzt eine Fehlermeldung bekommen, dann war vielleicht die IP-Adresse in der Firewall-Regel doch falsch? Wir können aber – wie gesagt – jederzeit weitere Regeln hinzufügen. Ansonsten haben wir jetzt einen Kontext, mit dem wir weiterarbeiten können, zum Beispiel um eine Datenbank anzulegen.

Datenbank anlegen

Wir haben in den letzten Abschnitten einen Datenbank-Server angelegt, ein kleines Loch in die Firewall gebohrt, und einen Verbindungskontext hergestellt. Zeit für eine Datenbank, das war ja unser eigentliches Ziel…

New-AzureSqlDatabase -ConnectionContext $context -DatabaseName "MyDatabase"

Da gibt es noch weitere Optionen wie Collation, Edition oder MaxSizeGB, wir verwenden mal einfach die Standard-Einstellungen, die uns auch als Ergebnis angezeigt werden:

new-db

Verbindungszeichenfolge

Für eine Verbindung zu dieser Datenbank benötigen wir einen (handelsüblichen) sog. Connection String (die deutsche Übersetzung “Verbindungszeichenfolge” hab ich eigentlich nur zum Spaß in die Überschrift gesetzt…). Unter anderem beinhaltet der den Servernamen. Den Anfang des Namens kennen wir schon, den haben wir schließlich jetzt schon mehrfach verwendet. Aber wie lautet der Rest des Namens? Nun, eigentlich ganz einfach. Solche Angaben stehen immer im Azure Environment drin (Get-AzureEnvironment), das sich eben je nach Umgebung ändern kann. In den Beispielen (der aufmerksame Leser hat es vielleicht schon gemerkt) habe ich meinen Zugang zur Microsoft Cloud Deutschland verwendet, dort lauter der „SqlDatabaseDnsSuffix“ eben “.database.cloudapi.de”, in der weltweiten Azure Cloud “.database.windows.net”. Oder man frägt ihn einfach ab:

(get-azureenvironment -Name (get-azuresubscription -current).Environment).SqlDatabaseDnsSuffix

Ist PowerShell nicht einfach großartig?

Zusammen mit dem Servernamen haben wir jetzt alle Angaben, die wir brauchen. Die Connection Strings haben – je nachdem wo sie eingegeben werden müssen – verschiedene Formate, hier ist mal eines, dass wir auch direkt in PowerShell nutzen könnten (alles in einer Zeile):

$connectionString = "Server=tcp:uqmusppji1.database.cloudapi.de,1433;
DataBase=MyDatabase;User ID=superman@uqmusppji1;Password=p@ssw0rd;
Trusted_Connection=False;Encrypt=True;Connection Timeout=30;"

Aufpassen müssen wir an folgenden Stellen (keine Ahnung, wer sich das alles ausgedacht hat):

  • zwischen vollem Servernamen und dem Port (1433) steht ein Komma!
  • im Parameter User ID ist ein Leerzeichen zwischen User und ID
  • der Benutzer wird mit „@“ und dem Kurznamen des Servers angegeben
  • bei Trusted_Connection steht ein Unterstrich
  • bei Connection Timeout ist dagegen wieder eine Leerstelle
  • am Ende steht auch nochmal ein Semikolon;

Damit könnten wir jetzt eine Verbindung aufbauen:

$connection=New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionstring
$connection.Open()

Einfacher ist es aber sicher, wenn man einen der vielen möglichen SQL Clients nimmt (oder natürlich bevorzugt das SQL Server Management Studio) und dort die Verbindungsparameter eingibt. Ab da unterscheidet sich eigentlich nichts mehr von einem lokalen Microsoft SQL Server.

Aufräumen

Das Löschen von Datenbank-Servern geht ganz einfach (und eigentlich können wir das schon selbst herleiten):

Remove-AzureSqlDatabaseServer -ServerName uqmusppji1

Zum Glück kommt noch eine Sicherheitsabfrage, aber hinterher ist alles weg, einschließlich Firewall-Regeln und Datenbanken.

Auf githubhabe ich noch ein komplettes Script hinterlegt, das eine Datenbank anlegt, eine Tabelle erzeugt, mit ein paar Daten füllt und sie auch wieder ausliest.

War gar nicht schwer, oder? Viel Spaß beim Ausprobieren!