EC2で構築したWindowsサーバにおいて。
下記画像のように同じ容量で複数のEBSが割り当たっている場合。
(画像はDドライブからHドライブがすべて8GB)
下記のようなマネジメントコンソール上の表示と見比べてみると、どのEBSボリュームがOS上ではどのディスクに割り当たっているのかぱっと見ではわかりません。
本記事ではこのような場合、OS上のディスクとEBSボリュームをマッピングする方法について説明します。
なお、後述しますがNitro世代のNVMeドライブとNitro以前では状況が異なるのでその点についても少しだけ触れます。
今回利用する環境
- Windows Server 2022(ami-0987eed561fe06332 Windows_Server-2022-English-Full-Base-2024.07.10)
- t3.micro
- ebsnvme-id.exe
- PowerSHell 5.1.20348.2582
ebsnvme-id.exeを利用してNVMeドライブのマッピングをおこなう。(t3.microでNVMe)
最近ではAWSが提供するWindowsイメージから構築していれば、すでに下記パスに配置済みかと思います。
C:\PROGRAMDATA\AMAZON\Tools
こちらを利用すると簡単にディスクとEBSボリュームのマッピングを行えます。
(Windows Server 2008以降 かつ NVMeのみ対応)
画像ではC:\ProgramData\Amazon\tools\ebsnvme-id.exe
を実行するとOS上のDisk Numberとそれに対応するとVolume IDとDevice Nameが表示されます。
Disk Numberからドライブレターを確認するにはディスクの管理から確認するか
(画像ではDisk Number 4がFドライブである事を確認している)
PowerShellコマンドでドライブレターまで取得してみる
下記のようなワンライナーで一括して出力する事ができます。
Get-Partition | Where-Object DriveLetter | Select-Object DiskNumber , DriveLetter, @{name='Volume ID';expression={ C:\ProgramData\Amazon\tools\ebsnvme-id.exe $_.DiskNumber | Select-String "Volume ID"}},@{name='Device Name';expression={ C:\ProgramData\Amazon\tools\ebsnvme-id.exe $_.DiskNumber | Select-String "Device Name"}}
だいぶ手抜きをしていて、ebsnvme-id.exe
の処理結果をそのまま出力しているのでVolume ID
とDevice Name
項目に入っている文字列がVolume ID: vol-003f21ceb8373f470
やDevice Name: xvdd
といった具合にPrefixに余計な文字列がついています。
PowerShellスクリプト(mappings.ps1)を利用してドライブのマッピングを行う。(t3.microでNVMe)
Windows インスタンスでのディスクとボリュームのマッピング
ebsnvme-id.exeを利用する方法以外に、上記ドキュメントにPowerShellスクリプト(mappings.ps1)の記載あるので、こちらを利用してディスクとEBSボリュームのマッピングを行えます。
(Windows Server 2012以降に対応)
なお後述しますが、スクリプト内部ではAWS Tools for Windows PowerShellを利用しているため、EC2の情報が取得できるようなIAMロールをEC2にアタッチするか、個別にAWS Tools for Windows PowerShellに認証情報をセットする必要があります。
EC2にアタッチするIAMロールの調整
今回はEC2にアタッチするロールとしてqiita-ec2-roleを作成してec2にアタッチしました。
qiita-ec2-roleの作成
EC2へアタッチ
mappings.ps1の作成
# List the disks for NVMe volumes
function Get-EC2InstanceMetadata {
param([string]$Path)
(Invoke-WebRequest -Uri "http://169.254.169.254/latest/$Path").Content
}
function GetEBSVolumeId {
param($Path)
$SerialNumber = (Get-Disk -Path $Path).SerialNumber
if($SerialNumber -clike 'vol*'){
$EbsVolumeId = $SerialNumber.Substring(0,20).Replace("vol","vol-")
}
else {
$EbsVolumeId = $SerialNumber.Substring(0,20).Replace("AWS","AWS-")
}
return $EbsVolumeId
}
function GetDeviceName{
param($EbsVolumeId)
if($EbsVolumeId -clike 'vol*'){
$Device = ((Get-EC2Volume -VolumeId $EbsVolumeId ).Attachment).Device
$VolumeName = ""
}
else {
$Device = "Ephemeral"
$VolumeName = "Temporary Storage"
}
Return $Device,$VolumeName
}
function GetDriveLetter{
param($Path)
$DiskNumber = (Get-Disk -Path $Path).Number
if($DiskNumber -eq 0){
$VirtualDevice = "root"
$DriveLetter = "C"
$PartitionNumber = (Get-Partition -DriveLetter C).PartitionNumber
}
else
{
$VirtualDevice = "N/A"
$DriveLetter = (Get-Partition -DiskNumber $DiskNumber).DriveLetter
if(!$DriveLetter)
{
$DriveLetter = ((Get-Partition -DiskId $Path).AccessPaths).Split(",")[0]
}
$PartitionNumber = (Get-Partition -DiskId $Path).PartitionNumber
}
return $DriveLetter,$VirtualDevice,$PartitionNumber
}
$Report = @()
foreach($Path in (Get-Disk).Path)
{
$Disk_ID = ( Get-Partition -DiskId $Path).DiskId
$Disk = ( Get-Disk -Path $Path).Number
$EbsVolumeId = GetEBSVolumeId($Path)
$Size =(Get-Disk -Path $Path).Size
$DriveLetter,$VirtualDevice, $Partition = (GetDriveLetter($Path))
$Device,$VolumeName = GetDeviceName($EbsVolumeId)
$Disk = New-Object PSObject -Property @{
Disk = $Disk
Partitions = $Partition
DriveLetter = $DriveLetter
EbsVolumeId = $EbsVolumeId
Device = $Device
VirtualDevice = $VirtualDevice
VolumeName= $VolumeName
}
$Report += $Disk
}
$Report | Sort-Object Disk | Format-Table -AutoSize -Property Disk, Partitions, DriveLetter, EbsVolumeId, Device, VirtualDevice, VolumeName
ドキュメントに記載しているスクリプトをmapping.ps1に保存してスクリプトを実行していきます。(そのまま貼り付けても動きますが)
実行ポリシーの調整とmappings.ps1の実行
実行ポリシーをRemoteSignedに変更して、保存したmappings.ps1を実行します
実行するとしばらく時間がかかりますが、下記のように結果が表示されます。
なお実行に時間がかかるのは、ちゃんと見てませんが内部的にAWS Tools for Windows PowerShell
を利用しており、この巨大なモジュールを読み込む部分で時間がかかってそうな気がします。
認証情報がないとエラーになる。
AWS Tools for Windows PowerShell
の認証情報がない状態で実行すると上記画像のようにエラーとなり、VirtualDeviceがN/A
で表示されます。
なお2024年7月現在、ドキュメントには上記画像のように記載されており。
認証情報がないと取得できないのはEbsVolumeID
と書かれていますが。
EbsVolumeIDが取得できて、Deviceが取得できてない気がします。
NVMe以前のインスタンスタイプで実行すると
紹介したAWSのドキュメントにも記載がありますが、今回紹介している手順はNVMeドライバを対象としています。
このためNVMeドライバを使わない、Nitro以前のインスタンスタイプ(t2.micro)で同様にebsnvme-id.exeとPowerShellスクリプトを実行するとどうなるか確認してみます。
Nitro以前のt2.microでebsnvme-id.exeを実行してみる
Nitro以前なt2などのインスタンスタイプで実行すると下記のようになります。
# メタデータ(IMDSv2)にアクセスしてインスタンスタイプ表示
$headers = @{ "X-aws-ec2-metadata-token-ttl-seconds" = 21600 }
$token = Invoke-RestMethod http://169.254.169.254/latest/api/token -Method Put -Headers $headers
$tokenHeader = @{ "X-aws-ec2-metadata-token" = $token }
irm http://169.254.169.254/latest/meta-data/instance-type -Headers $tokenHeader
# ebsnvme-id.exe実行
C:\ProgramData\Amazon\tools\ebsnvme-id.exe
画像のようにNo EBS NVMe disks found.
となり情報が取得できません。
Nitro以前のt2インスタンスだとNVMeではないので情報が取得できないようです。
Nitro以前のt2.microでmappings.ps1を実行してみる
ドキュメントにはNVMeを想定していると記載がありますが。
Nitro以前のインスタンスタイプでも正常に動作していそうです。(t2.microでしかためしてませんが下記画像のように動作しました)
総評
目視で確認できるように、EBSごとにボリュームサイズを微妙に変えたりする手法もありますが。
今回はドキュメントにある方法を確認してみました。
Nitro世代とそれ以前では少し違いが出てくるって所は気にしたい所かと思います。