Tag AWS EC2 EBS volumes with the instance name tag

Tagging in AWS is an extraordinarily powerful way to manage your assets. You can use tags for everything from searches in the AWS Console to preparing billing reports. To maximize the usefulness of the tagging system, you need — surprise! — to tag the AWS resources. But that’s not always automatic, especially when you are creating an asset that creates additional items. For example, creating an EC2 instance in the console also creates EBS volumes to support that instance. However, there is no way in the console to give the EBS volumes that are created a tag that matches the instance.

Instead you have to go and find the volumes associated with the instance and tag them separately. This can be done in the Tag Editor. But I wanted a way to iterate through all the EBS volumes in an account and make sure they are named after the owning instance.

I’ve previously published PowerShell scripts that use the AWS PowerShell cmdlets to create nicely tagged snapshots of EBS volumes, one that creates AMIs by name tag and one that syncs up tags between your custom AMIs and its snapshots. One of the more popular posts on this blog is about using PowerShell hash tables with Amazon.EC2.Model.Filter. The script below is part of this growing suite of tagging scripts that makes use of Amazon.EC2.Model Filter with Get-Ec2Tag and New-EC2Tag.

It’s no secret I’m a big PowerShell fan, especially when PowerShell is combined with the AWS PowerShell cmdlets. The “everything is an object” nature of PowerShell just seems “right” when used with AWS. And in this script, I think you’ll see the power of the PowerShell pipeline in action as the Get-EC2Instance cmdlet passes everything I need to tag blank EBS volumes in the pipeline.

Two notes on this script:

  • If there’s a tag on an EBS volume, it is not replaced. Only blank tags are replaced with the value of the Name key on the instance’s tag
  • EBS volumes that are not attached to an instance are not processed.

I hope this helps you and, as always, I look forward to your comments and feedback.

<#
    .SYNOPSIS
        If an EBS volume attached to an instance has a blank Name tag, this script tags the name tag with the instance name
    
    .DESCRIPTION
        (c) 2017 Air11 Technology LLC
        
        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at
        
        http://www.apache.org/licenses/LICENSE-2.0
        
        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
    
    .NOTES
        ===========================================================================
        Created on:   2017-02-05 12:00 UTC
        Created by:     Alex Neihaus
        Organization:   Air11 Technology LLC
        Filename:       Tag-EC2-EBS-Volumes-With-Name-From-EC2-Instance.ps1
        ===========================================================================
#>
#>
Import-Module AWSPowerShell # Be sure to import AWS PowerShell cmdlets. If not using default credentials, add them after this import
#Set-AWSCredentials -ProfileName YOUR-STORED-PROFILE-HERE
#Set-DefaultAWSRegion -Region YOUR-REGION-HERE

(Get-EC2Instance).Instances | ` # Get EC2 instances and pass to pipeline
ForEach-Object -Process {
    # Get the name tag of the current instance ID; Amazon.EC2.Model.Tag is in the Instances object
    $instanceName = $_.Tags | Where-Object -Property Key -EQ "Name" | Select-Object -ExpandProperty Value
    $_.BlockDeviceMappings | ` # Pass all the current block device objects down the pipeline
    ForEach-Object -Process {
        $volumeid = $_.ebs.volumeid # Retrieve current volume id for this BDM in the current instance
        # Get the current volume's Name tag
        $volumeNameTag = Get-EC2Tag -Filter @(@{ name = 'tag:Name'; values = "*" }; @{ name = "resource-type"; values = "volume" }; @{ name = "resource-id"; values = $volumeid }) | Select-Object -ExpandProperty Value
        
        if (-not $volumeNameTag) # Replace the tag in the volume if it is blank
        {
            New-EC2Tag -Resources $volumeid -Tags @{ Key = "Name"; Value = $instanceName } # Add volume name tag that matches InstanceID
        }
    }
}

 


Posted

in

, , ,

by

Comments

4 responses to “Tag AWS EC2 EBS volumes with the instance name tag”

  1. dezren39 Avatar
    dezren39

    Thanks for this it was very useful to me! Ideally, I’d have all my stuff running from CloudFormation and auto-tagged, but we’ve still got a lot of manual setups to deal with.

    I’m sure there is a way to do this with the newer AWS Tools, or automatic rules that trigger on creation, but the module works well enough still for things like this.

    Below is my attempt to generalize your script for any tags, as I have 3-5 tags on each instance I wanted copied to the EBS volumes. Great success!
    https://gist.github.com/dezren39/83e8453be4777c260dee5a2c56127249

    Thank you again!

    1. Alex Neihaus Avatar
      Alex Neihaus

      I’m glad it was useful for you. And thanks for the credit in your GitHub version.

  2. Alex Neihaus Avatar
    Alex Neihaus

    You mean you’d like to tag volumes in an AWS EC2 instance at creation?

    Hmmm….I think you might want to investigate using AWS “user data” which differs depending on whether you are running Windows Server 2012 or Windows Server 2016. See https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html

  3. Rugbyball Avatar
    Rugbyball

    This is great, thank you.

    How would I alter this to add to a bootstrap Powershell script I have, would only need to alter the EBS volumes for the instance this would be running on, not all of the Instances in the account.

    Would also like to add an additional TAG called “cost-center” using a variable I can set in script so i can also factor the EBS costs into the costing report.

     

    Thanks Again.

Leave a Reply

Your email address will not be published. Required fields are marked *