Adventures in AWS: Measuring Ephemeral Storage

In this series, I explore some of the everyday challenges facing an AWS developer/sysadmin. First up: how do you aggregate information about EC2 instance store volumes?

The Problem
Recently, I got an urgent request to estimate the total amount of ephemeral storage attached to hundreds of EC2 instances across several AWS accounts. At first I got that sinking feeling. I don’t have access to billing data. I definitely didn’t have time to remote into each box and look up metadata by hand; security constraints prevented me from using Powershell Remoting, and not all the EC2 instances I was interested in were Windows machines anyway. No, I needed an AWS API solution. But did such a solution exist?

The Background
AWS allows you to create an EC2 instance with something called “instance store volumes” attached. Instance store volumes are SSD drives that are physically attached to the hardware under the instance. The drives are ephemeral, meaning that their contents go away if you stop or terminate the instance (reboots are OK). According to AWS, these drives are great for “temporary storage of information that changes frequently”, like cached runtime data.

Instance store volumes may be handy in some cases–we use them a lot where I work–but they’re not always easy to manage. Unlike EBS volumes, which have a full suite of configurable attributes, instance store volumes can’t be viewed in the AWS console or through the CLI. If you want to know whether an instance has ephemeral storage attached, you have to look at metadata within the instance itself.

The Solution
AWS limits the amount of ephemeral storage you can have on each EC2 instance type. You can view the full list of instances/storage sizes here. Since we pretty much always choose the default (maximum) storage size for an instance, I figured I could get a pretty good estimate of my ephemeral storage footprint just by adding up the provisioned instances in my various accounts/regions and matching them with their various instance store limits.

I made the following dictionary of instance types and their GiB instance store limits by referencing the link above:

$instance_types=@{
    "c1.medium"=350
    "c1.xlarge"=1680
    "c3.large"=32
    "c3.xlarge"=80
    "c3.2xlarge"=160
    "c3.4xlarge"=320
    "c3.8xlarge"=640
    "i2.xlarge"=800
    "i2.2xlarge"=1600
    "i2.4xlarge"=3200
    "i2.8xlarge"=6400
    "m1.small"=160
    "m1.medium"=410
    "m1.large"=840
    "m1.xlarge"=1680
    "m2.xlarge"=420
    "m2.2xlarge"=850
    "m2.4xlarge"=1680
    "m3.medium"=4
    "m3.large"=32
    "m3.xlarge"=80
    "m3.2xlarge"=160
    "r3.large"=32
    "r3.xlarge"=80
    "r3.2xlarge"=160
    "r3.4xlarge"=320
    "r3.8xlarge"=640
    }

You’ll notice that certain instance classes, like the t2 series, aren’t in the list at all; that’s because they don’t support ephemeral storage.

After that, all I had to do was write a simple Powershell function to loop through each region in each AWS account and add up the storage. I limited the search to running instances, since ephemeral storage isn’t preserved/billed when an instance is stopped.

function Get-TotalInstanceStoreBytes
{
    $regions = @(
        "ap-northeast-1",
        "ap-southeast-1",
        "ap-southeast-2",
        "eu-central-1",
        "eu-west-1",
        "sa-east-1",
        "us-east-1",
        "us-west-1",
        "us-west-2"
    )
    $instance_types=@{
    "c1.medium"=350
    "c1.xlarge"=1680
    "c3.large"=32
    "c3.xlarge"=80
    "c3.2xlarge"=160
    "c3.4xlarge"=320
    "c3.8xlarge"=640
    "i2.xlarge"=800
    "i2.2xlarge"=1600
    "i2.4xlarge"=3200
    "i2.8xlarge"=6400
    "m1.small"=160
    "m1.medium"=410
    "m1.large"=840
    "m1.xlarge"=1680
    "m2.xlarge"=420
    "m2.2xlarge"=850
    "m2.4xlarge"=1680
    "m3.medium"=4
    "m3.large"=32
    "m3.xlarge"=80
    "m3.2xlarge"=160
    "r3.large"=32
    "r3.xlarge"=80
    "r3.2xlarge"=160
    "r3.4xlarge"=320
    "r3.8xlarge"=640
    }
    #stored credentials
    $accounts = @("account1","account2","account3","account4")
    
    $totaltib = 0
    foreach($account in $accounts)
    {
        $accountgib = 0
        foreach ($region in $regions)
        {
            $instances = (Get-EC2Instance -Region $region -ProfileName $account).Instances
            foreach($instance in $instances)
            {
                if($instance.State.Name -eq "running")
                {
                	#look up each instance's type in the table, then add the associated storage quantity to the running total
                    $type = $instance.InstanceType.Value
                    $accountgib += $instance_types.$type
                }
            }
        }
        $accounttib = [math]::round($accountgib/1024, 2)
        $totaltib += $accounttib
        Write-Host "Total TiB of Ephemeral Storage Provisioned in $account=$accounttib"
    }
    Write-Host "----------------------------------------------------"
    Write-Host "Total TiB of Ephemeral Storage Provisioned=$totaltib"
}

This approach took a few seconds to run due to the number of instances searched, but eventually produced output similar to the following:

Total TiB of Ephemeral Storage Provisioned in account1=x.xx
Total TiB of Ephemeral Storage Provisioned in account2=x.xx
Total TiB of Ephemeral Storage Provisioned in account3=x.xx
Total TiB of Ephemeral Storage Provisioned in account4=x.xx
----------------------------------------------------
Total TiB of Ephemeral Storage Provisioned=x.xx

That’s all there is to it! This script could easily be tweaked to provide information about ephemeral storage associated with a particular instance type, in addition to the account totals listed above. Let me know if it is helpful to you or if you have come up with a better way to gather stats about instance store volumes in a diverse AWS environment!

Adventures in AWS: Measuring Ephemeral Storage

One thought on “Adventures in AWS: Measuring Ephemeral Storage

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s