Filter AWS EC2 Instances by Date Range Using AWS CLI: A Technical Guide


2 views

When working with AWS EC2 instances, filtering by launch time is a common requirement for system administrators and developers. The AWS CLI provides basic date filtering capabilities, but many users need more flexible time-based queries similar to Unix's find command functionality.

The native AWS CLI filters for EC2 instances only support exact or wildcard-based date matching:

aws ec2 describe-instances --filters "Name=launch-time,Values=2015-03*"

This approach has several limitations:

  • No direct support for relative date ranges (e.g., "last 30 days")
  • No built-in comparison operators (before/after specific dates)
  • Wildcards only work with specific date formats

Here's a practical solution using AWS CLI with jq for date range filtering:

Method 1: Filtering by Relative Days

# Get instances launched in the last 30 days
aws ec2 describe-instances | \
jq -r '.Reservations[].Instances[] | select(.LaunchTime >= "'$(date -d '-30 days' +%Y-%m-%d)'")'

Method 2: Exact Date Range Filtering

# Get instances launched between two specific dates
aws ec2 describe-instances | \
jq -r '.Reservations[].Instances[] | select(.LaunchTime >= "2023-01-01" and .LaunchTime <= "2023-03-31")'

For more complex scenarios, combine AWS CLI with shell scripting:

#!/bin/bash

START_DATE="2023-06-01"
END_DATE="2023-06-30"

aws ec2 describe-instances --query 'Reservations[].Instances[?LaunchTime>='"$START_DATE"' && LaunchTime<='"$END_DATE"'].[InstanceId,LaunchTime]' \
--output text | sort -k2

When working with large instance sets:

  • Filter at the API level when possible using --query
  • Process results locally for more complex date logic
  • Consider using --region flag to limit scope

For programmatic access, AWS SDKs offer more flexible date filtering:

# Python example using boto3
import boto3
from datetime import datetime, timedelta

ec2 = boto3.client('ec2')
thirty_days_ago = (datetime.now() - timedelta(days=30)).isoformat()

response = ec2.describe_instances(Filters=[
    {
        'Name': 'launch-time',
        'Values': [thirty_days_ago + '*']
    }
])

When working with AWS EC2 instances, filtering by precise date ranges is a common requirement for operations like cost analysis, maintenance tracking, or security audits. The native aws ec2 describe-instances command provides limited date filtering capabilities through the --filters parameter.

# Current limitation - only supports wildcard matching
aws ec2 describe-instances --filters "Name=launch-time,Values=2015-03*"

1. Using AWS CLI with JQ for Date Processing

The most robust approach combines AWS CLI with jq for JSON processing and date comparison logic:

# Get instances launched in last 30 days
aws ec2 describe-instances | \
jq -r '.Reservations[].Instances[] | 
select(.LaunchTime >= "'$(date -u -v-30d +"%Y-%m-%dT%H:%M:%SZ")'")'

2. Shell Script Solution for Date Range Filtering

For more complex date ranges, create a shell script with precise time calculations:

#!/bin/bash

START_DATE=$(date -u -d "30 days ago" +"%Y-%m-%dT%H:%M:%SZ")
END_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

aws ec2 describe-instances --query \
'Reservations[].Instances[?LaunchTime>='"$START_DATE"' && \
LaunchTime<='"$END_DATE"'].{ID:InstanceId,Type:InstanceType,LaunchTime:LaunchTime}'

3. AWS CLI JMESPath Query Alternative

For simpler installations without jq, use AWS CLI's built-in JMESPath query:

# Find instances launched between two specific dates
aws ec2 describe-instances \
--query 'Reservations[].Instances[?
  LaunchTime >= 2023-01-01 && 
  LaunchTime <= 2023-03-31].{
    InstanceId: InstanceId,
    LaunchTime: LaunchTime
  }'

AWS timestamps always use UTC (Zulu time). For accurate comparisons:

# Convert local time to UTC for comparison
TZ_OFFSET="-0400" # EDT offset
START_UTC=$(date -u -d "2023-07-01T00:00:00${TZ_OFFSET}" +"%Y-%m-%dT%H:%M:%SZ")

For accounts with many instances, add instance-state filters to reduce payload size:

aws ec2 describe-instances \
--filters Name=instance-state-name,Values=running \
--query "Reservations[].Instances[?LaunchTime >= \2023-01-01\]" 

For historical data beyond 60 days, use CloudWatch metrics with specific time ranges:

aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--start-time 2023-01-01T00:00:00Z \
--end-time 2023-03-31T23:59:59Z \
--period 3600 \
--statistics Average