使用 PowerShell 自動化 AWS EC2 快照

Amazon Elastic Block Store (EBS) 是一項為 Amazon EC2 實例提供存儲的服務。EBS 是您的 EC2 實例上運行的每個卷。當您依賴一個服務運行重要的基礎設施時,明智的做法是確保數據已經備份。在這篇博客文章中,了解如何使用 PowerShell 腳本語言來管理和自動化 EC2 快照。

每個附加到 EC2 實例的 EBS 卷都可以通過 EBS 快照進行備份。每個快照可以通過兩種方式之一創建;完整或增量快照。嗯,技術上是兩者都可以,但是…就跟我一起進行吧。

當為 EC2 實例創建第一個快照備份時,它會備份整個卷的數據。當創建後續快照時,只有自上一個快照以來已更改的塊級存儲數據被保存。然而,與典型的增量時間點備份不同,由於快照可以鏈接,當恢復快照時,該卷的所有數據都會被恢復,使其類似於完整備份。

快照可以異步發生,這意味著快照可以並行進行創建。當開始時,快照進入待定階段,直到所有必要的塊被複製到存儲所有 EBS 快照的 Amazon S3 中。

使用 PowerShell 創建 AWS EC2 快照

有幾種不同的方法可以使用AWS來管理EBS快照。您可以使用AWS管理控制台、AWS CLI、PowerShell或直接使用API。在本文中,我們將使用PowerShell,因為AWSPowerShell模塊對使用PowerShell命令管理EBS快照具有很好的支持。

先決條件

在我們進一步之前,我將假設您具備以下幾個先決條件,以便從本教程中獲得最大效益。您需要:

  • 一個AWS帳戶
  • 一個已附加卷的EC2實例
  • 使用根用戶或具有CreateSnapshot權限(arn:aws:ec2:region::snapshot/*)的IAM用戶進行身份驗證

完成這些先決條件後,我們就可以開始了!

查找現有的EC2快照

我們首先要做的任務之一是查看是否已經存在任何現有的快照。為了找出這一點,我們使用Get-EC2Snapshot命令。這個命令將搜索已經創建的任何快照並將它們輸出到PowerShell控制台。

PS C:\> Get-EC2Snapshot


DataEncryptionKeyId :
Description         : Business/Industry Summary (Windows)
Encrypted           : False
KmsKeyId            :
OwnerAlias          : amazon
OwnerId             : 947081328633
Progress            : 100%
SnapshotId          : snap-8af818e3
StartTime           : 11/19/2008 6:15:17 AM
State               : completed
StateMessage        :
Tags                : {}
VolumeId            : vol-e1ac4888
VolumeSize          : 15
<SNIP>

您會注意到出現的AWS EC2快照並不是針對您的EC2實例的。這些都是與您共享的快照,可用於還原到您的EC2實例。要發現來自您的EC2實例的所有快照,請使用OwnerId參數並設置為self值。

PS> Get-EC2Snapshot -OwnerId self

創建新的EBS快照

假設您已經創建了一個 EC2 實例,現在可以創建快照。您可以使用 New-EC2Snapshot 命令創建新的快照,但首先,您需要收集每個要創建快照的卷的卷 ID。為此,我們首先需要找到卷所附加到的 EC2 實例 ID。

PS> (Get-EC2Instance).instances
PS> $instanceId = (Get-EC2Instance).instances.InstanceId

一旦您知道了 EC2 實例 ID,您需要使用它來找到這些卷。要找到附加到 EC2 實例的所有卷,您將使用 Get-EC2Volume 命令並過濾輸出,只顯示附加實例 ID 與我們正在查找的實例 ID 相同的卷。

PS> $volumes = Get-EC2Volume | Where-Object { $_.attachments.InstanceId -eq $instanceId }

Attachments      : {i-083007f62ff750d7a}
AvailabilityZone : us-east-1b
CreateTime       : 3/1/2019 7:06:57 AM
Encrypted        : False
Iops             : 100
KmsKeyId         :
Size             : 8
SnapshotId       : snap-0ff5b79fdf9b021e8
State            : in-use
Tags             : {}
VolumeId         : vol-0bf53c62534f99eee
VolumeType       : gp2

現在,我們已經獲得了這些卷,AWS 建議關閉實例或至少卸載卷。我們將關閉實例。

PS> Stop-EC2Instance -InstanceId $instanceId

現在,我們可以遍歷每個卷,並將該卷的 ID 傳遞給 New-EC2Snapshot 命令的 VolumeId 參數。一旦完成,您將注意到快照的狀態變為 pending

foreach ($volume in $volumes) {
    New-EC2Snapshot -VolumeId $volume.VolumeId
}

DataEncryptionKeyId :
Description         :
Encrypted           : False
KmsKeyId            :
OwnerAlias          :
OwnerId             : 013223035658
Progress            :
SnapshotId          : snap-027a3550dde80eb3b
StartTime           : 3/1/2019 7:19:13 AM
State               : pending
StateMessage        :
Tags                : {}
VolumeId            : vol-0bf53c62534f99eee
VolumeSize          : 8

您可以再次運行 Get-EC2Snapshot 命令,並確認 State 現在為 completed,從而確認快照已完成。

分配標籤

如果您有很多快照要管理,可能很難保持它們的分類。為了對快照進行分類並將其分類,您還可以對其分配標籤。標籤是 EC2 的一部分,可以用於您的 EBS 快照。

您可以在創建快照時或之後分配標籤。要在創建快照時分配標籤,請使用 New-EC2Snapshot 命令的 TagSpecification 參數。

例如,也许我想为我刚刚拍摄的 AWS EC2 快照添加标签,以便在进行生产更改之前使用。我想创建一个名为 Stage 的标签,并将其分配为 Dev。为此,我可以创建一个 TagSpecification 对象,将一个或多个 Tag 对象分配给 Tags 属性,然后定义此标签将附加到的资源类型。

$tag = New-Object Amazon.EC2.Model.Tag
$tag.Key = 'Stage'
$tag.Value = 'Dev'
$tagSpec = New-Object Amazon.EC2.Model.TagSpecification
$tagSpec.Tags = $tag
$tagSpec.ResourceType = 'snapshot'

创建 TagSpecification 对象后,我可以将其传递给 New-EC2Snapshot

PS> New-EC2Snapshot -VolumeId <VolumeId> -TagSpecification $tagSpec

从快照创建新的 AMI

快照的另一个很酷的功能是,您可以从快照创建全新的镜像(AMI)。如果您有一个 仅限 Linux EC2 实例的根卷快照,您可以轻松地从该卷快照创建全新的 AMI。假设我想从刚刚创建的快照创建一个新的镜像。我可以使用 New-EC2Image 命令来实现。

I’ll first need to capture the snapshot ID.

PS> $snapshotId = Get-EC2Snapshot -OwnerId self | where {$_.Tags.where({$_.Key -eq 'Stage' -and $_.Value -eq 'Dev'})} | Select-Object -ExpandProperty SnapshotId

然后,我可以将该 ID 作为 hashtable 传递给 New-EC2Image 上的 BlockDeviceMapping 参数。

PS> $block = @{SnapshotId=$snapshotId}
PS> Register-EC2Image -Name 'my_image' -BlockDeviceMapping @{DeviceName="/dev/sda1";Ebs=$block;VirtualName='ephemeral0'} -RootDeviceName '/dev/sda1'

删除 AWS EC2 快照

如果我们完成了快照的使用,我们现在可以将它们删除。这样做很简单。只需将 Get-EC2Snapshot 返回的实例传递给 Remove-EC2Snapshot。然而,如果有一个 AMI 正在使用,您可能会遇到这个错误。

PS> Get-EC2Snapshot -OwnerId self | Remove-EC2Snapshot

Confirm
Are you sure you want to perform this action?
Performing the operation "Remove-EC2Snapshot (DeleteSnapshot)" on target "snap-066ccd492f85192be".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): a
Remove-EC2Snapshot : The snapshot snap-066ccd492f85192be is currently in use by ami-0b353cbd967f6658f
At line:1 char:33
+ Get-EC2Snapshot -OwnerId self | Remove-EC2Snapshot
+                                 ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Amazon.PowerShe...2SnapshotCmdlet:RemoveEC2SnapshotCmdlet) [Remove-EC2Snapshot], InvalidOperationExce
   ption
    + FullyQualifiedErrorId : Amazon.EC2.AmazonEC2Exception,Amazon.PowerShell.Cmdlets.EC2.RemoveEC2SnapshotCmdlet

在这种情况下,AMI 已注册,您必须首先使用 Unregister-EC2Image 命令取消注册它。

PS> $myImage = Get-EC2Image -Owner self
PS> Unregister-EC2Image -ImageId $myImage.ImageId
PS> Get-EC2Snapshot -OwnerId self | Remove-EC2Snapshot

总结

PowerShell 允許您管理 EBS 快照的各個方面。如果我們在這裡介紹的情境不符合您的需求,我建議您運行 Get-Command -Noun *ec2snapshot* -Module AWSPowerShell 查看所有可用的 EC2 快照命令。這將讓您對 PowerShell 和 EC2(EBS)快照的功能有一個良好的了解。

Source:
https://adamtheautomator.com/ec2-snapshot/