Получение общедоступных DNS экземпляра EC2 с помощью BOTO3

Я использую ipython, чтобы понять Boto3 и взаимодействовать с экземплярами EC2. Вот код, который я использую для создания экземпляра:

import boto3

ec2 = boto3.resource('ec2')
client = boto3.client('ec2')


new_instance = ec2.create_instances(
    ImageId='ami-d05e75b8',
    MinCount=1,
    MaxCount=1,
    InstanceType='t2.micro',
    KeyName=<name_of_my_key>,
    SecurityGroups=['<security_group_name>'],
    DryRun = False
    )

Это нормально запускает экземпляр EC2, и я могу получить общедоступное DNS-имя, IP-адрес и другую информацию из консоли AWS. Но когда я пытаюсь получить общедоступный DNS с помощью Boto, сделав следующее:

new_instance[0].public_dns_name

Возвращает пустые кавычки. Тем не менее, другие детали экземпляра, такие как:

new_instance[0].instance_type

Возвращает верную информацию.

Любые идеи? Спасибо.

РЕДАКТИРОВАТЬ:

So if I do:

def get_name(inst):
    client = boto3.client('ec2')
    response = client.describe_instances(InstanceIds = [inst[0].instance_id])
    foo = response['Reservations'][0]['Instances'][0]['NetworkInterfaces'][0]['Association']['PublicDnsName']
    return foo


foo = get_name(new_instance)
print foo

Затем он вернет общедоступный DNS. Но мне непонятно, зачем мне все это делать.


person William Rudisill    schedule 11.01.2016    source источник


Ответы (3)


Возвращаемый вами объект Instance гидратируется только атрибутами ответа из вызова create_instances. Поскольку DNS-имя недоступно до тех пор, пока экземпляр не достигнет рабочего состояния, [1], сразу не появится. Я полагаю, что время между созданием экземпляра и вызовом экземпляров описания достаточно велико для запуска микро-экземпляра.

import boto3

ec2 = boto3.resource('ec2')
instances = ec2.create_instances(
    ImageId='ami-f0091d91',
    MinCount=1,
    MaxCount=1,
    InstanceType='t2.micro',
    KeyName='<KEY-NAME>',
    SecurityGroups=['<GROUP-NAME>'])
instance = instances[0]

# Wait for the instance to enter the running state
instance.wait_until_running()

# Reload the instance attributes
instance.load()
print(instance.public_dns_name)
person Jordon Phillips    schedule 12.01.2016
comment
Я попробовал instance.load, он дал мне ошибку: AttributeError: объект 'dict' не имеет атрибута 'load' - person Alex; 24.10.2018
comment
Для всех, у кого есть проблема с Алексом, экземпляр должен быть типа ec2.Instance, поэтому проверьте свою логику. Также напоминаем, что возвращаемое значение create_instances() - это список из ec2.Instance объектов. - person The Unknown Dev; 02.02.2019
comment
спасибо - я не был уверен, почему мой экземпляр (даже после вызова ожидания) все еще отображается как ожидающий, я не использовал функцию загрузки. - person Ali; 24.05.2020

Вот моя обертка:

import boto3
from boto3.session import Session

def credentials():
    """Credentials:"""
    session = Session(aws_access_key_id= 'XXXXXXXXX',
                      aws_secret_access_key= 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
    ec2 = boto3.resource('ec2', region_name='us-east-2')
    return ec2

def get_public_dns(instance_id):
    """having the instance_id, gives you the public DNS"""
    ec2 = credentials()
    instance = ec2.Instance(instance_id)
    instancePublicDNS = instance.public_dns_name
    return instancePublicDNS

Затем вам просто нужно использовать свой instance_id, чтобы получить общедоступный идентификатор любого из ваших активных ec2:

dns = get_public_dns(instance_id)

Не забудьте изменить region_name на свою зону и добавить свои aws_access_key_id и aws_secret_access_key

person Javi    schedule 29.12.2020

import boto3
import pandas as pd
session = boto3.Session(profile_name='aws_dev')
dev_ec2_client = session.client('ec2')
response = dev_ec2_client.describe_instances()
df = pd.DataFrame(columns=['InstanceId', 'InstanceType', 'PrivateIpAddress','PublicDnsName'])
i = 0
for res in response['Reservations']:
    df.loc[i, 'InstanceId'] = res['Instances'][0]['InstanceId']
    df.loc[i, 'InstanceType'] = res['Instances'][0]['InstanceType']
    df.loc[i, 'PrivateIpAddress'] = res['Instances'][0]['PrivateIpAddress']
    df.loc[i, 'PublicDnsName'] = res['Instances'][0]['PublicDnsName']
    i += 1
print df

Примечание:

  1. Измените этот профиль на свое имя профиля AWS profile_name='aws_dev'
  2. Этот код работает на Python3
person Jitendra Bhalothia    schedule 19.09.2019
comment
Использование панд здесь кажется излишним. - person jarmod; 19.09.2019
comment
@jarmod: Я хотел бы видеть значения больше в табличном представлении, чтобы мы также могли подготовить инвентарь. Поскольку мы получаем данные из boto3, dicts очень сложны в визуализации. И это своего рода шаблон, в котором мы получаем и другие атрибуты aws. - person Jitendra Bhalothia; 20.09.2019