Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the most recently launched EC2 instance with AWS CLI?

I'm currently using the following CLI command to get the instance PublicIPAddress and LaunchTime for a given instance Name tag, 'myInstanceName':

aws ec2 describe-instances --filters 'Name=tag:Name,Values=myInstanceName' \ 
    --region us-east-1 \
    --query 'Reservations[*].Instances[*].{PublicIpAddress: PublicIpAddress, LaunchTime: LaunchTime}'

This results in the following:

[
    {
        "LaunchTime": "2019-01-25T11:49:06.000Z",
        "PublicIpAddress": "11.111.111.11"
    }
]

This is fine, but if there are two instances with the same name I will get two results in my result JSON. I need to find a way to get the most recent instance for a given name.

Solution Update

This question is quite specific to EC2 instances. The issue can be resolved using two different methods, answered below:
Parsing Result with jq
Using JMESPath

Please see this related question for more general sorting by date with JMESPath, and for further reading.

like image 966
x3nr0s Avatar asked Mar 21 '19 16:03

x3nr0s


2 Answers

Try using the jq utility. It's a command-line JSON parser. If you're not familiar with it then I'd recommend the jq playground for experimentation.

First flatten the awcli results, as follows:

aws ec2 describe-instances  \
    --query 'Reservations[].Instances[].{ip: PublicIpAddress, tm: LaunchTime}' \
    --filters 'Name=tag:Name,Values= myInstanceName'

Note that I've aliased LaunchTime to tm for brevity. That will result in (unsorted) output like this:

[
  {
    "ip": "54.4.5.6",
    "tm": "2019-01-04T19:54:11.000Z"
  },
  {
    "ip": "52.1.2.3",
    "tm": "2019-03-04T20:04:00.000Z"
  }
]

Next, pipe this result into jq and sort by descending tm (the alias for LaunchTime), as follows:

jq 'sort_by(.tm) | reverse'

That will result in output like this:

[
  {
    "ip": "52.1.2.3",
    "tm": "2019-03-04T20:04:00.000Z"
  },
  {
    "ip": "54.4.5.6",
    "tm": "2019-01-04T19:54:11.000Z"
  }
]

Finally, use jq to filter out all but the first result, as follows:

jq 'sort_by(.tm) | reverse | .[0]'

This will yield one result, the most recently launched instance:

{
  "ip": "52.1.2.3",
  "tm": "2019-03-04T20:04:00.000Z"
}

Putting it all together, the final command is:

aws ec2 describe-instances  \
    --query 'Reservations[].Instances[].{ip: PublicIpAddress, tm: LaunchTime}' \
    --filters 'Name=tag:Name,Values= myInstanceName' | \
    jq 'sort_by(.tm) | reverse | .[0]'
like image 91
jarmod Avatar answered Nov 15 '22 12:11

jarmod


Here's a method for finding the latest-launched instance, and displaying data about it:

aws ec2 describe-instances  --query 'sort_by(Reservations[].Instances[], &LaunchTime)[:-1].[InstanceId,PublicIpAddress,LaunchTime]'

sort_by(Reservations[].Instances[], &LaunchTime)[:-1] will return the last instance launched. The fields are then retrieved from those instances.

To understand this type of fun, see:

  • JMESPath Tutorial — JMESPath
  • JMESPath Examples — JMESPath
like image 37
John Rotenstein Avatar answered Nov 15 '22 10:11

John Rotenstein