From 972ca56c288720f68f46a115c7eb3a7a22efa39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sr=C4=91an=20Bo=C5=BEovi=C4=87?= Date: Sun, 9 Sep 2018 14:36:43 +0200 Subject: [PATCH 1/5] mod: verify ps version for attach p2s --- .../attach-vpn-gateway/attachVPNGateway.ps1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/samples/manage/azure-sql-db-managed-instance/attach-vpn-gateway/attachVPNGateway.ps1 b/samples/manage/azure-sql-db-managed-instance/attach-vpn-gateway/attachVPNGateway.ps1 index 176dc9df..14364d4e 100644 --- a/samples/manage/azure-sql-db-managed-instance/attach-vpn-gateway/attachVPNGateway.ps1 +++ b/samples/manage/azure-sql-db-managed-instance/attach-vpn-gateway/attachVPNGateway.ps1 @@ -8,6 +8,20 @@ $force = $parameters['force'] $scriptUrlBase = $args[1] +function VerifyPSVersion +{ + Write-Host "Verifying PowerShell version, must be 5.0 or higher." + if($PSVersionTable.PSVersion.Major -ge 5) + { + Write-Host "PowerShell version verified." -ForegroundColor Green + } + else + { + Write-Host "You need to install PowerShell version 5.0 or heigher." -ForegroundColor Red + Break; + } +} + function Ensure-Login () { $context = Get-AzureRmContext @@ -156,6 +170,7 @@ function CalculateVpnClientAddressPoolPrefix } +VerifyPSVersion Ensure-Login Select-SubscriptionId -subscriptionId $subscriptionId From 6bf175d2971e7ca8a743ab72a437d261b84888a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sr=C4=91an=20Bo=C5=BEovi=C4=87?= Date: Sun, 9 Sep 2018 15:16:11 +0200 Subject: [PATCH 2/5] add: attach jumpbox --- .../attach-jumpbox/README.md | 80 ++++++++ .../attach-jumpbox/attachJumpbox.ps1 | 165 +++++++++++++++- .../attach-jumpbox/azuredeploy.json | 186 ++++++++++++++++++ 3 files changed, 430 insertions(+), 1 deletion(-) create mode 100644 samples/manage/azure-sql-db-managed-instance/attach-jumpbox/README.md create mode 100644 samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json diff --git a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/README.md b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/README.md new file mode 100644 index 00000000..af34d600 --- /dev/null +++ b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/README.md @@ -0,0 +1,80 @@ +# Attaches VM with SQL Server Management Studio (SSMS) to Managed Instance virtual network + +### Contents + +[About this sample](#about-this-sample)
+[Before you begin](#before-you-begin)
+[Run this sample](#run-this-sample)
+[Sample details](#sample-details)
+[Disclaimers](#disclaimers)
+[Related links](#related-links)
+ + + + +## About this sample + +- **Applies to:** Azure SQL Database +- **Key features:** Managed Instance +- **Workload:** n/a +- **Programming Language:** PowerShell +- **Authors:** Srdan Bozovic +- **Update history:** n/a + + + +## Before you begin + +To run this sample, you need the following prerequisites. + +**Software prerequisites:** + +1. PowerShell 5.1 +2. Azure PowerShell 5.4.2 or higher + +**Azure prerequisites:** + +1. Permission to manage Azure virtual network + + + +## Run this sample + +Run the script below from Windows PowerShell or Azure Cloud Shell + +```powershell + +$scriptUrlBase = 'https://raw.githubusercontent.com/Microsoft/sql-server-samples/master/samples/manage/azure-sql-db-managed-instance/attach-jumpbox' + +$parameters = @{ + subscriptionId = '' + resourceGroupName = '' + virtualNetworkName = '' + administratorLogin = 'cloudSA' + administratorLoginPassword = '' + } + +Invoke-Command -ScriptBlock ([Scriptblock]::Create((iwr ($scriptUrlBase+'/attachJumpbox.ps1?t='+ [DateTime]::Now.Ticks)).Content)) -ArgumentList $parameters, $scriptUrlBase + +``` + + + +## Sample details + +This sample shows how to attach VM with SSMS to Managed Instance virtual network using PowerShell + + + +## Disclaimers +The scripts and this guide are copyright Microsoft Corporations and are provided as samples. They are not part of any Azure service and are not covered by any SLA or other Azure-related agreements. They are provided as-is with no warranties express or implied. Microsoft takes no responsibility for the use of the scripts or the accuracy of this document. Familiarize yourself with the scripts before using them. + + + +## Related Links + + +For more information, see these articles: + +- [What is a Managed Instance (preview)?](https://docs.microsoft.com/azure/sql-database/sql-database-managed-instance) +- [Configure a VNet for Azure SQL Database Managed Instance](https://docs.microsoft.com/azure/sql-database/sql-database-managed-instance-vnet-configuration) \ No newline at end of file diff --git a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/attachJumpbox.ps1 b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/attachJumpbox.ps1 index fc6bb0ec..dda80d1c 100644 --- a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/attachJumpbox.ps1 +++ b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/attachJumpbox.ps1 @@ -1 +1,164 @@ -#placeholder \ No newline at end of file +$parameters = $args[0] + +$subscriptionId = $parameters['subscriptionId'] +$resourceGroupName = $parameters['resourceGroupName'] +$virtualNetworkName = $parameters['virtualNetworkName'] +$administratorLogin = $parameters['administratorLogin'] +$administratorLoginPassword = $parameters['administratorLoginPassword'] + +$scriptUrlBase = $args[1] + +function VerifyPSVersion +{ + Write-Host "Verifying PowerShell version, must be 5.0 or higher." + if($PSVersionTable.PSVersion.Major -ge 5) + { + Write-Host "PowerShell version verified." -ForegroundColor Green + } + else + { + Write-Host "You need to install PowerShell version 5.0 or heigher." -ForegroundColor Red + Break; + } +} + +function EnsureLogin () +{ + $context = Get-AzureRmContext + If($null -eq $context.Subscription) + { + Write-Host "Loging in ..." + If($null -eq (Login-AzureRmAccount -ErrorAction SilentlyContinue -ErrorVariable Errors)) + { + Write-Host ("Login failed: {0}" -f $Errors[0].Exception.Message) -ForegroundColor Red + Break + } + } + Write-Host "User logedin." -ForegroundColor Green +} + +function SelectSubscriptionId { + param ( + $subscriptionId + ) + Write-Host "Selecting subscription '$subscriptionId'." + $context = Get-AzureRmContext + If($context.Subscription.Id -ne $subscriptionId) + { + Try + { + Select-AzureRmSubscription -SubscriptionId $subscriptionId -ErrorAction Stop | Out-null + } + Catch + { + Write-Host "Subscription selection failed: $_" -ForegroundColor Red + Break + } + } + Write-Host "Subscription selected." -ForegroundColor Green +} + +function LoadVirtualNetwork { + param ( + $resourceGroupName, + $virtualNetworkName + ) + Write-Host("Loading virtual network '{0}' in resource group '{1}'." -f $virtualNetworkName, $resourceGroupName) + $virtualNetwork = Get-AzureRmVirtualNetwork -ResourceGroupName $resourceGroupName -Name $virtualNetworkName -ErrorAction SilentlyContinue + If($null -ne $virtualNetwork.Id) + { + Write-Host "Virtual network loaded." -ForegroundColor Green + return $virtualNetwork + } + else + { + Write-Host "Virtual network not found." -ForegroundColor Red + Break + } +} + +function ConvertCidrToUint32Array +{ + param($cidrRange) + $cidrRangeParts = $cidrRange.Split(@(".","/")) + $ipnum = ([Convert]::ToUInt32($cidrRangeParts[0]) -shl 24) -bor ` + ([Convert]::ToUInt32($cidrRangeParts[1]) -shl 16) -bor ` + ([Convert]::ToUInt32($cidrRangeParts[2]) -shl 8) -bor ` + [Convert]::ToUInt32($cidrRangeParts[3]) + + $maskbits = [System.Convert]::ToInt32($cidrRangeParts[4]) + $mask = 0xffffffff + $mask = $mask -shl (32 -$maskbits) + $ipstart = $ipnum -band $mask + $ipend = $ipnum -bor ($mask -bxor 0xffffffff) + return @($ipstart, $ipend) +} + +function ConvertUInt32ToIPAddress +{ + param($uint32IP) + $v1 = $uint32IP -band 0xff + $v2 = ($uint32IP -shr 8) -band 0xff + $v3 = ($uint32IP -shr 16) -band 0xff + $v4 = ($uint32IP -shr 24) + return "$v4.$v3.$v2.$v1" +} + +function CalculateNextAddressPrefix +{ + param($virtualNetwork, $prefixLength) + Write-Host "Calculating address prefix." + $startIPAddress = 0 + ForEach($addressPrefix in $virtualNetwork.AddressSpace.AddressPrefixes) + { + $endIPAddress = (ConvertCidrToUint32Array $addressPrefix)[1] + If($endIPAddress -gt $startIPAddress) + { + $startIPAddress = $endIPAddress + } + } + $startIPAddress += 1 + return (ConvertUInt32ToIPAddress $startIPAddress) + "/" + $prefixLength +} + +function CalculateVpnClientAddressPoolPrefix +{ + param($gatewaySubnetPrefix) + Write-Host "Calculating VPN client address pool prefix." + If($gatewaySubnetPrefix.StartsWith("10.")) + { + return "192.168.0.0/24" + } + else + { + return "172.16.0.0/24" + } + +} + +VerifyPSVersion +EnsureLogin +SelectSubscriptionId -subscriptionId $subscriptionId + +$virtualNetwork = LoadVirtualNetwork -resourceGroupName $resourceGroupName -virtualNetworkName $virtualNetworkName + +$managementSubnetPrefix = CalculateNextAddressPrefix $virtualNetwork 28 + +$virtualNetwork.AddressSpace.AddressPrefixes.Add($managementSubnetPrefix) +Add-AzureRmVirtualNetworkSubnetConfig -Name Management -VirtualNetwork $virtualNetwork -AddressPrefix $managementSubnetPrefix | Out-Null + +Set-VirtualNetwork $virtualNetwork + +Write-Host + +# Start the deployment +Write-Host "Starting deployment..." + +$templateParameters = @{ + virtualNetworkName = $virtualNetworkName + managementSubnetPrefix = $managementSubnetPrefix + administratorLogin = $administratorLogin + administratorLoginPassword = $administratorLoginPassword +} + +New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateUri ($scriptUrlBase+'/azuredeploy.json?t='+ [DateTime]::Now.Ticks) -TemplateParameterObject $templateParameters diff --git a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json new file mode 100644 index 00000000..093e1c27 --- /dev/null +++ b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json @@ -0,0 +1,186 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.1", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Enter location. If you leave this field blank resource group location would be used." + } + }, + "virtualNetworkName": { + "type": "string", + "metadata": { + "description": "Enter virtual network name. If you leave this field blank name will be created by the template." + } + }, + "managementSubnetPrefix": { + "type": "string", + "metadata": { + "description": "Enter management subnet address prefix." + } + }, + "administratorLogin": { + "type": "string", + "metadata": { + "description": "Enter user name." + } + }, + "administratorLoginPassword": { + "type": "securestring", + "metadata": { + "description": "Enter password." + } + } + }, + "variables": { + "managementSubnetName": "Management", + "virtualMachineName": "JumpBox", + "virtualMachineSize": "Standard_B2s", + "networkInterfaceName": "nicJumpBox", + "publicIPAddressName": "ipJumpBox", + "networkSecurityGroupName": "nsgJumpBox", + "scriptFileUri": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/201-sqlmi-new-vnet-w-jumpbox/installSSMS.ps1" + }, + "resources": [ + { + "name": "[variables('virtualMachineName')]", + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2018-06-01", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkInterfaces/', variables('networkInterfaceName'))]" + ], + "properties": { + "osProfile": { + "computerName": "[variables('virtualMachineName')]", + "adminUsername": "[parameters('administratorLogin')]", + "adminPassword": "[parameters('administratorLoginPassword')]", + "windowsConfiguration": { + "provisionVmAgent": "true" + } + }, + "hardwareProfile": { + "vmSize": "[variables('virtualMachineSize')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "2016-Datacenter", + "version": "latest" + }, + "osDisk": { + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "Standard_LRS" + } + }, + "dataDisks": [] + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" + } + ] + } + }, + "resources": [ + { + "name": "SetupChocolatey", + "type": "extensions", + "location": "[parameters('location')]", + "apiVersion": "2018-06-01", + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', variables('virtualMachineName'))]" + ], + "tags": { + "displayName": "SetupChocolatey" + }, + "properties": { + "publisher": "Microsoft.Compute", + "type": "CustomScriptExtension", + "typeHandlerVersion": "1.9", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[variables('scriptFileUri')]" + ], + "commandToExecute": "powershell -ExecutionPolicy Unrestricted -File installSSMS.ps1" + } + } + } + ] + }, + + { + "name": "[variables('networkInterfaceName')]", + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2017-10-01", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "[concat('Microsoft.Network/publicIpAddresses/', variables('publicIPAddressName'))]", + "[concat('Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('managementSubnetName'))]" + }, + "privateIPAllocationMethod": "Dynamic", + "publicIpAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('publicIpAddressName'))]" + } + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + } + } + }, + { + "name": "[variables('publicIpAddressName')]", + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2017-08-01", + "location": "[parameters('location')]", + "properties": { + "publicIPAllocationMethod": "Dynamic" + }, + "sku": { + "name": "Basic" + } + }, + { + "name": "[variables('networkSecurityGroupName')]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2018-01-01", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "RDP", + "properties": { + "priority": 300, + "protocol": "Tcp", + "access": "Allow", + "direction": "Inbound", + "sourceApplicationSecurityGroups": [], + "destinationApplicationSecurityGroups": [], + "sourceAddressPrefix": "*", + "sourcePortRange": "*", + "destinationAddressPrefix": "*", + "destinationPortRange": "3389" + } + } + ] + } + } + ] +} \ No newline at end of file From 6ffaefafe44b0da4b15cc28e39acefe32587e645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sr=C4=91an=20Bo=C5=BEovi=C4=87?= Date: Sun, 9 Sep 2018 15:21:28 +0200 Subject: [PATCH 3/5] fix: virtual network update --- .../attach-jumpbox/attachJumpbox.ps1 | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/attachJumpbox.ps1 b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/attachJumpbox.ps1 index dda80d1c..eda28bbf 100644 --- a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/attachJumpbox.ps1 +++ b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/attachJumpbox.ps1 @@ -77,6 +77,21 @@ function LoadVirtualNetwork { } } +function SetVirtualNetwork +{ + param($virtualNetwork) + + Write-Host "Applying changes to the virtual network." + Try + { + Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetwork -ErrorAction Stop | Out-Null + } + Catch + { + Write-Host "Failed: $_" -ForegroundColor Red + } +} + function ConvertCidrToUint32Array { param($cidrRange) @@ -147,7 +162,7 @@ $managementSubnetPrefix = CalculateNextAddressPrefix $virtualNetwork 28 $virtualNetwork.AddressSpace.AddressPrefixes.Add($managementSubnetPrefix) Add-AzureRmVirtualNetworkSubnetConfig -Name Management -VirtualNetwork $virtualNetwork -AddressPrefix $managementSubnetPrefix | Out-Null -Set-VirtualNetwork $virtualNetwork +SetVirtualNetwork $virtualNetwork Write-Host From 39de498f4fd8b90a09b3e14a95d5e32838e0b421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sr=C4=91an=20Bo=C5=BEovi=C4=87?= Date: Sun, 9 Sep 2018 15:23:27 +0200 Subject: [PATCH 4/5] fix: removed vnet dependancy from template --- .../attach-jumpbox/azuredeploy.json | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json index 093e1c27..28ab99c4 100644 --- a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json +++ b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json @@ -121,7 +121,6 @@ "apiVersion": "2017-10-01", "location": "[parameters('location')]", "dependsOn": [ - "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", "[concat('Microsoft.Network/publicIpAddresses/', variables('publicIPAddressName'))]", "[concat('Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]" ], From 1d71fa155156fd8aa7df8a9db53e91bae73ade39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sr=C4=91an=20Bo=C5=BEovi=C4=87?= Date: Sun, 9 Sep 2018 15:27:14 +0200 Subject: [PATCH 5/5] fix: arm template nic subnet name --- .../attach-jumpbox/azuredeploy.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json index 28ab99c4..ff12fca4 100644 --- a/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json +++ b/samples/manage/azure-sql-db-managed-instance/attach-jumpbox/azuredeploy.json @@ -130,7 +130,7 @@ "name": "ipconfig1", "properties": { "subnet": { - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('managementSubnetName'))]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), variables('managementSubnetName'))]" }, "privateIPAllocationMethod": "Dynamic", "publicIpAddress": {