使用 PowerShell 自动化 AWS EC2 快照

Amazon Elastic Block Store(EBS)是为Amazon EC2实例提供存储的服务。EBS是您的每个EC2实例上运行的每个卷的基础。当您依赖于一个服务来运行重要的基础设施时,确保数据已备份是明智的。在本博客文章中,了解如何使用PowerShell脚本语言管理和自动化EC2快照。

每个附加到EC2实例的EBS卷都可以通过EBS快照进行备份。每个快照可以通过两种方式之一创建;完整或增量快照。嗯,从技术上讲,两者都可以,但是…就跟我一起做吧。

当为EC2实例创建第一个快照备份时,它会创建整个卷的备份。当创建后续快照时,只保存自上一个快照以来已更改的块级存储级别的数据。但是,与典型的增量时间点备份不同,由于快照可以链接,当恢复快照时,所有该卷的数据都将被恢复,这使其类似于完整备份。

快照可以异步发生,这意味着快照可以同时处于创建过程中。启动时,快照进入待处理阶段,直到将所有必要的块复制到Amazon S3,其中存储了所有EBS快照。

使用PowerShell创建AWS EC2快照

有几种不同的方式可以使用AWS来管理EBS快照。您可以使用AWS管理控制台、AWS CLI、PowerShell或直接使用API。在本文中,我们将使用PowerShell,因为AWSPowerShell模块对使用PowerShell命令管理EBS快照提供了很好的支持。

先决条件

在我们深入讨论之前,我将假设您有一些前提条件,以便从本教程中获得最大的收益。您将需要:

  • 一个AWS账户
  • 带有附加卷的EC2实例
  • 通过根用户或具有CreateSnapshot权限的IAM用户进行身份验证(arn:aws:ec2:region::snapshot/*)

一旦您准备好了所有这些先决条件,我们就可以开始了!

查找现有的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-EC2ImageBlockDeviceMapping 参数。

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/