How to deploy an Azure Site Recovery template to Azure Stack Hub using PowerShell
This document explains how to deploy an Azure Site Recovery configuration server Azure Resource Manager (ARM) template to Azure Stack Hub using PowerShell.
It will guide you through the process of:
-
-
Obtaining an ARM template
-
Deploying an ARM template for Azure Site Recovery
What is an ARM template?
You can use ARM templates to deploy and provision all the resources for your application in a single, coordinated operation. You can also redeploy templates to make changes to the resources in a resource group. You can deploy these templates via the Azure Stack Hub portal, PowerShell, Azure CLI, REST API and Visual Studio. Microsoft provides some quick-start templates on GitHub.
Prerequisites
Prerequisites from a Windows-based external client are:
-
-
PowerShell 5.1 and AzureStack PowerShell Module.
-
A service principal with contributor permissions on both Azure and Azure Stack Hub.
-
A virtual network in Azure Stack Hub to deploy the Azure Site Recovery configuration server to.
-
For any VMs that you want protecting, be sure to add the relevant custom script extension. These are required as specified in the Azure Stack Hub Site Recovery documentation.
Microsoft documentation
-
-
-
-
Understand the structure and syntax of Azure Resource Manager Templates
-
-
What does the template deploy?
This template deploys a Windows Server Datacenter 2016 virtual machine, which is then configured for use with Azure Site Recovery. It also creates the following resources:
-
-
A storage account for the configuration server disks
-
A network security group for the configuration server
-
A network interface for the configuration server
-
A public IP address for the configuration server
-
Creates a resource group (can use existing), recovery services vault (can use existing), storage account and virtual network on public Azure
Notes
The images used to create this deployment are:
-
-
Windows Server Datacenter 2016
-
Windows Custom Script Extension
Configuration
-
- The configuration server will have a 127 GB OS disk, and two 600 GB data disks.
Overview of the ARM template deployment process for Azure Stack Hub using service principal name (SPN) authentication
-
-
Declare your variables accordingly.
-
Create your Azure Stack Hub environment.
-
Log in to your Azure Stack Hub Subscription with the service principal name (SPN).
-
Check if a resource group and virtual network exist.
-
Deploy resources from the ARM template.
Declare variables
Variable name | Variable description | Input |
---|---|---|
$StackArmEndpoint | The Azure Resource Manager endpoint for Azure Stack Hub | |
$StackResourceGroup | The resource group to deploy the ASR configuration server to on Azure Stack Hub | |
$ClientId | The application ID of a service principal with contributor permissions on Azure Stack Hub and Azure | |
$ClientSecret | A password of the service principal specified in the ClientID parameter | |
$StackVNetName | The name of the existing virtual network to connect the configuration server to on Azure Stack Hub | |
$StackSubnetName | The name of the existing virtual network subnet to connect the configuration server to on Azure Stack Hub | |
$StackStorageAccount | The name of the storage account to be created on Azure Stack Hub (Must be unique across Azure Stack Hub) | |
$AzureResourceGroup | The name of the resource group to be created on public Azure | |
$ExistingAzureRG | Select True if the resource group already exists in public Azure | |
$AzureLocation | The location of the recovery services vault on public Azure | |
$AzureVNetName | The name of the virtual network to be created on public Azure | |
$AzureVNetRange | The address space of the virtual network to be created on public Azure (In CIDR notation) | |
$AzureSubnetRange | The subnet range of the virtual network to be created on public Azure (In CIDR notation) | |
$AzureStorageAccount | The name of the storage account to be created on public Azure (Must be unique across public Azure) | |
$VaultName | The name of the recovery services vault to be created on public Azure | |
$ExistingAzureVault | Select True if the vault already exists in public Azure | |
$ReplicationPolicyName | The name of the site recovery replication policy to be created in the recovery services vault | |
$ConfigServerUsername | The username for the configuration server | |
$ConfigServerPassword | The password for the configuration server | |
$ConfigurationServerName | The name of the configuration server VM | |
$TempFilesPath | Location on configuration server where setup files will be stored | |
$ExtractionPath | The name of the folder within the TempFilesPath where the configuration server unified setup will be extracted to | |
$MySqlRootPassword | The root password for the MySQL server created on the Configuration Server (Must meet password requirements specified below) | |
$MySqlUserPassword | The user password for the MySQL server created on the Configuration Server (Must meet password requirements specified below) | |
$EncryptionKey | The encryption key for the MySQL database on the configuration server | |
$WindowsUsername | The username of an administrator account on the Windows VMs to be protected | |
$WindowsPassword | The password of an administrator account on the Windows VMs to be protected | |
$LinuxRootPassword | The password of the root account on the Linux VMs to be protected | |
MySQL password requirements
MySQL passwords must conform to all of the following rules:
-
-
Must contain at least one letter
-
Must contain at least one number
-
Must contain at least one special character (_!@#$%)
-
Must be between 8 and 16 characters
-
Cannot contain spaces
Deploy ARM template code
Change the required variables as per your environment and run the following script:
# Initialise environment and variables
# Declare endpoint
$StackArmEndpoint = ""
## Add environment
Add-AzEnvironment -Name "AzureStackUser" -ArmEndpoint $StackArmEndpoint
## Login
Connect-AzAccount -EnvironmentName "AzureStackUser"
# Get location of Azure Stack Hub
$Location = (Get-AzLocation).Location
# Declare template variables
$StackResourceGroup = ""
$ClientId = ""
$ClientSecret = ''
$StackVNetName = ""
$StackSubnetName = ""
$StackStorageAccount = ""
$AzureResourceGroup = ""
$ExistingAzureRG =
$Azure$AzureVNetName = ""
$AzureVNetRange = ""
$AzureSubnetRange = ""
$AzureStorageAccount = ""
$VaultName = ""
$ExistingAzureVault =
$ReplicationPolicyName = ""
$ConfigServerUsername = ""
$ConfigServerPassword = ''
$ConfigurationServerName = ""
$TempFilesPath = ""
$ExtractionPath = ""
$MySqlRootPassword = ''
$MySqlUserPassword = ''
$EncryptionKey = ''
$WindowsUsername = ""
$WindowsPassword = ''
$LinuxRootPassword = ''
$TemplateUri = "https://raw.githubusercontent.com/UKCloud/AzureStack/master/Users/ARM%20Templates/Azure%20Site%20Recovery%20-%20Config%20Server/azuredeploy.json"
# Validate that resource group, virtual network and subnet exist
$TestRG = Get-AzResourceGroup -Name $StackResourceGroup
if ($TestRG) {
$TestVNet = Get-AzVirtualNetwork -Name $StackVNetName -ResourceGroupName $StackResourceGroup
if ($TestVNet) {
$TestSubnet = Get-AzVirtualNetworkSubnetConfig -Name $StackSubnetName -VirtualNetwork $TestVNet
if ($TestSubnet) {
Write-Output -InputObject "Validated resource group, virtual network and subnet successfully"
}
else {
Write-Error -Message "Could not find subnet with name $StackSubnetName, please check and try again"
break
}
}
else {
Write-Error -Message "Could not find virtual network with name $StackVNetName, please check and try again"
break
}
}
else {
Write-Error -Message "Could not find resource group with name $StackResourceGroup, please check and try again"
break
}
# Create ARM template parameters object
$TemplateParameters = @{
"Client ID" = $ClientId
"Client Secret" = $ClientSecret
"Stack Arm Endpoint" = $StackArmEndpoint
"Stack VNet Name" = $StackVNetName
"Stack Subnet Name" = $StackSubnetName
"Stack Storage Account" = $StackStorageAccount
"Azure Resource Group" = $AzureResourceGroup
"Existing Azure Resource Group" = $ExistingAzureRG
"Azure Location" = $AzureLocation
"Azure VNet Name" = $AzureVNetName
"Azure VNet Range" = $AzureVNetRange
"Azure Subnet Range" = $AzureSubnetRange
"Azure Storage Account" = $AzureStorageAccount
"Vault Name" = $VaultName
"Existing Azure Vault" = $ExistingAzureVault
"Replication Policy Name" = $ReplicationPolicyName
"Config Server Username" = $ConfigServerUsername
"Config Server Password" = $ConfigServerPassword
"Config Server Name" = $ConfigurationServerName
"Temporary Files Path" = $TempFilesPath
"Extraction Path" = $ExtractionPath
"MySQL Root Password" = $MySqlRootPassword
"MySQL User Password" = $MySqlUserPassword
"Encryption Key" = $EncryptionKey
"Windows Username" = $WindowsUsername
"Windows Password" = $WindowsPassword
"Linux Root Password" = $LinuxRootPassword
}
# Test deployment
$TestDeployment = Test-AzResourceGroupDeployment -ResourceGroupName $StackResourceGroup -TemplateUri $TemplateUri -TemplateParameterObject $TemplateParameters
# Deploy ARM template
if ($TestDeployment.Count -eq 0) {
Write-Output -InputObject "Deploying ARM template..."
Write-Warning -Message "This may take a while..."
New-AzResourceGroupDeployment -ResourceGroupName $StackResourceGroup -TemplateUri $TemplateUri -TemplateParameterObject $TemplateParameters -Name "AzureSiteRecovery"
}
else {
Write-Warning -Message "Unable to deploy ARM template due to following issue(s):"
$TestDeployment
break
}
Feedback
If you find a problem with this article, click Improve this Doc to make the change yourself or raise an issue in GitHub. If you have an idea for how we could improve any of our services, send an email to [email protected].