Skip to content

Instantly share code, notes, and snippets.

@softprops
Last active November 25, 2022 02:30
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save softprops/3711c9fe54da673b1ebb53610aab4171 to your computer and use it in GitHub Desktop.
Save softprops/3711c9fe54da673b1ebb53610aab4171 to your computer and use it in GitHub Desktop.
when you want `docker exec` but your containers live on ecs container instances. assumes an vpn bastion host
#!/usr/bin/env bash
# runs an arbitrary command on a remote ecs target
#
# usage: `ecs-exec bash`
#
# ssh credentials
#
# Add the following to your ~/.ssh/config file
#
# Assumes ec2 bastion key for authenicating
# exists under ~/.pems/{ec2-key}.pem
#
# Host prod_bastion
# HostName {your-bastion-host}
# User ubuntu
# ForwardAgent yes
# IdentityFile ~/.pems/{ec2-key}.pem
#
# authenticate ssh agent
ssh-add ~/.pems/{ec2-key}.pem 2>/dev/null
bastion="ubuntu@{your-bastion-host}"
cluster={your-default-cluster}
service={your-default-service}
container={your-default-container}
# process flags --cluster, --service, --container
cmd=()
while [[ $# -gt 0 ]]
do
case "$1" in
-c|--cluster)
cluster="$2"
shift
shift
;;
-s|--service)
service="$2"
shift
shift
;;
--container)
container="$2"
shift
shift
;;
*)
cmd+=("$1")
shift
;;
esac
done
set -- "${cmd[@]}"
# get an arn for a task spawned by a service in a target cluster
task_arn=$(
aws ecs list-tasks \
--cluster ${cluster} \
--service-name ${service} \
--query 'taskArns[0]' \
--output=text
)
# get the ecs cluster instance id
container_instance_id=$(
aws ecs describe-tasks \
--tasks ${task_arn} \
--cluster ${cluster} \
--query 'tasks[0].containerInstanceArn' \
--output=text
)
# get the ec2 id that cluster instance is running on
ec2_instance_id=$(
aws ecs describe-container-instances \
--container-instances $container_instance_id \
--cluster ${cluster} \
--query 'containerInstances[0].ec2InstanceId' \
--output=text
)
# get the private ip of that ec2 instance
ec2_private_ip=$(
aws ec2 describe-instances \
--instance-ids ${ec2_instance_id} \
--query 'Reservations[0].Instances[0].NetworkInterfaces[0].PrivateIpAddresses[0].PrivateIpAddress' \
--output=text
)
# get the container id for a named container in the task definition of the target service
container_id=$(
ssh -q \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-At ${bastion} \
ssh -q \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-q ec2-user@${ec2_private_ip} \
curl -s http://localhost:51678/v1/tasks?taskarn=${task_arn} \
| jq -r ".Containers[] | select(.Name==\"${container}\") | .DockerId"
)
# remote docker exec an arbitrary command
ssh -q \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-At ${bastion} \
ssh -q \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no \
-q ec2-user@${ec2_private_ip} -qt \
docker exec -it ${container_id} ${@}
@daya
Copy link

daya commented Jul 18, 2019

@softprops does this support Fargate containers by any chance?

@softprops
Copy link
Author

not at the movement. there are no ec2 instances to ssh into with fargate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment