Tag the AWS EBS volume with disk drive letter or label

How to run `make` command from another directory
March 26, 2018
How to add task in cron
March 26, 2018

Tag the AWS EBS volume with disk drive letter or label

You have several EC2 instances & all with several drives. It becomes unclear to identify which drive is mapped to which EBS volume. This causes difficulties to operational teams when using the AWS console or any other way to take a snapshot or to perform other tasks on a particular drive.

We faced the similar issues when using MS SQL on Windows EC2 instances which were needed at least three separate drives.

When searched on the internet I did not found the exact way to do it but found this script in MSSQLTips(here) which does part of the job. Thanks for the helpful post.

So here is the PowerShell script that tags the EBS volumes of that particular EC2 instance. This should script should be run in userdata script or once the EC2 is booted.

Important is that it must be called within the same ec2 instance and the EC2 instance must have proper IAM role to run it successfully.

Sample IAM policy for EC2:

{
       "Version" : "2012-10-17",
            "Statement" :
      [
           {
                 "Effect" : "Allow",
                 "Action" : "ec2: Describe*",

"Action" : "ec2:CreateTags*"
                 "Resource" : "*"
            }
       ]
 }

PowerShell script:

(Tested on Windows 2016 with PowerShell version 5.1)

Start-Transcript -Path C:\Tag-EBS-Volumes.log -Append

# Create a hash table that maps each device to a SCSI target
 $Map = @{"0" = '/dev/sda1'}
 for($x = 1; $x -le 25; $x++) {$Map.add($x.ToString(), [String]::Format("/dev/xvd{0}",[char](97 + $x)))}
 for($x = 78; $x -le 102; $x++) {$Map.add($x.ToString(), [String]::Format("/dev/xvdc{0}",[char](19 + $x)))}

Try {
 # Use the metadata service to discover which instance the script is running on
 $InstanceId = (Invoke-WebRequest '169.254.169.254/latest/meta-data/instance-id').Content
 $AvailabilityZone = (Invoke-WebRequest '169.254.169.254/latest/meta-data/placement/availability-zone').Content
 $Region = $AvailabilityZone.Substring(0, $AvailabilityZone.Length -1)

# Get the list of volumes attached to this instance
 $BlockDeviceMappings = (Get-EC2Instance -Region $Region -Instance $InstanceId).Instances.BlockDeviceMappings
 }
 Catch
 {
 Write-Host "Could not access the AWS API, are your credentials loaded?" -ForegroundColor Yellow
 }

Get-WmiObject -Class Win32_DiskDrive | %{
 $Drive = $_
 # Find the partitions for this drive
 Get-WmiObject -Class Win32_DiskDriveToDiskPartition | Where-Object {$_.Antecedent -eq $Drive.Path.Path} | %{
 $D2P = $_
 # Get details about each partition
 $Partition = Get-WmiObject -Class Win32_DiskPartition | Where-Object {$_.Path.Path -eq $D2P.Dependent}
 # Find the drive that this partition is linked to
 $Disk = Get-WmiObject -Class Win32_LogicalDiskToPartition | Where-Object {$_.Antecedent -in $D2P.Dependent} | %{
 $L2P = $_
 # Get the drive letter for this partition, if there is one
 Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.Path.Path -in $L2P.Dependent}
 }

$BlockDeviceMapping = $BlockDeviceMappings | Where-Object { $_.DeviceName -eq $Map[$Drive.SCSITargetId.ToString()] }

If( $Disk.VolumeName -eq "") {
 $tagvalue= "$env:COMPUTERNAME-Root"
 } ElseIf ($Disk.VolumeName -eq "ABC" )
 {
 $tagvalue= "$env:COMPUTERNAME-ABC"
 }ElseIf ($Disk.VolumeName -eq "DEF" )
 {
 $tagvalue= "$env:COMPUTERNAME-DEF"
 }Else
 {
 $tagvalue= ""
 }

New-EC2Tag -Resources $BlockDeviceMapping.Ebs.VolumeId -Tags @{ Key = "Name"; Value = $tagvalue } # Add volume name tag that matches VolumeId
 }
 }
Stop-Transcript


In the above script, you can alter the assignment for the actual tag as per your requirement

{               
     $tagvalue= "$env:COMPUTERNAME-DEF"
}
Bitnami