How to get public ip from a network interface attached to an ECS task with boto3

I need some help here.

I'm trying to obtain a public IP from a network interface using boto3, for some reason I'm getting the following error:

ec2 = boto3.resource('ec2')
nia = ec2.NetworkInterfaceAssociation('eni-r2d2')
nia.id  # I can obtain the id without any issue
# 'eni-r2d2'
nia.public_ip
# /usr/local/lib/python3.6/site-packages/boto3/resources/factory.py in property_loader(self)
#     343                             self.__class__.__name__))
#     344
# --> 345             return self.meta.data.get(name)
#     346
#     347         property_loader.__name__ = str(snake_cased)
# 
# AttributeError: 'NoneType' object has no attribute 'get'

Note: The network interface belongs to an ECS task, launch type is FARGATE and the network mode is awsvpc. Can someone help me please?

Thanks!

1 answer

  • answered 2018-07-11 12:44 bluescores

    I don't think you can do this purely with boto3, so unless you have a requirement to use it, use the metadata service. AWS docs would tell you to invoke the metadata service from within the container and parse the json response for the public IP. Documentation here. Note ECS "classic" has a different metadata endpoint when the ecs-agent version < 1.17.0.

    Something like this should work from inside a container in Fargate:

    import requests
    
    try:
        response = requests.get('http://169.254.170.2/v2/metadata').json()  
        for container in response.get('Containers', []):
            if 'Networks' in container:
                for network in container.get('Networks', []):
                    if 'IPv4Addresses' in network:
                        for ipv4address in network.get('IPv4Addresses', []):
                            print ipv4address # or do something else
    except requests.exceptions.RequestException:
        # parse the smoldering remains of the response object