如何按Hostrecord或Logical ID升序排序AWS EC2实例ID输出?
Got it, let's fix that sorting issue for your EC2 instance IDs. Depending on whether you want to sort by the CloudFormation Logical ID or the Route53 Hostrecord, here are tailored solutions:
This is the easiest approach, since AWS automatically tags EC2 instances with their CloudFormation Logical ID via the aws:cloudformation:logical-id tag. We can use the CLI's built-in sort_by function directly in the --query parameter:
aws ec2 describe-instances \ --query "Reservations[*].Instances[*].{InstanceId:InstanceId, LogicalID:Tags[?Key=='aws:cloudformation:logical-id'].Value | [0]} | sort_by(@, &LogicalID) | [*].InstanceId" \ --filters "Name=tag-key,Values=aws:cloudformation:stack-name" "Name=tag-value,Values=Stack-Name-XYZ" \ --output json
Breakdown of how this works:
- First, we extract each instance's
InstanceIdand its corresponding CloudFormation Logical ID (filtered from the instance tags) sort_by(@, &LogicalID)sorts the list of instances alphabetically by their Logical ID in ascending order- The final
[*].InstanceIdtrims the result down to just the sorted array of instance IDs
This has two scenarios, depending on whether your EC2 instances already have a Hostrecord tag matching their Route53 record name.
Case 1: Instances have a Hostrecord tag
If you've manually (or via CloudFormation) added a Hostrecord tag to your instances that matches the Route53 record set name, you can use a nearly identical approach to the Logical ID method:
aws ec2 describe-instances \ --query "Reservations[*].Instances[*].{InstanceId:InstanceId, Hostrecord:Tags[?Key=='Hostrecord'].Value | [0]} | sort_by(@, &Hostrecord) | [*].InstanceId" \ --filters "Name=tag-key,Values=aws:cloudformation:stack-name" "Name=tag-value,Values=Stack-Name-XYZ" \ --output json
Case 2: No Hostrecord tag (fetch directly from Route53)
If your instances don't have this tag, we'll need to fetch Route53 record sets, match them to EC2 instances via their IP addresses, then sort. We'll use jq to handle the JSON data association:
- First, get the EC2 instances from your target stack with their private IPs (swap
PrivateIpAddressforPublicIpAddressif you use public IPs in Route53):
ec2_instances=$(aws ec2 describe-instances \ --query "Reservations[*].Instances[*].{InstanceId:InstanceId, PrivateIpAddress:PrivateIpAddress}" \ --filters "Name=tag-key,Values=aws:cloudformation:stack-name" "Name=tag-value,Values=Stack-Name-XYZ" \ --output json)
- Next, fetch the A record sets from your Route53 hosted zone (replace
YOUR_HOSTED_ZONE_IDwith your actual zone ID):
route53_records=$(aws route53 list-resource-record-sets \ --hosted-zone-id YOUR_HOSTED_ZONE_ID \ --query "ResourceRecordSets[?Type=='A'].{Name:Name, Target:ResourceRecords[0].Value}" \ --output json)
- Finally, use
jqto match instances to their Route53 hostnames, sort, and output the instance IDs:
echo "$ec2_instances" | jq --argjson r53 "$route53_records" ' # Create a map of Route53 IP targets to hostnames ($r53 | map({Target: .Target, Hostrecord: .Name})) as $r53_map # Flatten the nested EC2 instance array | .[] | .[] # Match each instance to its Route53 hostname via IP | ($r53_map[] | select(.Target == .PrivateIpAddress).Hostrecord) as $hostrecord # Create a combined object for sorting | {InstanceId: .InstanceId, Hostrecord: $hostrecord} # Sort alphabetically by hostname | sort_by(.Hostrecord) # Extract just the sorted instance IDs | [].InstanceId '
Quick notes for this scenario:
- Ensure your AWS CLI user has permission to run
route53:ListResourceRecordSets - If multiple Route53 records point to the same IP, this script will pick the first match (adjust the
jqlogic if you need to handle duplicates differently)
内容的提问来源于stack exchange,提问作者ErikWe

