Как получить список томов EBS в EC2 с помощью Python

Я пытаюсь получить список томов EBS в EC2 с помощью python.

Вот мой код:

import boto3
import objectpath
aws_account = 'company-lab'
region = 'us-east-1'
session = boto3.Session(profile_name=aws_account, region_name=region)
ec2 = session.client("ec2")
instance_list = ec2.describe_instances()
for reservation in instance_list["Reservations"]:
    for instance in reservation.get("Instances", []):
        tree = objectpath.Tree(instance)
        block_devices = set(tree.execute('$..BlockDeviceMappings[\'Ebs\'][\'VolumeId\']'))
        block_devices = list(block_devices)
        for volume_id in block_devices:
            volume = ec2.Volume(volume_id)

Когда я пытаюсь это сделать, я получаю следующую ошибку:

Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
  File "C:\Users\tdun0002\AppData\Local\Programs\Python\Python38-32\lib\site-packages\botocore\client.py", line 573, in __getattr__
    raise AttributeError(
AttributeError: 'EC2' object has no attribute 'Volume'

Я пытаюсь использовать boto3 EC2 Volume атрибут. Я хотел бы получить список томов EBS и их размеров для любого конкретного экземпляра EC2. Как я могу это сделать?


person bluethundr    schedule 28.09.2020    source источник
comment
ec2.Volume(volume_id) использует метод resource, а не метод client. Это немного сбивает с толку, но в основном клиент EC2 эквивалентен необработанным вызовам API, сделанным к AWS, в то время как ресурс EC2 - это более питонический способ представления ресурсов boto3. Как правило, лучше придерживаться одного метода, чем переключаться между ними.   -  person John Rotenstein    schedule 29.09.2020


Ответы (1)


Я хотел бы получить список томов EBS и их размеров для любого конкретного экземпляра EC2.

Вот код, использующий метод resource:

import boto3

ec2_resource = boto3.resource('ec2')

for instance in ec2_resource.instances.all():
    for volume in instance.volumes.all():
        print(instance.id, volume.id, volume.volume_type, volume.size)

И используя метод client:

import boto3

ec2_client = boto3.client('ec2')

response = ec2_client.describe_instances()

for reservation in response['Reservations']:
    for instance in reservation['Instances']:
        volumes = ec2_client.describe_volumes(
            Filters=[{'Name':'attachment.instance-id','Values':[instance['InstanceId']]}]
        )
        for disk in volumes['Volumes']:
            print(instance['InstanceId'], disk['VolumeId'], disk['VolumeType'], disk['Size'])

Однако это приводит к нескольким вызовам API (по одному DescribeInstances(), а затем по одному DescribeVolumes() для каждого экземпляра).

В этой версии используется всего лишь один вызов DescribeVolumes() и выполняется сортировка по InstanceId:

import boto3

ec2_resource = boto3.resource('ec2')

volumes = [(v.attachments[0]['InstanceId'], v.id, v.size)
           for v in ec2_resource.volumes.filter(Filters=[{'Name':'attachment.status','Values':['attached']}])]

for volume in sorted(volumes):
    print(volume[0], volume[1], volume[2])

Вот эквивалентный код с использованием метода client:

import boto3

ec2_client = boto3.client('ec2')

response = ec2_client.describe_volumes(Filters=[{'Name':'attachment.status','Values':['attached']}])

volumes = [(v['Attachments'][0]['InstanceId'], v['VolumeId'], v['Size']) for v in response['Volumes']]

for volume in sorted(volumes):
    print(volume[0], volume[1], volume[2])

В дополнение к лицензии, предоставленной в соответствии с условиями обслуживания этого сайта, содержание этого сообщения находится под лицензией MIT-0.

person John Rotenstein    schedule 29.09.2020
comment
Спасибо! Это действительно полезно. Поскольку я использую клиент в своих сценариях, могу ли я как-нибудь перечислить тома, привязанные к определенному идентификатору экземпляра? Было бы неплохо сделать это и с помощью ресурса. - person bluethundr; 29.09.2020
comment
Я добавил client пример списка томов, прикрепленных к экземпляру. - person John Rotenstein; 30.09.2020
comment
Ок, отлично! Спасибо, это очень помогло. Очень ценю всю информацию. - person bluethundr; 30.09.2020