Old AMIs on your AWS Account

If you’re using Amazon Web Services (AWS), there’s a pretty reasonable chance that you’re also explicitly using an Amazon Machine Image (AMI) – the format that AWS uses to make a virtual machine image. And if you’ve been using AWS for more than a few months, you might have some resources that were built with an old AMI. Maybe it was current when you created the instance or launch configuration, but has been aging since then.

If you’re using an old AMI and you haven’t been patching it, or if you have been patching it but the release is no longer supported, your resources might be vulnerable to attack. Patch management is crucial to keeping a long-running server secure. Of course, just because an AMI is old doesn’t mean it hasn’t been patched. Amazon Linux and Ubuntu both have an option for a rolling release model that can keep an old AMI relatively secure. If you’ve invested a lot into devops, you might also have a continuous deployment pipeline that rebuilds phoenix servers on a regular basis, which might include updating the AMI.

You might also be using AMIs, but not explicitly. You might be implicitly using AMIs through Fargate or Lambda, for instance. Getting out of the business of configuring and patching server instances is part of the value proposition of the ‘serverless’ model. There are still servers and patches, but you, the AWS user, don’t need to care about them.

But if you’re using AMIs and you’re not sure that you’ve been keeping on top of the support timelines and the patch management, then it’s probably also a good idea to consider how old those AMIs might be.

Finding Old AMIs

If you are using AMIs, how can you find out if the AMIs you’re using are current? You can look at the AMI metadata:

So, if you gather a list of all the AMIs that you’re using, you can look at these two fields to get hints about which images need a closer examination. An image created a year or more ago, or marked as deprecated are both worth examining to see if they’re well-patched and well-supported.

A Simple Tool

If looking up all the AMIs in use on your account and checking the metadata sounds like a lot of work, then you’re in luck. After reading about the new DeprecationTime data point, I made a small JavaScript tool, oldamis (github, npm) that looks up AMIs and checks both of those data points for you. You can run it with npx if you have NPM installed:

❯ npx @codiform/oldamis
   ___    _       _        _      __  __   ___
  / _ \  | |   __| |      / \    |  \/  | |_ _|  ___
 | | | | | |  / _` |     / _ \   | |\/| |  | |  / __|
 | |_| | | | | (_| |    / ___ \  | |  | |  | |  \__ \
  \___/  |_|  \__,_|   /_/   \_\ |_|  |_| |___| |___/

ami ami-730ebd17 is old (created 2016-08-22T19:58:21.000-04:00), sources:
  - instance i-13e13eeb963a78ab9
ami ami-0cde1f5ee149df291 is ok, sources:
  - instance i-a3c31bb5ebbd4790d
  - instance i-11aff774c13d785ef
  - instance i-486d7a5e0171e6749
ami ami-0f1c5116668d961c3 is ok, sources:
  - instance i-8f434ca2c2c36dfb5
  - instance i-4b344522536719e4f
  - launch config demo-launch-config-2340234

This isn’t a sophisticated tool – it’s a proof of concept. Organizations that want to monitor this sort of thing should probably be looking at monitoring or policy-as-code tools that can be configured to look at this and many, many other things that could go wrong with your AWS account. That said, if you’re not sure how old the AMIs you’re using are right now, and this tool makes your life easier, I’m happy to hear it.

Just to be clear, oldamis doesn’t record information about your account, intercept data, or use your credentials in sneaky ways. The tool respects your privacy and its open-source, so you’re welcome to dig into the code before running it, just to make sure.

How it’s made

I made oldamis with the AWS JavaScript SDK v3. I’ve done a bunch of AWS automation using Python and Boto3 and wanted to try a different language and SDK for a change, and refresh my knowledge of publishing an NPM module. There were a few hiccups, but all in all it worked well, and there’s a good library for mocking API calls, which I’ve found to be somewhat important when you’re writing a tool that is a thin layer over AWS API calls.

As an example, once oldamis has figured out which AMIs you might be using, it uses the DescribeImages api call to get the DeprecationTime and CreationDate:

const getAmiDates = async (amis) => {
    const command = new DescribeImagesCommand({
        "ImageIds": amis,
        "IncludeDeprecated": true
    });
    const response = await ec2Client.send(command);
    return response.Images.reduce((o, img) => {
        const {ImageId, DeprecationTime, CreationDate} = img;
        o[ImageId] = {DeprecationTime, CreationDate};
        return o;
    }, {})
}

After getting the response it transforms the results into a smaller data structure for consumption by the CLI that looks like this:

{
    "ami-730ebd17": {
        "CreationDate": "2016-08-22T19:58:21.000-04:00",
        "DeprecationTime": null
    }
}

There’s more to it, but if you want to see more code samples, then I invite you to check out the GitHub repository. Contributions and feedback are welcome.

The oldami tool uses chalk to colorize the output and figlet for the banner.