skip to Main Content

I am trying to retrieve the private IP from my containers on AWS ECS, I am using python and boto3 for that work.

That is my code:

import json
import boto3

def lambda_handler(event, context):
  client = boto3.client("ecs", region_name="sa-east-1")

  clusterArn='ANY ARN'

  tasks = client.list_tasks(cluster=clusterArn)

  containers = []
  for each in tasks['taskArns']:
      containers.append(each)
     
    
  resp = client.describe_tasks(cluster=clusterArn,tasks=containers)
  print(json.dumps(resp, indent=4, default=str, sort_keys=True))

The describe tasks return for me the following IP from container:

{
"bindIP": "0.0.0.0",
"containerPort": 8080,
"hostPort": 8080,
"protocol": "tcp"
}

I alredy tried to use ecs describe task on aws cli, but its the same response. Is there another way to retrieve the private ip using boto3?

Thanks,

2

Answers


  1. With ECS on EC2, your task will have the IP of your EC2 instance and will then bind with an available port.

    You can get the port with the ECS API, but you’ll need the EC2 API to get the IP if there’s no networkInterfaces attached yo your containers.

    Here’s an example with the cli to get both IP and ports for a task:

    CLUSTER=your-cluster-name                                                                        
    TASK_NAME=your-task-name
    
    TASK_ARN=$(aws ecs list-tasks --service-name ${TASK_NAME} --query 'taskArns[0]' --output text --cluster ${CLUSTER})
    CONTAINERS_DATA=$(aws ecs describe-tasks --task ${TASK_ARN} --cluster ${CLUSTER})
    
    CONTAINER_ARN=$(echo $CONTAINERS_DATA | jq -r '.tasks[0].containerInstanceArn')
    CONTAINER_PORTS=$(echo $CONTAINERS_DATA | jq '.tasks[0].containers[].networkBindings[].hostPort')
    
    EC2_IID=$(aws ecs describe-container-instances --cluster ${CLUSTER} --container-instances ${CONTAINER_ARN} --output text --query 'containerInstances[0].ec2InstanceId')
    TASK_IP=$(aws ec2 describe-instances --instance-id ${EC2_IID} --output text --query 'Reservations[0].Instances[0].PrivateIpAddress')
    
    echo "Task IP: ${TASK_IP} | Task Ports: ${CONTAINER_PORTS}"
    # Task IP: 10.24.35.188 | Task Ports: 49165
    
    Login or Signup to reply.
  2. In AWS IP addresses are provided for Network Interfaces, which will be attached to the running containers. So you would want to fetch the network interface section of a container.

    For example:

    import boto3
    
    
    def lambda_handler(event, context):
        client = boto3.client("ecs", region_name="sa-east-1")
    
        cluster_arn = '...'
    
        tasks = client.list_tasks(cluster=cluster_arn)
        task_arns = [arn for arn in tasks['taskArns']]
        
        resp = client.describe_tasks(cluster=cluster_arn, tasks=task_arns)
        for task in resp['tasks']:
            for container in task['containers']:
                private_ips = [interface['privateIpv4Address'] for interface in container['networkInterfaces']]
                print(f'{container["name"]}: {private_ips}')
    

    It should output something like this:

    nginx: ['10.0.0.49']
    node: ['10.0.0.55']
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search