【问题标题】:Retrieving public dns of EC2 instance with BOTO3使用 BOTO3 检索 EC2 实例的公共 dns
【发布时间】:2016-04-16 04:07:21
【问题描述】:

我正在使用 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 实例,我可以从 AWS 控制台获取公共 DNS 名称、IP 和其他信息。但是,当我尝试使用 Boto 获取公共 DNS 时,这样做:

new_instance[0].public_dns_name

返回空白引号。然而,其他实例详细信息,例如:

new_instance[0].instance_type

返回正确的信息。

有什么想法吗?谢谢。

编辑:

如果我这样做:

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。但对我来说,为什么我需要做这一切没有意义。

【问题讨论】:

    标签: python amazon-web-services dns boto3 aws-ec2


    【解决方案1】:

    您返回的Instance 对象仅使用来自create_instances 调用的响应属性进行补充。由于在实例达到运行状态[1] 之前,DNS 名称不可用,因此它不会立即出现。我想您创建实例和调用 describe 实例之间的时间足够长,足以启动微实例。

    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)
    

    【讨论】:

    • 我尝试了 instance.load,它给了我错误:“AttributeError: 'dict' object has no attribute 'load'
    • 对于遇到 Alex 问题的任何其他人,实例的类型应为 ec2.Instance,因此请检查您的逻辑。另外,提醒一下create_instances() 的返回值是ec2.Instance 对象的列表
    • 谢谢 - 我不确定为什么我的实例(即使在等待调用之后)仍然显示为待处理,我没有使用加载功能。
    【解决方案2】:
    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

    【讨论】:

    • 这里使用 pandas 似乎有点过头了。
    • @jarmod :我希望在表格中看到更多的值,这样我们也可以准备库存,当我们从 boto3 获取数据时,dicts 在可视化方面非常复杂。它是一种模板,我们也可以在其中获取其他 aws 属性。
    • 感谢使用 pandas,因为它使理解 API 接口变得更容易
    【解决方案3】:

    这是我的包装:

    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:

    dns = get_public_dns(instance_id)
    

    记得将“region_name”更改为您的区域并添加您的“aws_access_key_id”和“aws_secret_access_key”

    【讨论】:

      猜你喜欢
      • 2019-01-28
      • 2014-01-23
      • 2015-03-23
      • 2014-12-29
      • 2019-03-29
      • 2021-04-25
      • 1970-01-01
      • 2012-03-03
      • 2018-03-11
      相关资源
      最近更新 更多