Finding all Amazon AWS Instances That Do Not Have a Certain Tag

前端 未结 9 2018
借酒劲吻你
借酒劲吻你 2020-12-23 12:09

I\'m trying to use the Amazon AWS Command Line Tools to find all instances that do not have a specified tag.

Finding all instances WITH a tag is simple enough, e.g.<

相关标签:
9条回答
  • 2020-12-23 12:17

    You can do that with jmespath (the engine that drives the --query parameter) despite what others say:

    aws ec2 describe-instances \
      --query 'Reservations[].Instances[?!not_null(Tags[?Key == `Name`].Value)] | []'
    

    Source: Using Amazon Web Services Command Line Interface (AWS CLI) to Find Instances without a 'Name' Tag.

    0 讨论(0)
  • 2020-12-23 12:23

    Unfortunately the underlying api call DescribeSnapshots does not support inverse tag filtering, and so neither does the CLI. You can, however, do client side filtering with the --query parameter which performs a JMESPath search. This will prevent you from having to use pipes as with user2616321's answer.

    For example:

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

    Add .InstanceId to the end of that to just get the instance ids.

    0 讨论(0)
  • 2020-12-23 12:26

    AFAIK directly through the CLI you won't be able to do that.

    By the syntax you are using, I can guess you are using the old cli. I suggest you to download the new CLI http://aws.amazon.com/cli/ and call

    aws ec2 describe-instances --output json

    from python, ruby or any scripting language you may like to parse the json output filtering using the proper regular expression according to your needs

    0 讨论(0)
  • 2020-12-23 12:28

    I use this python3 / boto script for very large inverse tag filtering operations:

    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)
    
    0 讨论(0)
  • 2020-12-23 12:32

    You could always do this: ec2-describe-instances | grep -v "Name" :p

    0 讨论(0)
  • 2020-12-23 12:33

    This will do what you're asking - find every instance which doesn't contain a tag named "YOUR_KEY_NAME_HERE" (2nd line filters for instances without tags named "Name"):

    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)' 
    

    If you wanted to filter against the value of the tag, instead of the name of the tag, this query lists all instances which don't contain a tag named YOUR_KEY_NAME_HERE whose value is EXCLUDE_ME. (2nd line lists instances which aren't named "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)'
    

    Felipe is correct. Parsing the output is the only way to go, since the AWS API does not provide this feature, nor do either of the official AWS CLIs. JSON output is very parseable, especially when compared to the multi-line text records which the old CLI prints by default.

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

    The API itself returns JSON, and the new awscli prints that JSON as its default output format. The "jq" program is very useful to parse it, and will even colorize when sent to a terminal, or you can --output text to reduce it back to strings.

    0 讨论(0)
提交回复
热议问题