Drücke "Enter", um den Text zu überspringen.

Kategorie: Azure

Am Samstag beim Global Azure Bootcamp

Wer kommenden Samstag den 27. April 2019 noch nichts vor hat, dem sei das Global Azure Bootcamp, welches weltweit gleichzeitig an wahnsinnig vielen Orten stattfindet, nahegelegt.

Ich selbst werde in Jena sein, um beim dortigen Bootcamp über Opensource DevOps zu sprechen.

Die folgende Agenda mit spannenden Vorträgen erwartet euch dort:

10:00-10:15 Uhr – Begrüßung
10:15-11:15 Uhr – „Azure Governance – Das Regelwerk für Azure“ – Eric Berg
11:15-11:30 Uhr – Kaffeepause
11:30-12:30 Uhr – „Azure Kubernetes Services (AKS) und Azure DevOps“ – Mark Blume
12:30-13:00 Uhr – Mittag
13:00-14:00 Uhr – “Azure DevOps – aber in OpenSource” – Haiko Hertes
14:00-14:15 Uhr – Kaffeepause
14:15-15:15 Uhr – „Machine Learning in der Cloud mit Azure Machine Learning Service“ – Stefan Hellfritzsch

Wer mehr über das Global Azure Bootcamp und die anderen Locations erfahren möchte, der kann dies hier tun:
https://global.azurebootcamp.net/

Ich würde mich freuen, das eine oder andere bekannte Gesicht in Jena zu sehen.

Schreibe einen Kommentar...

Azure / PowerShell – Azure SQL Performance Empfehlungen per PowerShell abholen und verteilen

Azure und insbesondere Azure SQL ist klasse – es nimmt einem viele Dinge der täglichen Verwaltung ab, einiges davon sogar automatisch. Klar, das hat seinen Preis, immerhin ist Azure SQL nicht ganz billig, aber wenn man es schon bezahlt, dann kann man auch seine Fähigkeiten nutzen. Eine davon ist, automatisch anhand der Nutzung einer Datenbank Empfehlungen für die Leistungsoptimierung zu geben. Diese kann man sich im UI bzw. dem Azure Portal anschauen. Dazu öffnet man entweder links im Blade den Punkt „Recommondations“ unterhalb von „Intelligent Performance“ oder den Punkt „Performance“ auf der Main-Page bei den Notifications:

Dort sieht man dann einige Empfehlungen aufgeführt (vorausgesetzt, Azure hat etwas gefunden, was wiederum eine regelmäßige Nutzung der Datenbank voraussetzt):

Diese Daten kann man sich auch automatisch abrufen und auf Wunsch dann z.B. an die Entwickler verteilen. Dazu bediene ich mich einfach der PowerShell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
$ErrorActionPreference = "Stop"
$SubscriptionId = "YOUR_SUBSCRIPTION_ID"
 
function Get-SQLServerRecommendations()
{
    # Define the resource types
    $resourceTypes = ("Microsoft.Sql/servers/databases")
    $advisors = ("CreateIndex", "DropIndex","DbParameterization","SchemaIssue");
    $results = @()
 
    # Loop through all subscriptions
 
    $rgs = Get-AzureRmResourceGroup
 
    # Loop through all resource groups
    foreach($rg in $rgs) {
        $rgname = $rg.ResourceGroupName;
 
        # Loop through all resource types
        foreach($resourceType in $resourceTypes) {
            $resources = Get-AzureRmResource -ResourceGroupName $rgname -ResourceType $resourceType
 
            # Loop through all databases
            # Extract resource groups, servers and databases
            foreach ($resource in $resources) {
                $resourceId = $resource.ResourceId
                if ($resourceId -match ".*RESOURCEGROUPS/(?<content>.*)/PROVIDERS.*") {
                    $ResourceGroupName = $matches['content']
                } else {
                    continue
                }
                if ($resourceId -match ".*SERVERS/(?<content>.*)/DATABASES.*") {
                    $ServerName = $matches['content']
                } else {
                    continue
                }
                if ($resourceId -match ".*/DATABASES/(?<content>.*)") {
                    $DatabaseName = $matches['content']
                } else {
                    continue
                }
 
                # Skip if master
                if ($DatabaseName -eq "master") {
                    continue
                }
 
                # Loop through all Automatic tuning recommendation types
                foreach ($advisor in ($advisors -notmatch "SchemaIssue")) {
                    $recs = Get-AzureRmSqlDatabaseRecommendedAction -ResourceGroupName $ResourceGroupName -ServerName $ServerName  -DatabaseName $DatabaseName -AdvisorName $advisor
                    foreach ($r in $recs) {
                        if ($r.State.CurrentValue -eq "Active") {
                            $object = New-Object -TypeName PSObject
                            $object | Add-Member -Name 'SubscriptionId' -MemberType Noteproperty -Value $subscriptionId
                            $object | Add-Member -Name 'ResourceGroupName' -MemberType Noteproperty -Value $r.ResourceGroupName
                            $object | Add-Member -Name 'ServerName' -MemberType Noteproperty -Value $r.ServerName
                            $object | Add-Member -Name 'DatabaseName' -MemberType Noteproperty -Value $r.DatabaseName
                            $object | Add-Member -Name 'Advisor' -MemberType Noteproperty -Value $advisor
                            $object | Add-Member -Name 'Script' -MemberType Noteproperty -Value $r.ImplementationDetails.Script
                            $results += $object
                        }
                    }
                }
            }
        }
    }
    Return $results
}
 
$AzurePasswordSecure = ConvertTo-SecureString "$($YOUR_AZURE_PASSWORD)" -AsPlainText -Force
$AzureCredentials = New-Object System.Management.Automation.PSCredential ("$YOUR_AZURE_USER", $AzurePasswordSecure)
Connect-AzureRmAccount -Credential $AzureCredentials | Out-Null
Select-AzureRmSubscription -Subscription $SubscriptionId | Out-Null
 
$Recommendations = Get-SQLServerRecommendations
$table = $Recommendations | Sort-Object DatabaseName,Advisor | Format-Table Databasename,Advisor,Script -AutoSize -Wrap
Write-Output $table
 
$head = "<style>
td {background-color:lightgrey;}
table {width:100%;}
th {font-size:14pt;background-color:lightblue;}
</style>
<title>SQL Server performance recommendations</title>"
 
[string]$html = $Recommendations | ConvertTo-Html -Property Databasename,Advisor,Script -Body "<h1>Azure SQL Server automatic tuning recommendations for $stage</h1>Auto-generated by PUT_SOMETHING_HERE<br><br>" -Head $head
 
Send-MailMessage -Body $html -SmtpServer YOUR.SMTPSERVER.COM -From sender@domain.com -To recipient@domain.com -Subject "MS SQL Recommendations - $(Get-Date -Format "yyyy-dd-MM HH:mm:ss")" -BodyAsHtml

Dieses Script wiederum kann man dann z.B. per Jenkins regelmäßig auslösen. Oder alternativ ein Azure Automation Runbook dafür anlegen… Viel Spaß beim Ausprobieren!

Die Mails sehen dann in etwa so aus:

Schreibe einen Kommentar...

YouTube Videos zu Microsoft Azure

Wie ihr ggf. dem ein- oder anderen Blog-Artikel hier entnehmen könnt, beschäftige ich mich seit einigen Monaten sowohl berufsbedingt als auch aus eigenem Interesse mit Microsoft Azure. Als logische Konsequenz daraus habe ich jetzt bereits einige erste YouTube Videos aus diesem Umfeld aufgezeichnet und veröffentlicht. Ihr findet diese hier:

azure

Konkret geht es in den ersten Videos um ARM Templates und Azure CDN – weitere werden folgen! Schaut mal rein – ich freue mich auf Kommentare, Fragen und Likes! Smiley

 

https://www.youtube.com/playlist?list=PLPK8RW8p4Ok_g5ojGI6Lq80POQRRscRpz

Schreibe einen Kommentar...

Azure / PowerShell – Die App Settings mehrerer / aller Web Apps exportieren

Jüngst wollte ich mir den Überblick über alle App Settings der vielen Web Apps, die wir einsetzen, und deren Werten verschaffen und dabei auch schauen, ob die Settings in allen Entwicklungs-Stages gleich bzw. analog passend sind. Dazu habe ich ein PowerShell Skript geschrieben, was alle Web Apps in allen aufgeführten Ressource Groups prüft und deren App Settings in ein gemeinsames CSV File exportiert:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Adjust theese as needed
 
# Change this to the subscription you want to query
$SubscriptionId = "1234567-890123-132312312"
 
# Name the RG's here, that you want to check
[string[]]$ResourceGroups = "RG-A","RG-B","RG-C"
 
### no changes needed below ###
 
Connect-AzureRmAccount -Subscription $SubscriptionId
Set-AzureRmContext -SubscriptionId $SubscriptionId
 
$AllSettings = @()
[string[]]$AllURLs = $null
 
# Iterate over all RGs
Foreach($RG in $ResourceGroups)
{
    Write-Host "$RG..."
    # Get all WebApps in this RG
    $AllWebAppsInRG = Get-AzureRmWebApp -ResourceGroupName $RG
    Foreach($WebApp in ($AllWebAppsInRG))
    {
        Write-Host "$($WebApp.SiteName)..."
        $webAppObject = Get-AzureRmWebApp -ResourceGroupName $RG -Name $($WebApp.SiteName)
        $AppSettings = $webAppObject.SiteConfig.AppSettings
        $AllURLs += $WebApp.DefaultHostName
 
        ForEach($Setting in $AppSettings)
        {
            Write-Host "$($Setting.Name)"
            $SettingObject = New-Object PSCustomObject
            $SettingObject | Add-Member -Type NoteProperty -Name "Ressource Group" -Value $RG
            $SettingObject | Add-Member -Type NoteProperty -Name "WebApp Name" -Value $($WebApp.SiteName)
            $SettingObject | Add-Member -Type NoteProperty -Name "WebApp URL" -Value $($WebApp.DefaultHostName)
            $SettingObject | Add-Member -Type NoteProperty -Name "Setting Name" -Value $($Setting.Name)
            $SettingObject | Add-Member -Type NoteProperty -Name "Setting Value" -Value $($Setting.Value)
            $AllSettings += $SettingObject
        }
 
    }
 
}
 
$AllSettings | ConvertTo-Csv -Delimiter ";" -NoTypeInformation | Out-File "AllAppSettings.csv"

 

Danach sind die Settings alle in der Datei AllAppSettings im aktuellen Verzeichnis, und zwar so, dass man die Datei direkt in Excel öffnen kann. Viel Spaß beim Ausprobieren!

Schreibe einen Kommentar...

Azure / PowerShell – HttpsOnly für alle Web Apps aktivieren

In Azure stellt jeder App Service Plan ab B1 (d.h., alle außer F1 “Free” und D1 “Shared”) SSL entweder mit einem von Azure generierten oder einem eigenen Zertifikat zur Verfügung:

image

Allerdings lassen die App Services auch weiterhin HTTP ohne SSL zu, es sei denn, man aktiviert die Option “HTTPS Only”:

image

Diese Option kann man natürlich auch per PowerShell und damit ganz bequem gleich für eine größere Menge App Services setzen. Dazu habe ich dieses Skript geschrieben:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Adjust theese as needed
$SubscriptionId = "9feacb87-1fe6-447e-a0f4-4ae1ba2496e3"
[string[]]$ResourceGroups = "RG-A","RG-B","RG-C"
 
### no changes needed below ###
 
Connect-AzureRmAccount -Subscription $SubscriptionId
Set-AzureRmContext -SubscriptionId $SubscriptionId
 
# Iterate over all RGs
Foreach($RG in $ResourceGroups)
{
    Write-Host "$RG..."
    # Get all WebApps in this RG
    $AllWebAppsInRG = Get-AzureRmWebApp -ResourceGroupName $RG
    Foreach($WebApp in $AllWebAppsInRG)
    {
        Write-Host "$($WebApp.Name)..."
        # State before setting it:
        (Get-AzureRmWebApp -ResourceGroupName $RG -Name $($WebApp.Name)).HttpsOnly
        # Enabling HttpsOnly
        Set-AzureRmWebApp -ResourceGroupName $RG -Name $($WebApp.Name) -HttpsOnly $true
    }
}

 

Viel Spaß beim Ausprobieren!

Schreibe einen Kommentar...

Azure – Portal ermöglicht jetzt auch DENY für Berechtigungen / IAM / RBAC

Bis gestern kannte das Azure Portal nur die Möglichkeit, Berechtigungen zu gewähren (ALLOW). Seit heute kann man nun (neben der neuen Möglichkeit, sich die effektiven Berechtigungen eines Users anzeigen zu lassen, die sich aus Vererbung und co. ergeben) auch Berechtigungen explizit entziehen (DENY). Dadurch wird es jetzt viel einfacher möglich, einem Account z.B. Rechte auf „alles“ außer einem bestimmten Bereich zu geben. Bisher war es nicht möglich, jemandem z.B. zum Contributor auf einer Subscription zu machen, aber zu verhindern, dass er in eine bestimmte Ressource Group schauen kann. Dies ist nun möglich:

 

 

 

 

 

 

Immer wieder schön, wenn man über Nacht neue Features bekommt und diese dann entdeckt 🙂 Viel Spaß beim Ausprobieren…

1 Kommentar

Azure / PowerShell – App Settings von einer Web App zur anderen kopieren

Insbesondere, wenn man viele App Settings (Umgebungsvariablen für eine Web App) in Azure verwendet und die Web App ein zweites Mal benötigt, z.B. um eine Test- oder Entwicklungs-Stage abzubilden, kann es sehr mühselig sein, die Settings zu übertragen. Hier bietet es sich an, diese per PowerShell zu kopieren.  Voraussetzung dazu ist nur das Azure PowerShell RM Modul, welches man auf diesem Weg installieren kann:

Install-Module -Name AzureRM -AllowClobber

Dabei muss ggf. ein Sicherheitshinweis bestätigt werden. Wer das Modul schon installiert hat, muss natürlich nichts tun.

Zum Kopieren der Settings kann dann dieses Skript verwendet werden:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Adjust theese as needed
 
$SubscriptionId = "123456-7890-1234-12132"
 
$ResourceGroupSource = "RG-Source"
$ResourceGroupTarget = "RG-Target"
 
$WebAppSource = "WebApp-Source"
$WebAppTarget = "WebApp-Target"
 
### no changes needed below ###
 
Connect-AzureRmAccount -Subscription $SubscriptionId -Scope Process
Set-AzureRmContext -SubscriptionId $SubscriptionId
 
$webAppSource = Get-AzureRmWebApp -ResourceGroupName $ResourceGroupSource -Name $WebAppSource 
 
# Get reference to the source app settings
$AppSettingsSource = $WebAppSource.SiteConfig.AppSettings
 
# Create empty Hash table variable for App Settings
$AppSettingsTarget = @{}
 
# Copy over all existing App Settings to the Hash table
ForEach ($AppSettingSource in $AppSettingsSource) {
    $AppSettingsTarget[$AppSettingSource.Name] = $AppSettingSource.Value
}
 
# Save strings to target Web App
Set-AzureRmWebApp -ResourceGroupName $ResourceGroupTarget -Name $WebAppTarget -AppSettings $AppSettingsTarget

Viel Spaß beim Ausprobieren – mir spart das immer wieder viel Arbeit!

Schreibe einen Kommentar...

Azure / PowerShell – Das OS Image eines VMSS ändern

Da es hierzu keine gute Dokumentation im Netz gibt und ich heute dieses Problem hatte schreibe ich diesen kurzen Blog-Artikel.

Das Problem:

In verschiedenen bestehenden Virtual Maschine Scale Sets (VMSS) in Azure wird ein angepasstes Windows Server 2016 Image verwendet. Dieses Image sollte nun aktualisiert und weiter angepasst werden. Dazu habe ich aus dem Image eine VM erstellt, diese entsprechend hergerichtet und dann mit sysprep generalisiert. Danach habe ich mit Azure ein Image davon aufzeichnen lassen. Nun möchte ich dieses Image in den bestehenden VMSS einsetzen. Über das Portal geht das nicht und die PowerShell-Befehle sind nur unzureichend beschrieben.

Die Lösung:

Dieses kleine PowerShell-Skript legt das Basis-OS-Image für ein definiertes VMSS neu fest und löst danach das Re-Image der Instanzen aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Parameters
[string]$NewVmssBaseImageName = "VMSS-Base-Image-Name"
[string]$SubscriptionId = "123456789"
[string]$VMSSRessourceGroup = "RessourceGroupName"
[string]$VMSSName = "VMSSName"
 
# Connect to Azure
Connect-AzureRmAccount -Subscription $SubscriptionId
Set-AzureRmContext -SubscriptionId $SubscriptionId
 
# Get Image ID
$ImageId = (Get-AzureRmImage | Where Name -eq $NewVmssBaseImageName).Id
# Get VMSS
$VMSS = Get-AzureRmVmss -ResourceGroupName $VMSSRessourceGroup -VMScaleSetName $VMSSName
# Set new OS Image
$VMSS | Update-AzureRmVmss -ImageReferenceId $ImageId
# Upgrade VM instances to latest model
Update-AzureRmVmssInstance -InstanceId (Get-AzureRmVmssVM -VMScaleSetName $VMSS.Name -ResourceGroupName $VMSS.ResourceGroupName).InstanceId -ResourceGroupName $VMSSRessourceGroup -VMScaleSetName $VMSSName
Schreibe einen Kommentar...

Azure – Application Settings von einem App Service zu einem anderen Kopieren

Wenn man beispielsweise für Entwicklung, Test und andere Zwecke Kopien einer Azure Web App benötigt oder zumindest initial die Settings übernehmen will, kann das, bei einer längeren Liste von Settings, ein recht hoher manueller Aufwand werden. Um diesen zu umgehen, habe ich ein entsprechendes PowerShell-Skript geschrieben. Dieses kopiert alle Settings und deren Werte von einer benannten Web App auf eine andere. Dabei sind die Ressource Groups und die Namen der Web Apps anzugeben.

Hier das Skript im Textlaut:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Adjust theese as needed
 
$SubscriptionId = "FILLINSUBSCRIPTIONID"
 
$ResourceGroupSource = "FILLINRGOFSOURCEWEBAPP"
$ResourceGroupTarget = "FILLINRGOFDESTWEBAPP"
 
$WebAppSource = "FILLINSOURCEWEBAPP"
$WebAppTarget = "FILLINDESTWEBAPP"
 
### no changes needed below ###
 
Connect-AzureRmAccount -Subscription $SubscriptionId
Set-AzureRmContext -SubscriptionId $SubscriptionId
 
$webAppSource = Get-AzureRmWebApp -ResourceGroupName $ResourceGroupSource -Name $WebAppSource 
 
# Get reference to the source app settings
$AppSettingsSource = $WebAppSource.SiteConfig.AppSettings
 
# Create empty Hash table variable for App Settings
$AppSettingsTarget = @{}
 
# Copy over all Existing App Settings to the Hash table
ForEach ($AppSettingSource in $AppSettingsSource) {
    $AppSettingsTarget[$AppSettingSource.Name] = $AppSettingSource.Value
}
 
# Save Connection Strings to Target Web App
Set-AzureRmWebApp -ResourceGroupName $ResourceGroupTarget -Name $WebAppTarget -AppSettings $AppSettingsTarget
Write-Host "Done!"

Viel Spaß damit!

Schreibe einen Kommentar...