简体   繁体   中英

Python Boto3 - Unable to list Instances without tags

Here I'm writing a python program to list all the ec2 instances without the tag "Owner". Where I'm stuck right now is if the program encounters any Instance already having the "Owner" tag then it exits without checking further Instances. What I want is to skip those instances and continue to check other instances. Here is my Code:

    import boto3
    client = boto3.client('ec2',region_name='ap-south-1')
    a = client.describe_instances()
    count=0
    y="Owner"
    for i in a['Reservations']:
       for j in i['Instances']:
         for k in range(len(j['Tags'])):
            if y == j['Tags'][k]['Key']:
               count +=1
            else:
              continue
         if count==0:
           print "The following Instance does not have Owner Tag: "+j['InstanceId']

Here is how the json dict object would look like:

    {
     'Reservations': [{
      'Instances': [{
            .
            .
            .
            .
          'Tags':[
            {
             'Value': 'sample1',
             'Key': 'Name'
            }, 
            {
             'Value': 'user',
             'Key': 'Owner'
            }
        ]
    }
  }
}

I noticed a couple of things in your code that if you did them slightly different maybe it would be easier to control the program's flow. For starters, use more descriptive variable names, if you have a list of instances for example, a good name would simply be instances . Here is an example of how you could do this:

import boto3
client = boto3.client('ec2',region_name='ap-south-1')
data = client.describe_instances()
count=0

reservations = data["Reservations"]

for reservation in reservations:

    instances = reservation["Instances"]

    for instance in instances:

        tags = instance["Tags"]
        instanceId = instance['InstanceId']

        hasOwner = len([tag for tag in tags if tag["Key"] == "Owner"]) > 0

        print "The following Instance does not have Owner Tag: " + instanceId

Notice how I also added some spacing to increase readability.

Lastly, if you have a string, namely "Owner" , it would be silly to put thin into a variable called owner , since that would only be confusing if it were ever changed.

Your continue is causing a few problems.

Here's an alternate version:

import boto3

key_to_find = 'Owner'

client = boto3.client('ec2')

response = client.describe_instances()

for reservation in response['Reservations']:
  for instance in reservation['Instances']:
    if key_to_find not in [tag['Key'] for tag in instance['Tags']]:
      print (key_to_find + ' tag not found for Instance ' + instance['InstanceId'])

You are exiting the loop after finding the first tag that does not match. Get all the tag and then check. Try this:

for i in a['Reservations']:
  for j in i['Instances']: # For each instance
    keys = [tag['Key'].upper() for tag in j['Tags']] # Collect all tags
    if 'OWNER' not in keys: # Case insensitive check of Owner tag
      print "The following Instance does not have Owner Tag: "+j['InstanceId']

having just written almost exactly this there are few areas that were over looked here. In no particular order:

  1. The examples given will only cover one region.
  2. The examples will only find instance that are missing an owner tag, There is the case where the Tag exists, but the Value is empty
  3. In the case of newly launched instance, with no Tags added, the answer examples will error out.

Below answers the question, and covers the points above.

#Open an initial client to get a list of existing regions
client = boto3.client('ec2', region_name='us-east-1')

# Get a list of all existing regions
zones = client.describe_regions()

# Loop through all regions as anyone can launch in any region though we all 
# tend to work in us-east-1
for region in zones["Regions"]:
    #reset a dict used for tracking to make sure we don't carry data forward
    bt_missing = {}
    region_called = region["RegionName"]
    # open a new client as we move through each region
    ec2 = boto3.client('ec2', region_name=region_called)

    # Get a list of running instances in the region
    response = ec2.describe_instances()
    
    # Loop though all instances looking for instances with No tags, Missing Billing Owner tags,
    # or empty Billing Owner tags... adding the instance-id to a list 

    for resv in response["Reservations"]:
        for inst in resv["Instances"]:
            if "Tags" not in [x for x in inst]:
                print(f"The instance: {inst['InstanceId']} has no tags at all, if your's please update: {region_called}")
                continue
            if "Billing_Owner" not in [t['Key'] for t in inst["Tags"]]:
                bt_missing.update({inst["InstanceId"]: region_called})


    for resv in response["Reservations"]:
        for inst in resv["Instances"]:
            if "Tags" not in [x for x in inst]:
                continue
            for tag in inst["Tags"]:
                if tag['Key'] == "Billing_Owner" and not tag['Value']:
                    bt_missing.update({inst["InstanceId"]: region_called})

    # Take the list of all instance-ids in all regions that have blank, or missing
    # billing owner tags or no tags at all, and retrieve the Name tag for that instance
    # and put that into a dict -- instanceid: name-region format

    # reset inst to not carry data foward
    inst = ""
    for inst in bt_missing:
        report_on = ec2.describe_tags(
            Filters=[
                {
                    'Name': 'resource-id',
                    'Values': [inst],
                },
            ],
        )

        for tag in report_on["Tags"]:
            if tag["Key"] == "Name":
                instname = tag["Value"]
        message = f"The instance: {inst} has no Billing Owner tag, if yours, please update: Name: {instname}, region: {bt_missing[inst]}"
        print(message)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM