George Polevoy
George Polevoy

Reputation: 7681

How to get public IP address of a newly launched AWS instance?

When launching new instance in AWS, the public IP address and DNS name is not returned as part of the response.

The machine created has public IP and DNS name assigned, as I can see in the web console, but the response to the SDK method call does not have the IP and DNS field values assigned.

I'm using following code:

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

I believe the assignment of the public ip address is somehow delayed, even if I can't notice that using the web console.

How do I obtain the public IP address and DNS name after creating the instance? Is polling DescribeInstances the right method to do it?

Upvotes: 5

Views: 1843

Answers (1)

George Polevoy
George Polevoy

Reputation: 7681

The RunInstances method can return before the instance is created, so there is not public IP address assigned yet.

To get the address, we need to issue an additional Describe... request, but not only that - we need to wait until the instance is created. There are various Wait* methods for this purpose in the Go AWS SDK, which poll using Descibe* family of methods until requested status is obtained. In this case, you can use the WaitUntilInstanceExists method (I'm using the ..WithContext versions of the methods):

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

Internally, it makes multiple Describe... requests until the instances reach required state, then the instance state can be obtained using a Describe... request. The response will contain the public IP addresses assigned to the instances.

Upvotes: 1

Related Questions