Python Boto3 - 无法列出没有标签的实例

时间:2018-04-23 11:10:35

标签: python amazon-web-services amazon-ec2 tags boto3

这里我正在编写一个python程序来列出所有没有标签“Owner”的ec2实例。我现在被困住的地方是如果程序遇到任何已经拥有“所有者”标签的实例,那么它会在不检查其他实例的情况下退出。我想要的是跳过这些实例并继续检查其他实例。 这是我的代码:

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

以下是json dict对象的外观:

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

4 个答案:

答案 0 :(得分:1)

我注意到你的代码中有一些东西,如果你做的稍微不一样,那么控制程序的流程会更容易。对于初学者,使用更多描述性变量名称,例如,如果您有一个实例列表,那么一个好名称就是<connectionStrings> <add name="cnx" connectionString="Data Source=SERVER1\SQLEXPRESS; Initial Catalog=MyNICEDB; Persist Security Info=True; User ID=USER; Password=PASSWORD" providerName="System.Data.SqlClient" /> </connectionStrings> 。以下是如何执行此操作的示例:

instances

请注意我是如何添加一些间距以提高可读性的。

最后,如果你有一个字符串,即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 ,那么将瘦素放入一个名为"Owner"的变量中是愚蠢的,因为如果它被更改,那只会让人感到困惑。

答案 1 :(得分:1)

您的continue导致了一些问题。

这是一个替代版本:

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

答案 2 :(得分:1)

在找到不匹配的第一个标记后,您将退出循环。获取所有标签,然后检查。试试这个:

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

答案 3 :(得分:0)

几乎完全是这样写的,这里几乎没有什么地方可以看的。没有特别的顺序:

  1. 给出的示例仅覆盖一个区域。
  2. 这些示例将仅查找缺少所有者标签的实例。在某些情况下,标签存在,但“值”为空
  3. 对于新启动的实例,如果未添加标签,答案示例将出错。

下面回答了这个问题,并涵盖了以上几点。

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