Rik Hepworth - ARM Yourself for Effective Azure Provisioning
Provisioning in Microsoft Azure
Transcript of Provisioning in Microsoft Azure
Развертывания и настройка окружений, автоматизация и шаблонизация, инструменты и сценарии, Azure PowerShell
Provisioning в Microsoft Azure
Eugene Ilaginhttps://github.com/ilagin/
• Что такое Provisioning?
• Зачем это знать и где применять?
• Ручная настройка окружения или автоматическая?
• Provisioning как элемент Continuous Delivery.
Введение
Hands-on примерAPI Server Web Server
Database Server Replication Server
Web API Web App
Replicated Database
Database
Transactional Replication
• Миграция web-приложения с on-premises на IaaS
• Набор скриптов, позволяющий сделать все в один клик
• Azure PowerShell – open source модуль для Windows PowerShell
• Azure Account. Subscription
• Способы подключения к Azure подписке• Azure AD• Сертификат
https://github.com/Azure/azure-powershell/releases
Установка Azure PowerShell и подключение подписки
Создание Storage Account
Шаг 1.
$commonLocation = "North Europe"$storageAccountName = "ilagin"$subscriptionName = Get-AzureSubscription | Select SubscriptionName New-AzureStorageAccount -StorageAccountName $storageAccountName -Label "TestStorage" -Location $commonLocationSelect-AzureSubscription $subscriptionName.SubscriptionName.ToString()Set-AzureSubscription -SubscriptionName $subscriptionName.SubscriptionName.ToString() -CurrentStorageAccount $storageAccountName
• Объединение виртуальных машин в LAN
• Доступ к ресурсам в пределах LAN
• Организация VPN
• Создание VNet перед созданием VM
Шаг 2. Создание Виртуальной Сети
<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration"> <VirtualNetworkConfiguration> <Dns /> <VirtualNetworkSites> <VirtualNetworkSite name="MyVirtualNetwork" Location="North Europe"> <AddressSpace> <AddressPrefix> 10.0.0.1/26</AddressPrefix> </AddressSpace> <Subnets> <Subnet name="Subnet1"> <AddressPrefix> 10.0.0.1/26</AddressPrefix> </Subnet> </Subnets> </VirtualNetworkSite> </VirtualNetworkSites> </VirtualNetworkConfiguration></NetworkConfiguration>
Set-AzureVNetConfig -ConfigurationPath "D:\NetworkConfig.netcfg"
• Доступные образы: Get-AzureVMImage.
• Vmdepot.com
• Выбор конфигурации. A0-A11. D1- D14.
• VM с MS SQL стоят дороже.
• Операции создания и provisioning’a занимают относительно длительное время
Шаг 3. Создание Виртуальных Машин
$commonLocation = "North Europe"$webServerImageName = "bd507d3a70934695bc2128e3e5a255ba__RightImage-Windows-2012-x64-iis8-v14.2"$dbServerImageName = "fb83b3509582419d99629ce476bcb5c8__SQL-Server-2012-SP2-11.0.5569.0-Ent-ENU-Win2012-cy15su02"$virtualNetworkName = "MyVirtualNetwork"$subnetName = "Subnet1" $vmNames = @("ilgonetest", "ilgtwotest", "ilgthreetest", "ilgfourtest") $pwd = "Super Secure Password1"$instanceSize = "Large"$userName = "eugene" $vm0 = New-AzureVMConfig -Name $vmNames[0] -InstanceSize $instanceSize -Image $webServerImageName$vm0 | Add-AzureProvisioningConfig -Windows -AdminUserName $userName -Password $pwd | Set-AzureSubnet $subnetName$vm0 | New-AzureVM -ServiceName $vmNames[0] -VNetName $virtualNetworkName –Location $commonLocation
$vm1 = New-AzureVMConfig -Name $vmNames[1] -InstanceSize $instanceSize -Image $webServerImageName$vm1 | Add-AzureProvisioningConfig -Windows -AdminUserName $userName -Password $pwd | Set-AzureSubnet $subnetName$vm1 | New-AzureVM -ServiceName $vmNames[1] -VNetName $virtualNetworkName –Location $commonLocation $vm2 = New-AzureVMConfig -Name $vmNames[2] -InstanceSize $instanceSize -Image $dbServerImageName$vm2 | Add-AzureProvisioningConfig -Windows -AdminUserName $userName -Password $pwd | Set-AzureSubnet $subnetName$vm2 | New-AzureVM -ServiceName $vmNames[2] -VNetName $virtualNetworkName –Location $commonLocation $vm3 = New-AzureVMConfig -Name $vmNames[3] -InstanceSize $instanceSize -Image $dbServerImageName$vm3 | Add-AzureProvisioningConfig -Windows -AdminUserName $userName -Password $pwd | Set-AzureSubnet $subnetName$vm3 | New-AzureVM -ServiceName $vmNames[3] -VNetName $virtualNetworkName –Location $commonLocation
• Потеря IP адреса после выключения
• Зависимость ресурсов от IP адреса
Шаг 4. Присвоение статических IP
$vmNames = @("ilgonetest", "ilgtwotest", "ilgthreetest", "ilgfourtest")$staticIPs = @("10.0.0.4", "10.0.0.5", "10.0.0.6", "10.0.0.7") for($i=0; $i -le 3; $i++){
Get-AzureVM -ServiceName $vmNames[$i] -Name $vmNames[$i] | Set-AzureStaticVNetIP -IPAddress $staticIPs[$i] | Update-AzureVM}
Шаг 5. Добавление Endpoint’ов к виртуальным машинам• Что такое endpoint?
• 2 endpoint’а по умолчанию: RDP, PowerShell
• HTTP(80), SQL(1433) и другие - закрыты
$webVmNames = @("ilgonetest", "ilgtwotest") foreach($vm in $webVmNames){
Get-AzureVM -ServiceName $vm -Name $vm | Add-AzureEndpoint -Name "HttpIn" -Protocol "tcp" -PublicPort 80 -LocalPort 80 | Update-AzureVM}
Шаг 6.
Отключение Windows Firewall
$vmNames = @("ilgonetest", "ilgtwotest", "ilgthreetest", "ilgfourtest") $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) foreach($vm in $vmNames){
$uri = Get-AzureWinRMUri -ServiceName $vm -Name $vm $sessionOption = New-PSSessionOption -SkipCACheck:$true -
SkipCNCheck:$true -SkipRevocationCheck:$true
$session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOption
Invoke-Command -Session $session -ScriptBlock {Get-NetFirewallProfile | Set-NetFirewallProfile –Enabled False}
$session | Remove-PSSession}
•Обзор доступных вариантов
• VHD – Virtual Hard Drive
• Azure Blob Storage
Шаг 7. Загрузка файлов на VM
$vmNames = @("ilgonetest", "ilgtwotest", "ilgthreetest", "ilgfourtest")$volumePath = "D:\FileStorage.vhd"$folderToCopy = "D:\PRJ"$azureStoragePaths = ("http://ilagin.blob.core.windows.net/vhdstore/FileStorage0.vhd", "http://ilagin.blob.core.windows.net/vhdstore/FileStorage1.vhd", "http://ilagin.blob.core.windows.net/vhdstore/FileStorage2.vhd", "http://ilagin.blob.core.windows.net/vhdstore/FileStorage3.vhd") $volume = new-vhd -Path $volumePath -SizeBytes 40MB | ` Mount-VHD -PassThru | ` Initialize-Disk -PartitionStyle mbr -Confirm:$false -PassThru | ` New-Partition -UseMaximumSize -AssignDriveLetter -MbrType IFS | ` Format-Volume -NewFileSystemLabel "VHD" -Confirm:$false Copy-Item $folderToCopy "$($volume.DriveLetter):\" -RecurseDismount-VHD $volumePath
for($i=0; $i -le 3; $i++){
Add-AzureVhd -Destination $azureStoragePaths[$i] -LocalFilePath $volumePath
Get-AzureVM $vmNames[$i] $vmNames[$i] | Add-AzureDataDisk -ImportFrom -MediaLocation $azureStoragePaths[$i] -DiskLabel "EXT" -LUN 0 | Update-AzureVM}
Шаг 8.
Удаленное конфигурирование IIS
$webVmNames = @("ilgonetest", "ilgtwotest")$webPaths = @("E:\PRJ\API", "E:\PRJ\Web") $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword)$i = 0 foreach($vm in $webVmNames){
$uri = Get-AzureWinRMUri -ServiceName $vm -Name $vm$sessionOption = New-PSSessionOption -SkipCACheck:$true -
SkipCNCheck:$true -SkipRevocationCheck:$true
$session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOption
Invoke-Command -Session $session -ScriptBlock {param($path, $user, $password)Set-ExecutionPolicy RemoteSignedImport-Module WebAdministration
if (!(Test-Path $path)){
$path = $path.Replace("E:", "F:")}
Remove-Item IIS:\AppPools\AdminAppPool -Force -Recurse
$appPool = New-WebAppPool -Name "AdminAppPool"$appPool.processModel.userName = $user$appPool.processModel.password = $password$appPool.processModel.identityType = "SpecificUser"$appPool | Set-Item
}
Remove-Item IIS:\Sites\"Default Web Site" -Force -RecurseRemove-Item IIS:\Sites\AzureProvisioning -Force -RecurseNew-Item IIS:\Sites\AzureProvisioning -physicalPath $path -
bindings @{protocol="http";bindingInformation=":80:"}
Set-ItemProperty IIS:\Sites\AzureProvisioning -name applicationPool -value AdminAppPool
} -Args $webPaths[$i], $userName, $pwd$session | Remove-PSSession$i++
}
Шаг 9.
Добавление Windows пользователей
$sqlVmNames = @("ilgthreetest", "ilgfourtest") $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) $newUserName = "Replication" foreach($vm in $sqlVmNames){
$uri = Get-AzureWinRMUri -ServiceName $vm -Name $vm$sessionOption = New-PSSessionOption -SkipCACheck:$true -SkipCNCheck:
$true -SkipRevocationCheck:$true
$session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOption
Invoke-Command -Session $session -ScriptBlock {
param($vmName, $userToCreate, $userPassword)$Computer = [ADSI]("WinNT://" + $vmName)$LocalAdmin = $Computer.Create("User", $userToCreate)$LocalAdmin.SetPassword($userPassword) $LocalAdmin.SetInfo() $LocalAdmin.FullName = "Azure Provisioning Demo" $LocalAdmin.SetInfo() $LocalAdmin.UserFlags = 64 + 65536 #
ADS_UF_PASSWD_CANT_CHANGE + ADS_UF_DONT_EXPIRE_PASSWD $LocalAdmin.SetInfo() $objOU = [ADSI]("WinNT://" + $vmName +
"/Administrators,group")$objOU.add("WinNT://" + $vmName +"/" + $userToCreate)
} -Args $vm, $newUserName, $pwd$session | Remove-PSSession
}
Шаг 10.
Добавление SQL пользователей
$sqlVmNames = @("ilgthreetest", "ilgfourtest") $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) $newUserName = "Replication" foreach($vm in $sqlVmNames){
$uri = Get-AzureWinRMUri -ServiceName $vm -Name $vm$sessionOption = New-PSSessionOption -SkipCACheck:$true -SkipCNCheck:$true -
SkipRevocationCheck:$true
$session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOption
Invoke-Command -Session $session -ScriptBlock { param($vmName, $userName, $userPassword)Set-ExecutionPolicy RemoteSignedImport-Module SQLPS -DisableNameChecking
$SQLInstanceName = "(local)"$Server = New-Object -TypeName
Microsoft.SqlServer.Management.Smo.Server -ArgumentList $SQLInstanceName
if ($Server.Logins.Contains($userName)){
$Server.Logins[$userName].Drop()}
$Login = New-Object -TypeName
Microsoft.SqlServer.Management.Smo.Login -ArgumentList $Server, $userName$Login.LoginType =
[Microsoft.SqlServer.Management.Smo.LoginType]::SqlLogin$Login.PasswordExpirationEnabled = $false
$Login.Create($userPassword)$Login.AddToRole("sysadmin")$Login.Alter()
$replicationWindowsUser = $vmName + "\Replication"
if ($Server.Logins.Contains($replicationWindowsUser)){
$Server.Logins[$replicationWindowsUser].Drop()}
$Login = New-Object -TypeName
Microsoft.SqlServer.Management.Smo.Login -ArgumentList $Server, $replicationWindowsUser
$Login.LoginType = [Microsoft.SqlServer.Management.Smo.LoginType]::WindowsUser
$Login.PasswordExpirationEnabled = $false
$Login.Create($userPassword)$Login.AddToRole("sysadmin")$Login.Alter()
} -Args $vm, $newUserName, $pwd$session | Remove-PSSession
}
Шаг 11.
Изменение режима проверки подлинности SQL сервера.
Включение SQL Server Agent.
$sqlVmNames = @("ilgthreetest", "ilgfourtest") $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) $newUserName = "Replication" foreach($vm in $sqlVmNames){
$uri = Get-AzureWinRMUri -ServiceName $vm -Name $vm$sessionOption = New-PSSessionOption -SkipCACheck:$true -
SkipCNCheck:$true -SkipRevocationCheck:$true
$session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOptionInvoke-Command -Session $session -ScriptBlock {
param($vmName)
Set-ExecutionPolicy RemoteSignedImport-Module SQLPS -DisableNameChecking
$sqlServer = new-object
('Microsoft.SqlServer.Management.Smo.Server') '(local)'$sqlServer.Settings.LoginMode =
[Microsoft.SqlServer.Management.SMO.ServerLoginMode]::Mixed
$sqlServer.Alter()CD SQLSERVER:\SQL\$vmName$Wmi = (get-item .).ManagedComputer
$sqlInstance = $Wmi.Services['MSSQLSERVER']$sqlInstance.Stop()Start-Sleep -s 10$sqlInstance.Start()
$agent = $Wmi.Services['SQLSERVERAGENT']$agent.Start()
} -Args $vm
$session | Remove-PSSession}
Шаг 12.
Восстановление бэкапа базы
$sqlVmNames = @("ilgthreetest", "ilgfourtest") $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) foreach($vm in $sqlVmNames){
$uri = Get-AzureWinRMUri -ServiceName $vm -Name $vm$sessionOption = New-PSSessionOption -SkipCACheck:$true -
SkipCNCheck:$true -SkipRevocationCheck:$true
$session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOption
Invoke-Command -Session $session -ScriptBlock { Set-ExecutionPolicy RemoteSignedImport-Module SQLPS -DisableNameChecking
$srv = new-Object Microsoft.SqlServer.Management.Smo.Server("(local)")$db = New-Object
Microsoft.SqlServer.Management.Smo.Database($srv, "AzureProvisioning")$db.Create()
$backupFilePath = "E:\PRJ\db.bak"
if (!(Test-Path $backupFilePath)){
$backupFilePath = "F:\PRJ\db.bak"}
Restore-SqlDatabase -ServerInstance "(local)" -Database
AzureProvisioning -BackupFile $backupFilePath -ReplaceDatabase}
$session | Remove-PSSession}
Шаг 13.1
Создание репликации. Конфигурация publisher’а
$distributorVm = "ilgthreetest" $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) $uri = Get-AzureWinRMUri -ServiceName $distributorVm -Name $distributorVm$sessionOption = New-PSSessionOption -SkipCACheck:$true -SkipCNCheck:$true -SkipRevocationCheck:$true $session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOptionInvoke-Command -Session $session -ScriptBlock {
Set-ExecutionPolicy RemoteSignedImport-Module SQLPS -DisableNameChecking
$publicationFilePath = "E:\PRJ\publication.sql"
if (!(Test-Path $publicationFilePath)){
$publicationFilePath = "F:\PRJ\publication.sql"}
Invoke-SqlCmd -InputFile $publicationFilePath -ServerInstance "(local)"} $session | Remove-PSSession
Шаг 13.2
Создание репликации. Копирование базы
$sqlSubscriberVM = "ilgfourtest" $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) $uri = Get-AzureWinRMUri -ServiceName $sqlSubscriberVM -Name $sqlSubscriberVM$sessionOption = New-PSSessionOption -SkipCACheck:$true -SkipCNCheck:$true -SkipRevocationCheck:$true $session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOption
Invoke-Command -Session $session -ScriptBlock { $pathToShare = "E:\PRJ"
if (!(Test-Path $pathToShare)){
$pathToShare = $pathToShare.Replace("E:", "F:")}$netSharePath = "PRJ=" + $pathToSharenet user guest /active:yesnet share $netSharePath "/GRANT:Everyone,FULL"
} $session | Remove-PSSession
$session | Remove-PSSession $sqlPublisherVM = "ilgthreetest" $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) $uri = Get-AzureWinRMUri -ServiceName $sqlPublisherVM -Name $sqlPublisherVM$sessionOption = New-PSSessionOption -SkipCACheck:$true -SkipCNCheck:$true -SkipRevocationCheck:$true $session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOption
Invoke-Command -Session $session -ScriptBlock {Set-ExecutionPolicy RemoteSignedImport-Module SQLPS -DisableNameChecking
$path = "E:\PRJ\"
if (!(Test-Path $path)){
$path = $path.Replace("E:", "F:")}
$backupPath = $path + "new.bak"
Backup-SqlDatabase -ServerInstance '(local)' -Database "AzureProvisioning" -BackupFile $backupPath
$pass="Super Secure Password1"|ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object System.Management.Automation.PsCredential("ILGFOURTEST\eugene",$pass)
New-PSDrive -Name R -Root "\\10.0.0.7\PRJ" -PSProvider FileSystem -Credential $cred
Copy-Item $backupPath "R:\"} $session | Remove-PSSession
Шаг 13.3
Создание репликации. Восстановление базы
publisher’а
$uri = Get-AzureWinRMUri -ServiceName $sqlSubscriberVM -Name $sqlSubscriberVM$sessionOption = New-PSSessionOption -SkipCACheck:$true -SkipCNCheck:$true -SkipRevocationCheck:$true $session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOptionInvoke-Command -Session $session -ScriptBlock {
Set-ExecutionPolicy RemoteSignedImport-Module SQLPS -DisableNameChecking$srv = new-Object
Microsoft.SqlServer.Management.Smo.Server("(local)")$db = New-Object Microsoft.SqlServer.Management.Smo.Database($srv,
"AzureProvisioning")$db.Create()
$backupPath = "E:\PRJ\new.bak"
if (!(Test-Path $backupPath)){
$backupPath = $backupPath.Replace("E:", "F:")}
Restore-SqlDatabase -ServerInstance "(local)" -Database
AzureProvisioning -BackupFile $backupPath -ReplaceDatabase}
Шаг 13.3
Создание репликации. Настройка подписки
$session | Remove-PSSession $distributorVm = "ilgthreetest" $userName = "eugene"$pwd = "Super Secure Password1" $securePassword = ConvertTo-SecureString $pwd -AsPlainText -Force$credential = New-Object System.Management.Automation.PSCredential($userName, $securePassword) $uri = Get-AzureWinRMUri -ServiceName $distributorVm -Name $distributorVm$sessionOption = New-PSSessionOption -SkipCACheck:$true -SkipCNCheck:$true -SkipRevocationCheck:$true $session = New-PSSession -ConnectionUri $uri -Credential $credential -SessionOption $sessionOptionInvoke-Command -Session $session -ScriptBlock {
Set-ExecutionPolicy RemoteSignedImport-Module SQLPS -DisableNameChecking
$supscriptionFilePath = "E:\PRJ\subscription.sql"
if (!(Test-Path $supscriptionFilePath)){
$supscriptionFilePath = $supscriptionFilePath.Replace("E:", "F:")}
Invoke-SqlCmd -InputFile $supscriptionFilePath -ServerInstance "(local)"} $session | Remove-PSSession
Шаг 14. Опциональный
Удаление окружения
$vmNames = @("ilgonetest", "ilgtwotest", "ilgthreetest", "ilgfourtest")$storageAccountName = "ilagin" foreach($vm in $vmNames){
Remove-AzureDeployment -ServiceName $vm -Slot Production -DeleteVHD -Force
Remove-AzureService -ServiceName $vm -Force} Remove-AzureVNetConfig Start-Sleep -s 30 Remove-AzureStorageAccount -StorageAccountName $storageAccountName
Заключение
Provisioning в один клик. Fun или необходимость?
Спасибо за внимание!
https://github.com/ilagin/AzureProvisioning