如何获取新启动的AWS实例的公共IP地址?

Geo*_*voy 5 amazon-web-services aws-sdk-go

在 AWS 中启动新实例时,公共 IP 地址和 DNS 名称不会作为响应的一部分返回。

正如我在 Web 控制台中看到的那样,创建的计算机已分配公共 IP 和 DNS 名称,但对 SDK 方法调用的响应没有分配 IP 和 DNS 字段值。

我正在使用以下代码:

output, err := ec2session.RunInstances(input)
...
if output.Instances[0].PublicIpAddress == nil {
    //... that is the case
}
Run Code Online (Sandbox Code Playgroud)

我相信公共 IP 地址的分配在某种程度上被延迟了,即使我使用 Web 控制台无法注意到这一点。

创建实例后如何获取公网IP地址和DNS名称?轮询DescribeInstances 是正确的方法吗?

Geo*_*voy 1

RunInstances 方法可以在实例创建之前返回,因此还没有分配公共 IP 地址。

为了获取地址,我们需要发出额外的Describe...请求,但不仅如此 - 我们需要等到实例创建。Go AWS SDK 中有多种用于此目的的 Wait* 方法,它们使用 Descibe* 系列方法进行轮询,直到获得请求的状态。在这种情况下,您可以使用该WaitUntilInstanceExists方法(我正在使用该方法的 ..WithContext 版本):

reservation, err := ec2session.RunInstancesWithContext(ctx, input)
if err != nil {
    log.Errorf("error creating instances %v", err)
    return nil, nil, err
}

if !q.needsPublicAddress() {
    return reservation, nil, nil
}

instanceIds := make([]*string, len(reservation.Instances))

for k, v := range reservation.Instances {
    instanceIds[k] = v.InstanceId
}

statusInput := ec2.DescribeInstancesInput{
    InstanceIds: instanceIds,
}

log.Debugf("waiting for instances to exist...")

instanceOkErr := ec2session.WaitUntilInstanceExistsWithContext(ctx, &statusInput)
if instanceOkErr != nil {
    log.Errorf("failed to wait until instances exist: %v", instanceOkErr)
    return nil, nil, instanceOkErr
}

log.Debugf("describing existing instances ...")

description, descriptionErr := ec2session.DescribeInstancesWithContext(ctx, &statusInput)
if descriptionErr  != nil {
    log.Errorf("failed to describe instances: %v", descriptionErr )
    return nil, nil, descriptionErr
}

return reservation, description, nil
Run Code Online (Sandbox Code Playgroud)

在内部,它会发出多个Describe...请求,直到实例达到所需状态,然后可以使用Describe...请求获取实例状态。响应将包含分配给实例的公共 IP 地址。