EC2
AWS
Cloud Computing
Instance Management
Command Line Tools

How can I get list of only running instances when using ec2-describe-tags

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

ec2-describe-tags can filter tags by key, value, resource type, and resource ID, but it does not know whether an EC2 instance is running or stopped. Instance state belongs to the instance description API, not the tag API. So if you want "tags for running instances only," you need a two-step approach or, better yet, the modern AWS CLI command that returns both state and tags together.

Why ec2-describe-tags Cannot Do It Alone

The old EC2 API tools split instance metadata across multiple commands:

  • instance state comes from instance descriptions
  • tags come from the tag listing API

That means this requirement actually has two filters:

  1. find instances whose state is running
  2. show the tags for those instance IDs

With the legacy tools, ec2-describe-tags only handles the second part.

The Modern AWS CLI Way

If you are not forced to stay on the old EC2 API tools, the cleanest solution is to query describe-instances directly. That API already returns tags on each instance object, so you do not need a second command.

bash
1aws ec2 describe-instances \
2  --filters Name=instance-state-name,Values=running \
3  --query 'Reservations[].Instances[].{Id:InstanceId,Tags:Tags}' \
4  --output json

That command asks EC2 for instances in the running state and then projects each instance ID together with its tag list.

If you only want the Name tag:

bash
1aws ec2 describe-instances \
2  --filters Name=instance-state-name,Values=running \
3  --query 'Reservations[].Instances[].{Id:InstanceId,Name:Tags[?Key==`Name`]|[0].Value}' \
4  --output table

This is usually the best answer today because it keeps state and tags in one response and avoids extra shell plumbing.

A Legacy Two-Step Pattern

If you specifically must use ec2-describe-tags, first gather running instance IDs and then query tags for those IDs.

Using the current AWS CLI as the first step:

bash
1running_ids=$(aws ec2 describe-instances \
2  --filters Name=instance-state-name,Values=running \
3  --query 'Reservations[].Instances[].InstanceId' \
4  --output text)
5
6for id in $running_ids; do
7  ec2-describe-tags --filter "resource-id=$id"
8done

This works because the loop performs the join that ec2-describe-tags cannot perform by itself.

If you are fully on the legacy EC2 API tools, the exact state query syntax may differ by package version, but the idea stays the same:

  1. list running instance IDs
  2. pass those IDs into the tags command

Filter by State and Tag at the Same Time

A common real requirement is not just "running instances" but "running instances with a particular tag." In that case, modern AWS CLI filtering is even more useful.

bash
1aws ec2 describe-instances \
2  --filters \
3    Name=instance-state-name,Values=running \
4    Name=tag:Environment,Values=prod \
5  --query 'Reservations[].Instances[].{Id:InstanceId,PrivateIp:PrivateIpAddress}' \
6  --output table

This avoids a separate tag lookup completely.

Format the Output Safely

If you plan to feed the results into scripts, prefer structured output over ad hoc parsing.

bash
1aws ec2 describe-instances \
2  --filters Name=instance-state-name,Values=running \
3  --output json \
4| jq -r '.Reservations[].Instances[] | [.InstanceId, .State.Name] | @tsv' ``` Using JSON plus JMESPath or `jq` is much more reliable than scraping columns from human-readable output. ## When to Keep `ec2-describe-tags` There are still cases where `ec2-describe-tags` makes sense: - maintaining an older automation environment - working on a host where only the legacy EC2 tools are installed - troubleshooting a script you cannot migrate immediately Even then, it helps to treat the command as a tag lookup tool, not as the main source of truth for instance lifecycle state. ## Common Pitfalls One common mistake is assuming every running instance has the tag you want. Some instances may return no `Name` or no custom tag at all, so write your query to tolerate missing values. Another issue is forgetting the region. Instance IDs and tags are region-specific, so mixing defaults across shells or profiles can make it look as if tags disappeared. Developers also often overcomplicate the task by insisting on `ec2-describe-tags` for a problem that `aws ec2 describe-instances` already solves directly. If you can migrate, do it. Finally, avoid brittle text parsing. Output formats meant for humans change more easily than JSON structures. ## Summary - '`ec2-describe-tags` cannot filter instances by runtime state on its own.' - The modern solution is `aws ec2 describe-instances` with `instance-state-name=running`. - If you must use `ec2-describe-tags`, first collect running instance IDs and then query tags for those IDs. - Combine tag filters and state filters in one instance query whenever possible. - Prefer JSON output with JMESPath or `jq` for reliable automation.

Course illustration
Course illustration

All Rights Reserved.