查找没有特定标记的所有Amazon AWS实例

时间:2013-09-17 19:17:52

标签: command-line amazon-web-services filter

我正在尝试使用Amazon AWS命令行工具查找没有指定标记的所有实例。

使用标记查找所有实例非常简单,例如

ec2-describe-instances --filter "tag-key=Name"

但是我如何反转该过滤器以仅返回没有标记“Name”的实例?

8 个答案:

答案 0 :(得分:22)

这将按照您的要求进行操作 - 找到每个不包含名为“YOUR_KEY_NAME_HERE”的标记的实例(第二行过滤没有标记为“名称”的标记的实例):

aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "YOUR_KEY_NAME_HERE"} ]}) | not)' 
aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "Name"} ]}) | not)' 

如果要过滤标记的值而不是标记的名称,此查询将列出所有不包含名为YOUR_KEY_NAME_HERE的标记的实例,其值为EXCLUDE_ME。 (第二行列出了未命名为“testbox1”的实例。)

aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "YOUR_KEY_NAME_HERE"}, {Value: "EXCLUDE_ME"}]}) | not)'
aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "Name"}, {Value: "testbox1"}]}) | not)'
菲利普是对的。解析输出是唯一的方法,因为AWS API不提供此功能,也不提供任何官方AWS CLI。 JSON输出非常易于解析,尤其是与旧CLI默认打印的多行文本记录相比时。

http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html

API本身返回JSON,新的awscli将JSON打印为默认输出格式。 “jq”程序对于解析它非常有用,甚至在发送到终端时会着色,或者你可以 - 输出文本以将其缩减回字符串。

答案 1 :(得分:3)

由于--filters参数似乎不支持反向过滤,所以我使用--query参数解决了这个问题:

aws ec2 describe-instances \
--query 'Reservations[].Instances[?!contains(Tags[].Key, `Name`)][].InstanceId'

它查看每个实例的标记键数组,并过滤​​那些没有标记'名称'在数组中。然后将输出展平为实例ID数组。

  • 优于以前的一些答案:无需jq或其他命令来过滤输出。
  • 相对于真正的逆滤波器的缺点:在大量实例上可能要慢得多。

答案 2 :(得分:2)

不幸的是,潜在的api调用DescribeSnapshots不支持反向标记过滤,因此CLI也不支持。但是,您可以使用执行JMESPath搜索的--query参数进行客户端过滤。这将阻止您像user2616321一样使用管道。

例如:

aws ec2 describe-instances --query "Reservations[].Instances[?Tags[?Key == 'Name']][]"

.InstanceId添加到其末尾以获取实例ID。

答案 3 :(得分:1)

我遇到了同样的问题,我想出了如何查询Tag-Values 您很可能为所有实例定义了相同的标记键;我在所有实例上都定义了一个标记键“MachineName”,我希望按标记键名称的值进行过滤

下面是过滤Name = Machine1

的示例

使用选项

--filters "Name=tag-key,Values=MachineName" "Name=tag-values,Values=Machine1"

这对我来说很好用

答案 4 :(得分:0)

AFAIK直接通过CLI你将无法做到。

根据您使用的语法,我猜您正在使用旧的cli。我建议您下载新的CLI http://aws.amazon.com/cli/并致电

aws ec2 describe-instances --output json

来自python,ruby或任何脚本语言,您可能希望根据需要使用正确的正则表达式解析json输出过滤

答案 5 :(得分:0)

我也很惊讶这是通过CLI做的有多么困难。我喜欢user2616321的答案,但我在输出每个实例所需的确切字段时遇到了一些麻烦。在查询语法中花费了一段时间并且使用JMESPath失败后,我最终只是制作了一个小的ruby脚本来执行此操作。如果有人想节省几分钟写一个自己的,这里是:

#!/usr/bin/env ruby
require 'json'

# We'll output any instance that doesn't contain all of these tags
desired_tags = if ARGV.empty?
                 %w(Name)
               else
                 ARGV
               end

# Put the keys we want to output per instance/reservation here
reservation_keys = %w(OwnerId RequesterId)
instance_keys = %w(Tags InstanceId InstanceType PublicDnsName LaunchTime PrivateIpAddress KeyName) 
instances_without_tags = []

# Just use CLI here to avoid AWS dependencies
reservations = JSON.parse(
  `aws ec2 describe-instances`
)["Reservations"]

# A reservation is a single call to spin up instances. You could potentially
# have more than one instance in a reservation, but often only one is
# spun up at a time, meaning there is a single instance per reservation.
reservations.each do |reservation|
  reservation["Instances"].each do |instance|
    # Filter instances without the desired tags
    tag_keys = instance["Tags"].map { |t| t["Key"] }
    unless (tag_keys & desired_tags).length == desired_tags.length
      instances_without_tags << 
        reservation.select { |k| reservation_keys.include?(k) }.
          merge(instance.select { |k| instance_keys.include?(k) })
    end
  end
end

puts JSON.pretty_generate(instances_without_tags)

答案 6 :(得分:0)

我将这个python3 / boto脚本用于非常大的逆标记过滤操作:

import boto3
from botocore.config import Config

# Attempts
config = Config(
  retries = dict(
    max_attempts = 3
  )
)

# Tag(s)
my_tags = [
  {
    "Key": "backup",
    "Value": "true"
  }
]

# Owner ID Filter
owner_id = 'SOME_OWNER_ID'

# Connection
ec2 = boto3.client("ec2", config=config)

# Instances
def tag_instances():
  # All Reservations [instances] (tagged or untagged)
  all_reservations = ec2.describe_instances(Filters = [{'Name': 'owner-id', 'Values':[owner_id]}])

  # Append each InstanceId in all_reservations to all_instances
  all_instances = []
  for all_reservation in all_reservations['Reservations']:
    for all_instance in all_reservation['Instances']:
      all_instances.append(all_instance['InstanceId'])

  # Append each InstanceId with backup:true or backup:false to tagged_instances
  tagged_reservations = ec2.describe_instances(Filters = [{'Name': 'owner-id', 'Values':[owner_id]},{'Name': 'tag:backup', 'Values':['true','false']}])
  tagged_instances = []
  for tagged_reservation in tagged_reservations['Reservations']:
    for tagged_instance in tagged_reservation['Instances']:
      tagged_instances.append(tagged_instance['InstanceId'])

  # Append each InstanceId in all_instances and not in tagged_instances to untagged_instances
  untagged_instances = [all_instance for all_instance in all_instances if all_instance not in tagged_instances]

  # Print untagged InstanceId
  print("untagged_instanceids:",untagged_instances)

答案 7 :(得分:-5)

您可以随时执行此操作: ec2-describe-instances | grep -v "Name" :P