Reputation: 1732
I have a cluster running with services and am also able to launch fargate tasks from the command line. I can get the taskArn as a response to launching the task and I can wait for the task to be in the running state by using "aws ecs wait". I'm stuck figuring out how to get the the public IP of the task. I can find it via the web page easily enough and can access the machine via it's public IP...
How do I get the public IP of a fargate task using the CLI interface?
I'm using the following commands to launch the task, wait for it to run and retrieve the task description:
$ aws ecs run-task --launch-type FARGATE --cluster xxxx --task-definition xxxx --network-configuration xxxx
$ aws ecs wait <taskArn>
$ aws ecs describe-tasks --cluster xxxx --task <taskArn> | grep -i ipv4
The last command only gives me the private IP...
"privateIpv4Address": "10.0.1.252",
"name": "privateIPv4Address"
I've also tried using:
$ ecs-cli ps --cluster xxxx
But the Ports column is blank.
Name State Ports TaskDefinition
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxxx RUNNING xxxx:1
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxxx RUNNING xxxx:1
Upvotes: 36
Views: 30124
Reputation: 1155
ECS Get PublicDnsName and PublicIp in case of FARGATE
Step-1
aws ecs list-tasks --cluster <cluster-name> --service-name <service-name>
CLI: aws ecs list-tasks --cluster inx --service-name inx-service
Step-2
aws ecs describe-tasks --cluster <cluster-name> --tasks <arn-of-task>
CLI: aws ecs describe-tasks --cluster inx --tasks arn:aws:ecs:ap-south-1:123456789012:task/inx/3b2902d17ca64d7e96eb412253fd8cf9
Inside attachments section get networkInterfaceId that should be like eni-0e07d16ba740ecf8d
...
{
"name": "networkInterfaceId",
"value": "eni-0e07d16ba740ecf8d"
},
...
Step-3
aws ec2 describe-network-interfaces --network-interface-ids <eni-id>
CLI: aws ec2 describe-network-interfaces --network-interface-ids eni-0e07d16ba740ecf8d
...
{
"NetworkInterfaces": [
{
"Association": {
"IpOwnerId": "amazon",
"PublicDnsName": "ec2-11-123-11-111.ap-south-1.compute.amazonaws.com",
"PublicIp": "11.123.11.111"
}
...
finally
Have a look into Step-3 Here "PublicDnsName": "ec2-11-123-11-111.ap-south-1.compute.amazonaws.com" is your Public Dns Name address and "PublicIp": "11.123.11.111" is your Public Ip address
Upvotes: 0
Reputation: 614
I tinkered around with one of the comments here and came up with the following shell script:
#!/bin/bash
# Take the cluster name from the script arguments
CLUSTER_NAME=$1
# Get a list of tasks in the cluster
TASKS=$(aws ecs list-tasks --cluster "$CLUSTER_NAME" --query "taskArns" --output text)
# Loop through each task to get the container instance ARN
for TASK_ARN in $TASKS
do
# Get a human readable ARN.
TASK_ID=$(basename $TASK_ARN)
# Get the network interface ID for the task
NETWORK_INTERFACE_ID=$(aws ecs describe-tasks --cluster $CLUSTER_NAME --tasks $TASK_ARN --query 'tasks[0].attachments[0].details[?name==`networkInterfaceId`].value' --output text)
#Get the public IP of the network interface
PUBLIC_IP=$(aws ec2 describe-network-interfaces --network-interface-ids $NETWORK_INTERFACE_ID --query 'NetworkInterfaces[0].Association.PublicIp')
echo "Task: $TASK_ID -- Public IP: $PUBLIC_IP"
done
you can call your script like ./list-ecs-tasks.sh <your-cluster-arn>
and it loops through the tasks in your cluster and prints out the TaskID and Public IP of each one.
Upvotes: 2
Reputation: 145
This was specific to my usecase, but perhaps its useful to someone else (intended to be run as javascript in Lambda just after you run ecs.createService() )
Yes, I know this topic is for CLI but this is the first result that popped up when looking for "Fargate public IP" and i was looking for a javascript based solution.
// get container IP
getContainerIP(myServiceName).then(ip => {
console.log("Container IP address is: ", ip);
}).catch(err => {
console.log(err);
});
function getContainerIP(servicename) {
// note: assumes that only 1 task with 1 container is in the provided service, and that a container only has 1 network interface
return new Promise(function (resolve, reject) {
// get task arns (needs a delay because we just launched it)
setTimeout(getTasks, 6000);
// get task arns
function getTasks() {
ecs.listTasks({
cluster: process.env.ecs_cluster,
launchType: "FARGATE",
serviceName: servicename
}, function (err, res) {
if (err) {
reject("Unable to get task list");
return;
}
// loop until we have a result
if (!res.taskArns.length) {
setTimeout(getTasks, 2000);
return;
}
// get details
getTaskDetails(res.taskArns);
});
}
// get the details of the task (we assume only one task because that's how its configured)
function getTaskDetails(taskArns) {
ecs.describeTasks({
cluster: process.env.ecs_cluster,
tasks: taskArns
}, function (err, res) {
if (err) {
reject("Unable to get task details");
return;
}
// no results
if (!res.tasks.length || !res.tasks[0].attachments.length) {
reject("No tasks available");
return;
}
// network needs to be in status ATTACHING to see the eni, else wait
if (res.tasks[0].attachments[0].status !== "ATTACHING") {
setTimeout(function () { getTaskDetails(taskArns); }, 2000);
return;
}
// get network ID from result
let eni = "";
for (let i in res.tasks[0].attachments[0].details) {
if (!res.tasks[0].attachments[0].details.hasOwnProperty(i)) continue;
if (res.tasks[0].attachments[0].details[i].name !== "networkInterfaceId") continue;
// get the eni
eni = res.tasks[0].attachments[0].details[i].value;
break;
}
// no eni
if (eni === "") {
reject("Unable to retrieve container ENI");
return;
}
// get network details
getNetworkDetails(eni);
});
}
// get network details
function getNetworkDetails(eni) {
// get the ENI details
ec2.describeNetworkInterfaces({
NetworkInterfaceIds: [eni]
}, function (err, res) {
if (err) {
reject("Unable to retrieve ENI details");
return;
}
// confirm available data
if (!res.NetworkInterfaces.length || typeof res.NetworkInterfaces[0].Association === "undefined" || typeof res.NetworkInterfaces[0].Association.PublicIp === "undefined") {
reject("Unable to retrieve IP from ENI details");
return;
}
// resolve the public IP address
resolve(res.NetworkInterfaces[0].Association.PublicIp);
});
}
});
}
Upvotes: 9
Reputation: 4296
You can use a script like this.
SERVICE_NAME="my-service"
TASK_ARN=$(aws ecs list-tasks --service-name "$SERVICE_NAME" --query 'taskArns[0]' --output text)
TASK_DETAILS=$(aws ecs describe-tasks --task "${TASK_ARN}" --query 'tasks[0].attachments[0].details')
ENI=$(echo $TASK_DETAILS | jq -r '.[] | select(.name=="networkInterfaceId").value')
IP=$(aws ec2 describe-network-interfaces --network-interface-ids "${ENI}" --query 'NetworkInterfaces[0].Association.PublicIp' --output text)
echo "$IP"
Upvotes: 10
Reputation: 783
describe-addresses
the docs are here: https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-addresses.html
Upvotes: -6
Reputation: 1732
Once I realized that describe-tasks gave me the ENI id along with the private IP I was able to get the public IP with:
$ aws ec2 describe-network-interfaces --network-interface-ids eni-xxxxxxxx
Upvotes: 39