Windows Server で EBS ボリューム ID とデバイス名とドライブレターの関連を確認したい
日々 Windows Server を触ることが増えてきました、那須です。
小さなことなんですが、わからなくて困ってて調べてたら AWS ドキュメントでまんま答えが見つかったので、忘れないように記事に書いておきます。
困っていたこと
ある Windows Server でディスクが 4 つついていて、そのうち 3 つが同じサイズでした。特定のボリュームだけスナップショットをとりたいけど、AWS コンソール上ではどのボリュームがその対象なのか判別できなくて困ってました。
文章だと難しいですね。OS 画面でいうとこんなディスク状況です。ディスク作成時にタグつけ忘れたらもうわかりません。
ドライブレターとサイズはわかりますが、AWS のボリューム ID はわかりません。
一方、AWS コンソール上ではデバイス名とボリューム ID とサイズはわかりますが、ドライブレターが見えません。
この状況で、例えば E ドライブだけスナップショットをとりたい場合、どのボリュームに対してスナップショットを作成すればいいか判別できるでしょうか?
見つけた AWS ドキュメント
まんま答えが書いてありました。
docs.aws.amazon.com
以下、スクリプトのコピペです。
function Get-EC2InstanceMetadata { param([string]$Path) (Invoke-WebRequest -Uri "http://169.254.169.254/latest/$Path").Content } function Convert-SCSITargetIdToDeviceName { param([int]$SCSITargetId) If ($SCSITargetId -eq 0) { return "/dev/sda1" } $deviceName = "xvd" If ($SCSITargetId -gt 25) { $deviceName += [char](0x60 + [int]($SCSITargetId / 26)) } $deviceName += [char](0x61 + $SCSITargetId % 26) return $deviceName } Try { $InstanceId = Get-EC2InstanceMetadata "meta-data/instance-id" $AZ = Get-EC2InstanceMetadata "meta-data/placement/availability-zone" $Region = $AZ.Remove($AZ.Length - 1) $BlockDeviceMappings = (Get-EC2Instance -Region $Region -Instance $InstanceId).Instances.BlockDeviceMappings $VirtualDeviceMap = @{} (Get-EC2InstanceMetadata "meta-data/block-device-mapping").Split("`n") | ForEach-Object { $VirtualDevice = $_ $BlockDeviceName = Get-EC2InstanceMetadata "meta-data/block-device-mapping/$VirtualDevice" $VirtualDeviceMap[$BlockDeviceName] = $VirtualDevice $VirtualDeviceMap[$VirtualDevice] = $BlockDeviceName } } Catch { Write-Host "Could not access the AWS API, therefore, VolumeId is not available. Verify that you provided your access keys." -ForegroundColor Yellow } Get-WmiObject -Class Win32_DiskDrive | ForEach-Object { $DiskDrive = $_ $Volumes = Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='$($DiskDrive.DeviceID)'} WHERE AssocClass=Win32_DiskDriveToDiskPartition" | ForEach-Object { $DiskPartition = $_ Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='$($DiskPartition.DeviceID)'} WHERE AssocClass=Win32_LogicalDiskToPartition" } If ($DiskDrive.PNPDeviceID -like "*PROD_PVDISK*") { $BlockDeviceName = Convert-SCSITargetIdToDeviceName($DiskDrive.SCSITargetId) $BlockDevice = $BlockDeviceMappings | Where-Object { $_.DeviceName -eq $BlockDeviceName } $VirtualDevice = If ($VirtualDeviceMap.ContainsKey($BlockDeviceName)) { $VirtualDeviceMap[$BlockDeviceName] } Else { $null } } ElseIf ($DiskDrive.PNPDeviceID -like "*PROD_AMAZON_EC2_NVME*") { $BlockDeviceName = Get-EC2InstanceMetadata "meta-data/block-device-mapping/ephemeral$($DiskDrive.SCSIPort - 2)" $BlockDevice = $null $VirtualDevice = If ($VirtualDeviceMap.ContainsKey($BlockDeviceName)) { $VirtualDeviceMap[$BlockDeviceName] } Else { $null } } Else { $BlockDeviceName = $null $BlockDevice = $null $VirtualDevice = $null } New-Object PSObject -Property @{ Disk = $DiskDrive.Index; Partitions = $DiskDrive.Partitions; DriveLetter = If ($Volumes -eq $null) { "N/A" } Else { $Volumes.DeviceID }; EbsVolumeId = If ($BlockDevice -eq $null) { "N/A" } Else { $BlockDevice.Ebs.VolumeId }; Device = If ($BlockDeviceName -eq $null) { "N/A" } Else { $BlockDeviceName }; VirtualDevice = If ($VirtualDevice -eq $null) { "N/A" } Else { $VirtualDevice }; VolumeName = If ($Volumes -eq $null) { "N/A" } Else { $Volumes.VolumeName }; } } | Sort-Object Disk | Format-Table -AutoSize -Property Disk, Partitions, DriveLetter, EbsVolumeId, Device, VirtualDevice, VolumeName
t2.medium の Windows Server 2016 でテスト
AWS ドキュメントにある PowerShell スクリプトを使って、対象の Windows Server 上で ps1 ファイルを作成して実行しましょう。
PS C:\Users\Administrator\Desktop> .\vol-check.ps1 Disk Partitions DriveLetter EbsVolumeId Device VirtualDevice VolumeName ---- ---------- ----------- ----------- ------ ------------- ---------- 0 1 C: vol-08daa03b6f1d83506 /dev/sda1 root 1 1 D: vol-0508d109e7ecc0d38 xvdb ebs2 programs 2 1 E: vol-0180d15334525ff2d xvdc ebs3 Data 3 1 F: vol-045116d3e27beddeb xvdd ebs4 Logs
この通りあっさりでました。ドライブレター、ボリューム ID、デバイス名の関連が出てきましたね。 ちなみに、今回は下記の AMI から起動したインスタンスでテストしましたが、特に問題なく上記と同様の結果が出てきました。
- Windows_Server-2016-English-Full-Base-2018.07.11 (ami-49096ba4)
- Windows_Server-2016-Japanese-Full-Base-2018.03.24 (ami-07f2a061)
- Windows_Server-2012-R2_RTM-English-64Bit-Base-2018.07.11 (ami-a73c5e4a)
- Windows_Server-2012-R2_RTM-Japanese-64Bit-Base-2018.07.11 (ami-011270ec)
これでいつでも確認できますね
最初に EBS ボリュームにタグつけててもなんとなくあってるのかどうか不安になるのが人間です。 いつでもこの情報が見れるのは嬉しいですね。
Systems Manager で同じことやってみました
Systems Manager でスナップショット作成のついでにタグもつける
Systems Manager の便利さにやっと気がつきました、那須です。
Systems Manager ほんとにいいですね。今まで頑張って Lambda で作ってたものがコード書かずにできるのが嬉しいです。 例えばバックアップとか。AMI 作成とかスナップショット作成とかをよしなにやってくれます。
完璧ではなかった
一例ですが、Systems Manager Automation のドキュメントに AWS-CreateSnapshot というドキュメントがあります。 名前の通りで、EBS の ボリューム ID を指定すれば EBS スナップショットを取ってくれます。 ただこのドキュメント、実行すると確かに EBS スナップショットは作成してくれるんですが残念なんですよね…
スナップショット作成する対象のボリュームはこれなんですが
実際に AWS-CreateSnapshot Automation を実行してみると…
タグ全くついてないやん!!
でも安心してください! Systems Manager ドキュメントは JSON か YAML で書かれているんです。ということは、自分で調整しちゃえばいいんですよ! Lambda みたいにがっつりコードを書くことなく、シンプルに運用自動タスクを実装できます(シンプルにできるかどうかは内容によります
AWS-CreateSnapshot でやってること
コンテンツを見てみると、大きく以下の流れになっています。
- CloudFormation スタックを作成する(中身は IAM ロール作成と Lambda 関数作成)
- Lambda 関数実行
- 確認して OK なら CloudFormation スタック削除
AWS で始まるドキュメントは編集できないのでドキュメント新規作成
ドキュメントを作成します。
ドキュメント名はただの名前なので好きにしてください。
コンテンツのところは、AWS-CreateSnapshot のコンテンツ内容をそのままコピペしてください。
まだ「ドキュメントの作成」ボタンは押しません。
コンテンツで変更するポイント(IAM ロール)
まずタグ付けするにも権限が必要です。一時的な IAM ロールを作成するところ(ec2: で検索するとすぐでてきます)で、下記の 3 つのアクションを追加します。
'ec2:DescribeTags', 'ec2:CreateTags', 'ec2:DescribeVolumes'
コンテンツで変更するポイント(Lambda 関数)
以下のスナップショットを作成するところで、
\\tsnapshot = volume.create_snapshot(Description=description)\\n\\n
こんな風にタグ付けする行を追加します。
\\tsnapshot = volume.create_snapshot(Description=description)\\n\\tsnapshot.create_tags(Tags=volume.tags)\\n
これだけです。必要に応じて try/catch 等の処理は入れてくださいね。 これでドキュメントの作成ボタンを押して完了です。
実行してみよう
こんな感じでステータスが成功になれば OK です!
スナップショットのコンソールでも確認してみましょう。作成された EBS スナップショットのタグを見ると…
ばっちりですね。
公開されているドキュメントを参考に自分好みのドキュメントを作ろう
いろんなドキュメントを見ていただければわかると思いますが、できることとできないことがなんとなく見えてきて、ここをこうすればたぶんできるな、みたいな感覚がつかめると思います。 環境によってやりたいことも異なると思うので、公開されているドキュメントを少しだけ変更して、自分の環境に適した Automation ドキュメントを作成して運用を少しでも楽にできるようにしていきましょう!