Add all prereq required files
This commit is contained in:
Родитель
5079ca14ad
Коммит
4537a77dea
12
README.md
12
README.md
|
@ -1,13 +1,13 @@
|
|||
|
||||
# Technical Reference Implementation for Enterprise BI and Reporting
|
||||
|
||||
Azure offers a rich data and analytics platform for customers and ISVs seeking to build scalable BI and Reporting solutions. However, customers face pragmatic challenges in building the right infrastructure for enterprise-grade, production systems. They have to evaluate the various products for security, scale, performance and geo-availability requirements. They have to understand service features and their interoperability, and plan to address any perceived gaps with custom software. This takes time and effort, and many times, the end to end system architecture they design is sub-optimal. Consequently, the promise and expectations set during proof-of-concept (POC) stages do not translate to robust production systems in the expected time to market.
|
||||
Azure offers a rich data and analytics platform for customers and ISVs seeking to build scalable BI and reporting solutions. However, customers face pragmatic challenges in building the right infrastructure for enterprise-grade, production systems. They have to evaluate the various products for security, scale, performance and geo-availability requirements. They have to understand service features and their interoperability, and plan to address any perceived gaps with custom software. This takes time and effort, and many times, the end to end system architecture they design is sub-optimal. Consequently, the promise and expectations set during proof-of-concept (POC) stages do not translate to robust production systems in the expected time to market.
|
||||
|
||||
This TRI addresses this customer pain by providing a reference implementation that
|
||||
- is pre-built based on selected, stable Azure components proven to work in enterprise BI and reporting scenarios
|
||||
- can be easily configured and deployed to an Azure subscription within a few hours,
|
||||
- is bundled with software to handle all the operational essentials for a full fledged production system, and
|
||||
- is tested end to end against large workloads.
|
||||
This TRI addresses this customer pain by providing a reference implementation that is:
|
||||
- pre-built based on selected, stable Azure components proven to work in enterprise BI and reporting scenarios
|
||||
- easily configured and deployed to an Azure subscription within a few hours
|
||||
- bundled with software to handle all the operational essentials for a full fledged production system
|
||||
- tested end to end against large workloads
|
||||
|
||||
Once deployed, the TRI can be used as-is, or customized to fit the application needs using the technical documentation that is provided with the TRI. This enables the customer to build the solution that delivers the business goals based on a robust and functional infrastructure.
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
# Summary
|
||||
This page summarizes prerequisites for EDW Reporting TRA deployment.
|
||||
This page summarizes prerequisites for Technical Reference Implementation for Enterprise BI and Reporting solution.
|
||||
|
||||
# VNET
|
||||
|
||||
Most of the resources provisioned will be placed in a pre-existing Azure VNET. Therefore, we require an Azure VNET resource and a domain controller to be deployed in the subscription where the EDW Reporting TRA will be deployed. Customers who already have a functioning Azure VNET can skip this section. For customers new to Azure, the guide below will show how to easily deploy prerequisites in their subscription.
|
||||
Most of the resources provisioned will be placed in a pre-existing Azure VNET. Therefore, we require an Azure VNET resource and a domain controller to be deployed in the subscription where the solution will be deployed. Customers who already have a functioning Azure VNET and domain controller can skip this section. For customers new to Azure, the guide below will show how to easily deploy prerequisites in their subscription.
|
||||
|
||||
## Provisioning Azure VNet resource
|
||||
|
||||
First, we will create new Azure VNET and VPN Gateway resources. Navigate to <source root>\edw\deployment directory and run the command below. Note that it might take up to 45 minutes to complete.
|
||||
First, we will create new Azure VNET and VPN Gateway resources. Navigate to the <source root>\scripts directory and run the command below. Note that it might take up to 45 minutes to complete.
|
||||
|
||||
```PowerShell
|
||||
Login-AzureRmAccount
|
||||
|
||||
.\DeployVPN.ps1 -SubscriptionName "My Subscription" -Location "westus" -EDWAddressPrefix "10.254.0.0/16" -EDWGatewaySubnetPrefix "10.254.1.0/24" -OnpremiseVPNClientSubnetPrefix "192.168.200.0/24" -ResourceGroupName "ContosoVNetGroup" -VNetName "ContosoVNet" -VNetGatewayName "ContosoGateway" -RootCertificateName "ContosoRootCertificate" -ChildCertificateName "ContosoChildCertificate"
|
||||
.\DeployVPN.ps1 -SubscriptionName "My Subscription" -ResourceGroupName "ContosoVNetGroup" -Location "westus" -VNetName "ContosoVNet" -VNetGatewayName "ContosoGateway" -AddressPrefix "10.254.0.0/16" -GatewaySubnetPrefix "10.254.1.0/24" -OnpremiseVPNClientSubnetPrefix "192.168.200.0/24" -RootCertificateName "ContosoRootCertificate" -ChildCertificateName "ContosoChildCertificate"
|
||||
```
|
||||
|
||||
In addition to provisioning Azure VNET and VPN Gateway resources, the script above will also create a self-signed root certificate and a client certificate for the VPN gateway. The root certificate is used for generating and signing client certificates on the client side, and for validating those client certificates on the VPN gateway side.
|
||||
|
@ -24,7 +24,7 @@ $rootCert = Get-ChildItem -Path cert:\CurrentUser\My | ?{ $_.Subject -eq "CN=Con
|
|||
$childCert = Get-ChildItem -Path cert:\CurrentUser\My | ?{ $_.Subject -eq "CN=ContosoChildCertificate" }
|
||||
|
||||
$type = [System.Security.Cryptography.X509Certificates.X509Certificate]::pfx
|
||||
$securePassword = ConvertTo-SecureString -String "Welcome1234!" -Force –AsPlainText
|
||||
$securePassword = ConvertTo-SecureString -String "MyPassword" -Force –AsPlainText
|
||||
|
||||
Export-PfxCertificate -Cert $rootCert -FilePath "ContosoRootCertificate.pfx" -Password $securePassword -Verbose
|
||||
Export-PfxCertificate -Cert $childCert -FilePath "ContosoChildCertificate.pfx" -Password $securePassword -Verbose
|
||||
|
@ -35,7 +35,7 @@ Export-PfxCertificate -Cert $childCert -FilePath "ContosoChildCertificate.pfx" -
|
|||
The next step is to deploy a Domain Controller VM and set up a new domain. All VMs provisioned during the EDW TRA deployment will join the domain managed by the domain controller. To do that, run the PowerShell script below.
|
||||
|
||||
```PowerShell
|
||||
.\DeployDC.ps1 -SubscriptionName "My Subscription" -Location "westus" -ExistingVNETResourceGroupName "ContosoVNetGroup" -ExistingVNETName "ContosoVNet" -DomainName "contosodomain.ms" -DomainUserName "edwadmin" -DomainUserPassword "Welcome1234!"
|
||||
.\DeployDC.ps1 -SubscriptionName "My Subscription" -Location "westus" -ResourceGroupName "ContosoVNetGroup" -VNetName "ContosoVNet" -DomainName "contosodomain.ms" -DomainUserName "edwadmin" -DomainUserPassword "MyPassword"
|
||||
```
|
||||
|
||||
The script above will provision an Azure VM and promote it to serve as the domain controller for the VNET. In addition, it will reconfigure the VNET to use the newly provisioned VM as its DNS server.
|
|
@ -0,0 +1,207 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"adminUsername": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the Administrator of the new VM and Domain"
|
||||
},
|
||||
"defaultValue": "adAdministrator"
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "The password for the Administrator account of the new VM and Domain"
|
||||
}
|
||||
},
|
||||
"domainName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The FQDN of the AD Domain to be created"
|
||||
}
|
||||
},
|
||||
"existingVirtualNetworkName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name of the existing VNET"
|
||||
}
|
||||
},
|
||||
"existingVirtualNetworkAddressRange": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Address range of the existing VNET"
|
||||
}
|
||||
},
|
||||
"dcSubnetName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name of the existing subnet for Domain Controller"
|
||||
}
|
||||
},
|
||||
"existingSubnetAddressRange": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Address range of the existing subnet"
|
||||
}
|
||||
},
|
||||
"_artifactsLocation": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The location of resources, such as templates and DSC modules, that the template depends on"
|
||||
},
|
||||
"defaultValue": "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/active-directory-new-domain-ha-2-dc"
|
||||
},
|
||||
"_artifactsLocationSasToken": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "Auto-generated token to access _artifactsLocation"
|
||||
},
|
||||
"defaultValue": ""
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"vhdStorageAccountName": "[concat('vhds', uniqueString(resourceGroup().id))]",
|
||||
"storageAccountType": "Premium_LRS",
|
||||
"dcVMName": "adDC",
|
||||
"imagePublisher": "MicrosoftWindowsServer",
|
||||
"imageOffer": "WindowsServer",
|
||||
"imageSKU": "2016-Datacenter",
|
||||
"dcVMSize": "Standard_DS2_v2",
|
||||
"dcPDCNicName": "adPDCNic",
|
||||
"dcSubnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('existingVirtualNetworkName'), parameters('dcSubnetName'))]",
|
||||
"dcDataDisk": "DCDataDisk",
|
||||
"dcDataDiskSize": 1000,
|
||||
"dcModulesURL": "[concat(parameters('_artifactsLocation'),'/DSC/CreateADPDC.zip', parameters('_artifactsLocationSasToken'))]",
|
||||
"dcConfigurationFunction": "CreateADPDC.ps1\\CreateADPDC",
|
||||
"vnetwithDNSTemplateUri": "[concat(parameters('_artifactsLocation'),'/nestedtemplates/vnet-with-dns-server.json', parameters('_artifactsLocationSasToken'))]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "[variables('vhdStorageAccountName')]",
|
||||
"type": "Microsoft.Storage/storageAccounts",
|
||||
"apiVersion": "2016-05-01",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
},
|
||||
"sku": { "name": "[variables('storageAccountType')]" },
|
||||
"kind": "Storage"
|
||||
},
|
||||
{
|
||||
"name": "[variables('dcPDCNicName')]",
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"apiVersion": "2016-10-01",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
],
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"subnet": {
|
||||
"id": "[variables('dcSubnetRef')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "[variables('dcVMName')]",
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"apiVersion": "2016-03-30",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Storage/storageAccounts',variables('vhdStorageAccountName'))]",
|
||||
"[resourceId('Microsoft.Network/networkInterfaces',variables('dcPDCNicName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[variables('dcVMSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[variables('dcVMName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "[variables('imagePublisher')]",
|
||||
"offer": "[variables('imageOffer')]",
|
||||
"sku": "[variables('imageSKU')]",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "osdisk",
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(resourceId('Microsoft.Storage/storageAccounts/', variables('vhdStorageAccountName'))).primaryEndpoints.blob,'vhds0/','osdisk.vhd')]"
|
||||
},
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "FromImage"
|
||||
},
|
||||
"dataDisks": [
|
||||
{
|
||||
"vhd": {
|
||||
"uri": "[concat(reference(resourceId('Microsoft.Storage/storageAccounts/', variables('vhdStorageAccountName'))).primaryEndpoints.blob,'vhds0/', variables('dcDataDisk'),'.vhd')]"
|
||||
},
|
||||
"name": "[concat(variables('dcVMName'),'-data-disk1')]",
|
||||
"caching": "None",
|
||||
"diskSizeGB": "[variables('dcDataDiskSize')]",
|
||||
"lun": 0,
|
||||
"createOption": "empty"
|
||||
}
|
||||
]
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces',variables('dcPDCNicName'))]"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "CreateADForest",
|
||||
"type": "extensions",
|
||||
"apiVersion": "2016-03-30",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Compute/virtualMachines', variables('dcVMName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.Powershell",
|
||||
"type": "DSC",
|
||||
"typeHandlerVersion": "2.19",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"ModulesUrl": "[variables('dcModulesURL')]",
|
||||
"ConfigurationFunction": "[variables('dcConfigurationFunction')]",
|
||||
"Properties": {
|
||||
"DomainName": "[parameters('domainName')]",
|
||||
"AdminCreds": {
|
||||
"UserName": "[parameters('adminUserName')]",
|
||||
"Password": "PrivateSettingsRef:AdminPassword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"protectedSettings": {
|
||||
"Items": {
|
||||
"AdminPassword": "[parameters('adminPassword')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
"outputs": {
|
||||
"DCIp": {
|
||||
"type": "string",
|
||||
"value": "[reference(variables('dcPDCNicName')).ipConfigurations[0].properties.privateIPAddress]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"gatewayName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name of the VPN gateway"
|
||||
}
|
||||
},
|
||||
"virtualNetworkName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Name for the Azure Virtual Network"
|
||||
}
|
||||
},
|
||||
"edwAzureVNetAddressPrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "CIDR block representing the address space of the Azure VNet"
|
||||
}
|
||||
},
|
||||
"vpnGatewaySubnetPrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "CIDR block for gateway subnet, subset of edwAzureVNetAddressPrefix address space"
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"apiVersion": "2015-06-15",
|
||||
"gatewaySubnetName": "GatewaySubnet",
|
||||
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
|
||||
"gatewaySubnetRef": "[concat(variables('vnetID'),'/subnets/', variables('gatewaySubnetName'))]",
|
||||
"gatewayPublicIPName": "EDWVPNGwPublicIp"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[parameters('virtualNetworkName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[parameters('edwAzureVNetAddressPrefix')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[variables('gatewaySubnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[parameters('vpnGatewaySubnetPrefix')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"name": "[variables('gatewayPublicIPName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "[variables('apiVersion')]",
|
||||
"type": "Microsoft.Network/virtualNetworkGateways",
|
||||
"name": "[parameters('gatewayName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"dependsOn": [
|
||||
"[concat('Microsoft.Network/publicIPAddresses/', variables('gatewayPublicIPName'))]",
|
||||
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Dynamic",
|
||||
"subnet": {
|
||||
"id": "[variables('gatewaySubnetRef')]"
|
||||
},
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('gatewayPublicIPName'))]"
|
||||
}
|
||||
},
|
||||
"name": "vnetGatewayConfig"
|
||||
}
|
||||
],
|
||||
"gatewayType": "Vpn",
|
||||
"vpnType": "RouteBased",
|
||||
"enableBgp": "false"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
function New-ResourceGroupIfNotExists ($resourceGroupName, $location) {
|
||||
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
|
||||
if(-not $resourceGroup) {
|
||||
New-AzureRmResourceGroup -Name $resourceGroupName -Location $location
|
||||
Write-Output ("Created Resource Group $resourceGroupName in $location.");
|
||||
return;
|
||||
}
|
||||
|
||||
$isSameLocation = $resourceGroup.Location -eq $location
|
||||
if(-not $isSameLocation) {
|
||||
throw "Resource Group $resourceGroup exists in a different location $resourceGroup.Location .. Delete the existing resource group or choose another name." ;
|
||||
}
|
||||
|
||||
Write-Output ("Resource Group $resourceGroupName already exists. Skipping creation.");
|
||||
}
|
||||
|
||||
function New-Session () {
|
||||
$Error.Clear()
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
Get-AzureRmContext -ErrorAction Continue;
|
||||
foreach ($eacherror in $Error) {
|
||||
if ($eacherror.Exception.ToString() -like "*Run Login-AzureRmAccount to login.*") {
|
||||
Add-AzureAccount
|
||||
}
|
||||
}
|
||||
$Error.Clear();
|
||||
$ErrorActionPreference = "Stop"
|
||||
}
|
||||
|
||||
function Load-Module($name)
|
||||
{
|
||||
if(-not(Get-Module -name $name))
|
||||
{
|
||||
if(Get-Module -ListAvailable |
|
||||
Where-Object { $_.name -eq $name })
|
||||
{
|
||||
Import-Module -Name $name
|
||||
Write-Host "Module $name imported successfully"
|
||||
} #end if module available then import
|
||||
|
||||
else
|
||||
{
|
||||
Write-Host "Module $name does not exist. Installing.."
|
||||
Install-Module -Name $name -AllowClobber -Force
|
||||
Write-Host "Module $name installed successfully"
|
||||
} #module not available
|
||||
|
||||
} # end if not module
|
||||
|
||||
else
|
||||
{
|
||||
Write-Host "Module $name exists and is already loaded"
|
||||
} #module already loaded
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
# This module contains network related common functions
|
||||
|
||||
# To get virtual network. If not possible to get virtual network, exit as it is a critical requirement
|
||||
Function Get-VirtualNetworkOrExit(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $ResourceGroupName,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $VirtualNetworkName
|
||||
)
|
||||
{
|
||||
try {
|
||||
$virtualNetwork = Get-AzureRmVirtualNetwork -Name $VirtualNetworkName -ResourceGroupName $ResourceGroupName
|
||||
|
||||
if (-not $virtualNetwork) {
|
||||
Write-Host -ForegroundColor DarkRed "Unable to get virtual network $($VirtualNetworkName). Exiting..."
|
||||
Display-VnetErrorMessage
|
||||
|
||||
exit 3
|
||||
}
|
||||
|
||||
return $virtualNetwork
|
||||
} catch {
|
||||
Write-Host -ForegroundColor DarkRed "Unable to get virtual network $($VirtualNetworkName). Exiting..."
|
||||
Write-Host $Error[0]
|
||||
Display-VnetErrorMessage
|
||||
|
||||
exit 3
|
||||
}
|
||||
}
|
||||
|
||||
# Get uint32 value for given IPv4 network address
|
||||
Function Get-NetworkValue(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $NetworkPrefix
|
||||
)
|
||||
{
|
||||
$strArray = $NetworkPrefix.Split(".")
|
||||
[uint32] $value = 0
|
||||
for($i=0; $i -lt 4; $i++) {
|
||||
$value = ($value -shl 8) + [convert]::ToInt16($strArray[$i])
|
||||
}
|
||||
|
||||
return $value
|
||||
}
|
||||
|
||||
# Get Ipv4 network address for given uint32
|
||||
Function Get-NetworkAddress(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[uint32] $NetworkValue
|
||||
)
|
||||
{
|
||||
[uint32] $mask = (1 -shl 8) - 1
|
||||
[string] $networkAddress = ""
|
||||
for($i=0; $i -lt 3; $i++) {
|
||||
[uint32] $value = $NetworkValue -band $mask
|
||||
$NetworkValue = $NetworkValue -shr 8
|
||||
$networkAddress = "." + $value + $networkAddress
|
||||
}
|
||||
|
||||
$networkAddress = "$($NetworkValue)$($networkAddress)"
|
||||
return $networkAddress
|
||||
}
|
||||
|
||||
# Get free subnet or existing given subnet under given virtual network or exit
|
||||
# If free subnet is found then it is created under VNET for this deployment to use
|
||||
Function Get-AvailableSubnetOrExit(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[object] $VirtualNetwork,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $SubnetName
|
||||
)
|
||||
{
|
||||
$GatewaySubnetName = "GatewaySubnet"
|
||||
$TotalBits = 32
|
||||
|
||||
try {
|
||||
$vnetAddressPrefix = $VirtualNetwork.AddressSpace.AddressPrefixes[0]
|
||||
$addressPrefixArray = $vnetAddressPrefix.Split("/")
|
||||
$networkAddress = $addressPrefixArray[0]
|
||||
[int]$networkNumBits = $TotalBits - ([convert]::ToInt32($addressPrefixArray[1], 10))
|
||||
|
||||
$gatewaySubnet = Get-AzureRmVirtualNetworkSubnetConfig -Name $GatewaySubnetName -VirtualNetwork $VirtualNetwork
|
||||
if (-not $gatewaySubnet) {
|
||||
Write-Host -ForegroundColor DarkRed "Unable to get subnet for deployment. Exiting..."
|
||||
Display-VnetErrorMessage
|
||||
|
||||
exit 4
|
||||
}
|
||||
|
||||
# Using GatewaySubnet range size for all subnets to keep things simple
|
||||
$addressPrefixArray = $gatewaySubnet.AddressPrefix.Split("/")
|
||||
$gwNetworkAddress = $addressPrefixArray[0]
|
||||
$gwNetworkAddressSuffix = $addressPrefixArray[1]
|
||||
[int]$gwNetworkNumBits = $TotalBits - ([convert]::ToInt16($gwNetworkAddressSuffix, 10))
|
||||
|
||||
# Track use subnets
|
||||
$usedSubnets = New-Object 'System.Collections.Generic.HashSet[int]'
|
||||
for($i=0; $i -lt $VirtualNetwork.Subnets.Count; $i++) {
|
||||
$subnet = $VirtualNetwork.Subnets[$i]
|
||||
if ($subnet.Name.Equals($SubnetName)) {
|
||||
# Found an existing given subnet, return it
|
||||
return $subnet.AddressPrefix
|
||||
}
|
||||
|
||||
[uint32]$value = Get-NetworkValue ($subnet.AddressPrefix.Split("/"))[0]
|
||||
$value = $value -shr $gwNetworkNumBits
|
||||
$mask = (1 -shl ($networkNumBits - $gwNetworkNumBits)) - 1
|
||||
$value = $value -band $mask
|
||||
|
||||
$usedSubnets.Add($value) | Out-Null
|
||||
}
|
||||
|
||||
# Find a free subnet
|
||||
$numSubnets = 1 -shl ($networkNumBits - $gwNetworkNumBits)
|
||||
for([uint32]$i=1; $i -lt $numSubnets; $i++) {
|
||||
if (-not $usedSubnets.Contains($i)) {
|
||||
# Found a free subnet
|
||||
|
||||
[uint32]$value = Get-NetworkValue $networkAddress
|
||||
$value = $value -bor ($i -shl $gwNetworkNumBits)
|
||||
|
||||
$newSubnetAddress = Get-NetworkAddress $value
|
||||
$newSubnetPrefix = "$($newSubnetAddress)/$($gwNetworkAddressSuffix)"
|
||||
|
||||
# Create the new subnet
|
||||
New-Subnet -VirtualNetwork $VirtualNetwork `
|
||||
-SubnetName $SubnetName `
|
||||
-SubnetPrefix $newSubnetPrefix | Out-Null
|
||||
|
||||
return $newSubnetPrefix
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host -ForegroundColor DarkRed "Unable to find free subnet for deployment. Exiting..."
|
||||
Display-VnetErrorMessage
|
||||
|
||||
exit 4
|
||||
} catch {
|
||||
Write-Host -ForegroundColor DarkRed "Unable to get subnet for deployment. Exiting..."
|
||||
Display-VnetErrorMessage
|
||||
|
||||
Write-Host $Error[0]
|
||||
|
||||
exit 4
|
||||
}
|
||||
}
|
||||
|
||||
# Creates a subnet under given VNET
|
||||
Function New-Subnet(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[object] $VirtualNetwork,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $SubnetName,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string] $SubnetPrefix
|
||||
)
|
||||
{
|
||||
Add-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -VirtualNetwork $VirtualNetwork -AddressPrefix $SubnetPrefix
|
||||
Set-AzureRmVirtualNetwork -VirtualNetwork $VirtualNetwork
|
||||
}
|
||||
|
||||
Function Display-VnetErrorMessage()
|
||||
{
|
||||
Write-Host -ForegroundColor DarkRed "Unable to determine VNET or subnet used for this deployment."
|
||||
Write-Host -ForegroundColor DarkRed "If your setup uses point-to-site VPN configuration, please run DeployVPN.ps1 script before running this script."
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
#Requires -RunAsAdministrator
|
||||
#Requires -Modules AzureRM.Network
|
||||
#Requires -Modules AzureRM.profile
|
||||
|
||||
# This script deploys a Domain Controller on an existing VNET resource group and assigns the DNS address of VNET to the DC IP address
|
||||
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$SubscriptionName,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Location,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$ResourceGroupName,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$VNetName,
|
||||
|
||||
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, HelpMessage="Domain name to create.")]
|
||||
[string]$DomainName,
|
||||
|
||||
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, HelpMessage="Domain admin user name.")]
|
||||
[string]$DomainUserName,
|
||||
|
||||
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, HelpMessage="Domain admin user password.")]
|
||||
[securestring]$DomainUserPassword
|
||||
)
|
||||
|
||||
$scriptPath = $MyInvocation.MyCommand.Path
|
||||
$scriptDir = Split-Path $scriptPath
|
||||
Import-Module (Join-Path $scriptDir CommonNetworking.psm1) -Force
|
||||
|
||||
# Name of the subnet in which Domain Controller will be present
|
||||
$SubnetName = "DCSubnet"
|
||||
|
||||
# Select subscription
|
||||
Select-AzureRmSubscription -SubscriptionName $SubscriptionName
|
||||
$subscription = Get-AzureRmSubscription -SubscriptionName $SubscriptionName
|
||||
$SubscriptionId = $subscription.Subscription.SubscriptionId
|
||||
|
||||
# Create a subnet for DC deployment
|
||||
$virtualNetwork = Get-VirtualNetworkOrExit -ResourceGroupName $ResourceGroupName -VirtualNetworkName $VNetName
|
||||
$subnetAddressPrefix = Get-AvailableSubnetOrExit -VirtualNetwork $virtualNetwork -SubnetName $SubnetName
|
||||
|
||||
$templateParameters = @{
|
||||
adminUsername=$DomainUserName
|
||||
adminPassword=$DomainUserPassword
|
||||
domainName=$DomainName
|
||||
existingVirtualNetworkName=$VNetName
|
||||
existingVirtualNetworkAddressRange=$virtualNetwork.AddressSpace.AddressPrefixes[0]
|
||||
dcSubnetName=$SubnetName
|
||||
existingSubnetAddressRange=$subnetAddressPrefix
|
||||
}
|
||||
|
||||
$templateFilePath = Join-Path (Join-Path (Split-Path -Parent $scriptDir) 'armTemplates') 'dc-deploy.json'
|
||||
$out = New-AzureRmResourceGroupDeployment -Name DeployDC `
|
||||
-ResourceGroupName $ResourceGroupName `
|
||||
-TemplateFile $templateFilePath `
|
||||
-TemplateParameterObject $templateParameters
|
||||
|
||||
# Update the DNS server address for VNET
|
||||
$virtualNetwork.DhcpOptions.DnsServers = $out.Outputs.dcIp.Value
|
||||
Set-AzureRmVirtualNetwork -VirtualNetwork $virtualNetwork
|
|
@ -0,0 +1,106 @@
|
|||
#Requires -RunAsAdministrator
|
||||
#Requires -Modules AzureRM.Network
|
||||
#Requires -Modules AzureRM.profile
|
||||
|
||||
# This script deploys a Azure Virtual Network, subnet and VPN gateway
|
||||
# Use this script when connectivity from onpremises to Azure VNET is using point-to-site VPN connection
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$SubscriptionName,
|
||||
|
||||
# Under this resource group common resources like VPN gateway, Virtual network will be deployed.
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$ResourceGroupName,
|
||||
|
||||
# The name of Azure VNet resource.
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$VNetName,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Location,
|
||||
|
||||
# The name of the Azure VNet Gateway resource.
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$VNetGatewayName,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$AddressPrefix = "10.254.0.0/16",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$GatewaySubnetPrefix = "10.254.1.0/24",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$OnpremiseVPNClientSubnetPrefix = "192.168.200.0/24",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$RootCertificateName = "VPN-RootCert-$($VNetName)",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$ChildCertificateName = "VPN-ChildCert-$($VNetName)"
|
||||
)
|
||||
|
||||
# Import the common functions
|
||||
$scriptPath = $MyInvocation.MyCommand.Path
|
||||
$scriptDir = Split-Path $scriptPath
|
||||
Import-Module (Join-Path $scriptDir Common.psm1) -Force
|
||||
|
||||
# Select subscription
|
||||
Select-AzureRmSubscription -SubscriptionName $SubscriptionName
|
||||
$subscription = Get-AzureRmSubscription -SubscriptionName $SubscriptionName
|
||||
$SubscriptionId = $subscription.Subscription.SubscriptionId
|
||||
|
||||
# Create the resource group if needed
|
||||
New-ResourceGroupIfNotExists $ResourceGroupName -Location $Location
|
||||
|
||||
# Deploy VNET, Gateway Subnet and VPN gateway
|
||||
$templateParamsVpnGateway = @{
|
||||
gatewayName=$VNetGatewayName
|
||||
virtualNetworkName=$VNetName
|
||||
edwAzureVNetAddressPrefix=$AddressPrefix
|
||||
vpnGatewaySubnetPrefix=$GatewaySubnetPrefix
|
||||
}
|
||||
|
||||
Write-Host -ForegroundColor Yellow "VPN Gateway deployment could take upto 45 minutes"
|
||||
|
||||
$templateFilePath = Join-Path (Join-Path (Split-Path -Parent $scriptDir) 'armTemplates') 'vpn-gateway.json'
|
||||
$vpnGwDeployment = New-AzureRmResourceGroupDeployment -Name VpnGateway `
|
||||
-ResourceGroupName $ResourceGroupName `
|
||||
-TemplateFile $templateFilePath `
|
||||
-TemplateParameterObject $templateParamsVpnGateway `
|
||||
-Verbose
|
||||
|
||||
Write-Host "Generating certificates for VPN gateway"
|
||||
|
||||
# Generate a self signed root certificate
|
||||
$vpnRootCert = New-SelfSignedCertificate -Type Custom -KeySpec Signature `
|
||||
-Subject "CN=$($RootCertificateName)" -KeyExportPolicy Exportable `
|
||||
-HashAlgorithm sha256 -KeyLength 2048 `
|
||||
-CertStoreLocation "Cert:\CurrentUser\My" -KeyUsageProperty Sign -KeyUsage CertSign
|
||||
|
||||
# Add the self signed root certificate to the trusted root certificates store
|
||||
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
|
||||
[System.Security.Cryptography.X509Certificates.StoreName]::Root,
|
||||
"currentuser"
|
||||
)
|
||||
$store.open("MaxAllowed")
|
||||
$store.add($vpnRootCert)
|
||||
$store.close()
|
||||
|
||||
# Generate a client certificate
|
||||
New-SelfSignedCertificate -Type Custom -KeySpec Signature `
|
||||
-Subject "CN=$($ChildCertificateName)" -KeyExportPolicy Exportable `
|
||||
-HashAlgorithm sha256 -KeyLength 2048 `
|
||||
-CertStoreLocation "Cert:\CurrentUser\My" `
|
||||
-Signer $vpnRootCert -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2")
|
||||
|
||||
# Get root certificate public key data to be used by VPN gateway
|
||||
$certBase64 = [system.convert]::ToBase64String($vpnRootCert.RawData)
|
||||
$rootCert = New-AzureRmVpnClientRootCertificate -Name $RootCertificateName -PublicCertData $certBase64
|
||||
|
||||
$gateway = Get-AzureRmVirtualNetworkGateway -Name $VNetGatewayName -ResourceGroupName $ResourceGroupName
|
||||
|
||||
Write-Host "Updating VPN gateway with certificates"
|
||||
|
||||
Set-AzureRmVirtualNetworkGateway -VirtualNetworkGateway $gateway `
|
||||
-VpnClientAddressPool $OnpremiseVPNClientSubnetPrefix `
|
||||
-VpnClientRootCertificates $rootCert
|
Загрузка…
Ссылка в новой задаче