PowerShell で AWS EC2 スナップショットを自動化する方法

Amazon Elastic Block Store (EBS)は、Amazon EC2インスタンスのストレージを提供するサービスです。EBSは、EC2インスタンス上のすべてのボリュームが実行される場所です。重要なインフラストラクチャを実行するためにサービスに依存する場合、データのバックアップを確実に行うことは賢明です。このブログポストでは、PowerShellスクリプト言語を使用してEC2スナップショットを管理および自動化する方法について学びます。

EC2インスタンスに接続された各EBSボリュームは、EBSスナップショットを介してバックアップできます。スナップショットは、完全または増分スナップショットのいずれかの方法で作成できます。実際には両方ですが、とりあえずこれに従ってください。

EC2インスタンスの最初のスナップショットバックアップが作成されると、ボリューム全体のバックアップが作成されます。その後のスナップショットの作成時には、前回のスナップショット以降に変更されたブロックレベルのデータのみが保存されます。ただし、通常のインクリメンタルなポイントインタイムバックアップとは異なり、スナップショットをチェーンすることができるため、スナップショットが復元されると、そのボリュームのすべてのデータが復元され、これは完全バックアップに類似しています。

スナップショットは非同期で発生するため、スナップショットは並列で作成されることがあります。開始されると、スナップショットは必要なすべてのブロックがAmazon S3にコピーされるまで保留状態に入ります。Amazon S3には、すべてのEBSスナップショットが保存されます。

PowerShellを使用してAWS EC2スナップショットを作成する

AWSはEBSスナップショットを管理するためにいくつかの方法を提供しています。AWS Management Console、AWS CLI、PowerShell、またはAPIを直接使用することができます。この記事では、PowerShellを使用します。なぜなら、AWSPowerShellモジュールはPowerShellコマンドでEBSスナップショットを管理するための優れたサポートがあるからです。

前提条件

進める前に、このチュートリアルを最大限に活用するために前提条件としていくつかのものがあると想定しています。以下が必要です:

  • AWSアカウント
  • 添付されたボリュームを持つEC2インスタンス
  • ルートユーザーまたはCreateSnapshot権限(arn:aws:ec2:region::snapshot/*)を持つIAMユーザーで認証されていること

これらの前提条件を整えたら、準備ができました!

既存のEC2スナップショットの検索

最初のタスクの1つは、既に存在するスナップショットがあるかどうかを確認することです。それを確認するために、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がアタッチされているボリュームのみにします。

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 を実行し、Statecompleted になっていることを確認します。

タグの割り当て

多くのスナップショットを管理する場合、それらをすべて区別するのは難しいかもしれません。スナップショットをソートして各発見のためにカテゴリ別にするには、タグを割り当てることもできます。タグはEC2の普遍的な一部であり、EBSスナップショットに対して使用することができます。

タグをスナップショットの作成時に割り当てるか、後で割り当てることができます。スナップショット作成時にタグを割り当てるには、New-EC2SnapshotTagSpecification パラメータを使用します。

例えば、私はちょうど本番環境の変更を行う前に取得したAWS EC2スナップショットにタグを付けたいと思っています。 Stageという名前のタグを作成し、それをDevに割り当てたいと考えています。これを行うために、TagSpecificationオブジェクトを作成し、Tagsプロパティに1つ以上のTagオブジェクトを割り当て、このタグがアタッチされるリソースのタイプを定義します。

$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を作成する

スナップショットの便利な機能のもう1つは、スナップショットから新しいイメージ(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を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/