Created
September 1, 2020 15:09
-
-
Save machv/1f0c956c546c93d80fb612a975c8678c to your computer and use it in GitHub Desktop.
Synchronize Routing Table with Azure Service Tag Listing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region Azure Automation bootstrap | |
try | |
{ | |
$servicePrincipalConnection = Get-AutomationConnection -Name "AzureRunAsConnection" | |
"Logging in to Azure..." | |
Connect-AzAccount ` | |
-ServicePrincipal ` | |
-TenantId $servicePrincipalConnection.TenantId ` | |
-ApplicationId $servicePrincipalConnection.ApplicationId ` | |
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint | |
} | |
catch { | |
if (!$servicePrincipalConnection) | |
{ | |
$ErrorMessage = "Connection AzureRunAsConnection not found." | |
throw $ErrorMessage | |
} else{ | |
Write-Error -Message $_.Exception | |
throw $_.Exception | |
} | |
} | |
$smtpCredential = Get-AutomationPSCredential -Name "SendGridCredentials" | |
#endregion | |
#region Configuration | |
# Azure | |
$routeTableResourceGroupName = "test_group" | |
$routeTableName = "RT-ForcedTunneling" | |
$routeNamePrefix = "ps-" # used only to detect candidates for deletion | |
$services = @{ | |
"AzureBackup" = @("WestEurope", "NorthEurope") | |
} | |
# Mail notifications | |
$smtpServer = "smtp.sendgrid.net" | |
$emailFrom = "Azure Automations <[email protected]>" | |
$emailTo = "[email protected]" # CC added to every e-mail sent by this script | |
#endregion | |
$routeTable = Get-AzRouteTable -ResourceGroupName $routeTableResourceGroupName -Name $routeTableName | |
$serviceTags = Get-AzNetworkServiceTag -Location "westeurope" | |
$seenPrefixes = @() | |
$addedPrefixes = @() | |
foreach($service in $services.GetEnumerator()) { | |
$serviceName = $service.Name | |
$regions = $service.Value | |
foreach($region in $regions) { | |
$serviceGroups = $serviceTags.Values | Where-Object { $_.Properties.SystemService -eq $serviceName -and $_.Properties.Region -eq $region } | |
$prefixes = $serviceGroups | Select-Object -ExpandProperty Properties | Select-Object -ExpandProperty AddressPrefixes | |
foreach($prefix in $prefixes) { | |
$existingRoute = $routeTable.Routes | Where-Object AddressPrefix -eq $prefix | |
if($existingRoute) { | |
$seenPrefixes += $existingRoute.AddressPrefix | |
continue # nothing else is needed | |
} | |
$routeName = "$($routeNamePrefix)$($serviceName).$($region)-$($prefix.Replace("/", "_"))" | |
Write-Output " - Inserting new route for prefix $prefix with name $routeName" | |
Add-AzRouteConfig -RouteTable $routeTable -Name $routeName -AddressPrefix $prefix -NextHopType "Internet" | Out-Null | |
$addedPrefixes += $prefix | |
} | |
} | |
} | |
Write-Output "Commiting changes to the route table" | |
Set-AzRouteTable -RouteTable $routeTable | Out-Null | |
# What can be removed? | |
$routesToRemove = $routeTable.Routes | Where-Object { $_.AddressPrefix -notin $seenPrefixes -and $_.AddressPrefix -notin $addedPrefixes -and $_.Name.StartsWith($routeNamePrefix) } | |
# should we send an email notification? | |
if($addedPrefixes.Count -gt 0 -or $removePrefixes) { | |
} | |
#region Functions | |
function Build-HtmlTable { | |
param( | |
$Object, | |
$Columns, | |
$CustomPrefix, | |
$Tag = "td", | |
$Style = "" | |
) | |
$row = "<tr style='text-align: left' valign=top>$($CustomPrefix)" | |
foreach($column in $Columns) { | |
if($Object) { | |
$value = $Object.$column | |
} else { | |
$value = $column | |
} | |
$row += "<$($tag) style=`"$($Style)`">$($value)</$($tag)>" | |
} | |
$row += "</tr>" | |
$row | |
} | |
$css = @{ | |
th = "text-align:left;color: #495057; background-color: #e9ecef; border-color: #dee2e6;line-height: 22px; font-size: 14px; border-top-width: 1px; border-top-style: solid; border-bottom-width: 1px; border-bottom-style: solid; margin: 0; padding: 12px;" | |
td = "text-align:left;border-spacing: 0px; border-collapse: collapse; line-height: 22px; font-size: 14px; border-color: #e9ecef; border-top-width: 1px; border-top-style: solid; border-bottom-width: 1px; border-bottom-style: solid; margin: 0; padding: 12px;" | |
} | |
$tableColumns = [Ordered]@{ | |
Indexer = "" | |
Name = "Name" | |
AddressPrefix = "Prefix" | |
NextHopType = "Next Hop Type" | |
} | |
#endregion | |
$messageBody = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'></head><body style='font-size: 14px; font-family: Helvetica, Arial, sans-serif;'>" | |
$messageBody += "<p style='font-size: 14px;'>Routing table <strong>$($routeTableName)</strong> in the resource group <strong>$($routeTableResourceGroupName)</strong> has been updated.</p>" | |
if($addedPrefixes.Count -gt 0) { | |
$routes = $routeTable.Routes | Where-Object AddressPrefix -In $addedPrefixes | |
$messageBody += "<div style=`"margin-top: 20px; margin-bottom: 10px; font-weight: 500; color: inherit; vertical-align: baseline; font-size: 20px; line-height: 24.4px;`">Created routes</div>" | |
$messageBody += '<table border="0" cellpadding="0" cellspacing="0" style="font-family: Helvetica, Arial, sans-serif; mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-spacing: 0px; border-collapse: collapse; width: 100%; max-width: 100%;" bgcolor="#ffffff">' | |
$messageBody += Build-HtmlTable -Columns $tableColumns.Values -Tag "th" -Style $css.th | |
$i = 1 | |
foreach($route in $routes) { | |
$rowData = $route | Select-Object @{ Name = "Indexer"; Expression = { "<strong>$($i).</strong>" } }, * | |
$messageBody += Build-HtmlTable -Object $rowData -Columns $tableColumns.Keys -Style $css.td | |
$i += 1 | |
} | |
$messageBody += "</table>" | |
} | |
if($routesToRemove) { | |
$messageBody += "<div style=`"margin-top: 20px; margin-bottom: 10px; font-weight: 500; color: inherit; vertical-align: baseline; font-size: 20px; line-height: 24.4px;`">No longer needed routes</div>" | |
$messageBody += "<p style='font-size: 14px;'>These routes might be removed from the routing table as their prefixes are no longer present in Azure Service Tags reference list.</p>" | |
$messageBody += '<table border="0" cellpadding="0" cellspacing="0" style="font-family: Helvetica, Arial, sans-serif; mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-spacing: 0px; border-collapse: collapse; width: 100%; max-width: 100%;" bgcolor="#ffffff">' | |
$messageBody += Build-HtmlTable -Columns $tableColumns.Values -Tag "th" -Style $css.th | |
$i = 1 | |
foreach($route in $routesToRemove) { | |
$rowData = $route | Select-Object @{ Name = "Indexer"; Expression = { "<strong>$($i).</strong>" } }, * | |
$messageBody += Build-HtmlTable -Object $rowData -Columns $tableColumns.Keys -Style $css.td | |
$i += 1 | |
} | |
$messageBody += "</table>" | |
} | |
$messageBody += "</body></html>" | |
$messageBody | Set-Clipboard | |
if($addedPrefixes.Count -gt 0 -or $routesToRemove) { | |
Send-MailMessage -SmtpServer $smtpServer -Credential $smtpCredential -UseSsl -Port 587 ` | |
-From $emailFrom -To $emailTo -Subject "Updated Routing Table $($routeTableName)" ` | |
-Body $messageBody -BodyAsHtml -Encoding UTF8 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment