Azure automation을 이용하여 자동 스냅샷 생성
- Azure
- March 1, 2022
Azure VM 백업을 자동화 하기전에 먼저 Azure VM 백업 방식에 대해 알 필요가 있습니다. Azure VM의 모든 데이터를 백업하는 방식은 크게 2가지가 있습니다.
- Azure의 백업 서비스
- 스냅샷
Azure에서 제공하는 백업 서비스 링크
https://docs.microsoft.com/ko-kr/azure/backup/quick-backup-vm-portal
가상 하드 디스크의 Azure 스냅샷 만들기 - Azure Virtual Machines
둘의 큰 차이점은 복구 방법으로 백업 서비스는 백업본으로 가지고 바로 복구할 수 있지만 스냅샷은 직접 한 번 스냅샷으로 디스크를 만든 다음에 VM 디스크를 교체하거나 새 VM에 디스크를 부착해야 합니다.
즉 자동으로 한번에 복구 vs 수동으로 여러 절차를 걸쳐서 복구 이렇게 이해 하시면 됩니다.
Azure native backup vs Azure disk snapshot - UnixArena
내용만 보면 백업이 더 좋지만 비용이 조금 더 들고 현재 SQL 백업이 알 수 없는 오류로 인해 실행되지 못하고 있는 경우도 있습니다.
그래서 스냅샷 방식으로 백업을 하기로 했습니다.
근데 스냅샷은 Azure 백업 서비스와는 달리 수동으로 실행해야 하는 번거로움이 있습니다.
그래서 자동으로 스냅샷을 만들 수 있는 방법이 있을까 찾아보다가 다행히도 누군가가 Automation을 이용하여 자동 스냅샷을 구현한 것을 찾을 수 있었습니다.
Automate Disk Snapshots using Azure | StarWind Blog
아쉽게도 찾은 자료를 그대로 반영하기는 어렵습니다. powerShell의 모듈이 너무 오래전 것이다보니 에러가 발생합니다.
블로그에서 사용한 모듈은 AzureRM으로 2024년 이후로는 서비스가 종료됩니다.
Overview of the AzureRM PowerShell module
문제를 해결하기 귀해서는 AzureRM대신 Az로 변경해야 했습니다.
해당 방법을 적용한 코드입니다.
$connectionName = "AzureRunAsConnection"
try{
#Getting the service principal connection "AzureRunAsConnection"
$servicePrincipalConnection = Get-AutomationConnection -name $connectionName
"Logging into Azure..."
Connect-AzAccount -ServicePrincipal -TenantID $servicePrincipalConnection.TenantID -ApplicationID $servicePrincipalConnection.ApplicationID -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch{
if(!$servicePrincipalConnection){
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage}
else {
Write-Error -Message $_.Exception
throw $_.Exception
}}
if($err) {
throw $err
}
# Get VMs with snapshot tag
$tagResList = Get-AzResource -TagName "Snapshot" -TagValue "True" | foreach {
Get-AzResource -ResourceId $_.resourceid}
foreach($tagRes in $tagResList) {
if($tagRes.ResourceId -match "Microsoft.Compute")
{
# "/"가 아닌 "//"인 것은 아직도 의문이다.
$vmInfo = Get-AzVM -ResourceGroupName $tagRes.ResourceId.Split("//")[4] -Name $tagRes.ResourceId.Split("//")[8]
#Set local variables
$location = $vmInfo.Location
$resourceGroupName = $vmInfo.ResourceGroupName
$timestamp = Get-Date -f MM-dd-yyyy_HH_mm_ss
#Snapshot name of OS data disk
$snapshotName = $vmInfo.Name + $timestamp
#Create snapshot configuration
$snapshot = New-AzSnapshotConfig -SourceUri $vmInfo.StorageProfile.OsDisk.ManagedDisk.Id -Location $location -CreateOption copy
#Take snapshot
New-AzSnapshot -Snapshot $snapshot -SnapshotName $snapshotName -ResourceGroupName $resourceGroupName
if($vmInfo.StorageProfile.DataDisks.Count -ge 1){
#Condition with more than one data disks
for($i=0; $i -le $vmInfo.StorageProfile.DataDisks.Count - 1; $i++){
#Snapshot name of OS data disk
$snapshotName = $vmInfo.StorageProfile.DataDisks[$i].Name + $timestamp
#Create snapshot configuration
$snapshot = New-AzSnapshotConfig -SourceUri $vmInfo.StorageProfile.DataDisks[$i].ManagedDisk.Id -Location $location -CreateOption copy
#Take snapshot
New-AzSnapshot -Snapshot $snapshot -SnapshotName $snapshotName -ResourceGroupName $resourceGroupName
}
}
else{
Write-Host $vmInfo.Name + " doesn't have any additional data disk."
}
}
else{
$tagRes.ResourceId + " is not a compute instance"
}
}
다행히도 쉽게 적용할 수 있었습니다.