Bash script to make ECS Exec (aws ecs execute-command) useful
Published: 2021-11-08 01:22:03

---
title: Bash script to make ECS Exec (aws ecs execute-command) useful
published: true
description: Bash script to make ECS Exec (aws ecs execute-command) useful
tags: 
cover_image: https://user-images.githubusercontent.com/177159/140670332-aff1486b-2dd4-4003-9efc-808ab70deccf.png
---

- Translated from [qiita.com](https://qiita.com/yuki777/items/e7bcb80e32eca355ddac)
- Bash script([gist](https://gist.github.com/yuki777/640cba3e0a68587c36165b8a87d25390))

## Usage

```bash
# Download it, save it any name you like, `chmod` it.
curl https://gist.githubusercontent.com/yuki777/640cba3e0a68587c36165b8a87d25390/raw/5bfa8242ba00ed336da76711d602e6df4f76a452/sssh -o sssh
chmod 744 sssh
./sssh

# Select aws profile from `aws configure list-profiles`
Select aws profile.
1) default
2) foo-bar
#? 2
profile: foo-bar

# Select cluster from `aws ecs list-clusters`
Select cluster.
1) dev-foo-bar-cluster          9) prod-foo-app-cluster
2) prd-foo-hoge-ad-cluster      10) stg-foo-app-cluster
3) prd-foo-hoge-cluster         11) stg-foo-hoge-cluster
4) prd-foo-piyo2021-ad-cluster  12) stg-foo-piyo2021-cluster
5) prd-foo-piyo2021-cluster     13) stg-foo-bar-cluster
6) prd-foo-bar-ad-cluster       14) stg-foo-tags-cluster
7) prd-foo-bar-cluster          15) hoge-foo-bar-cluster
8) prd-foo-tags-cluster
#? 1
cluster: dev-foo-bar-cluster

# Select service from `aws ecs list-services`
 1) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1125-service
 2) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1206-service
 3) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1249-service
 4) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1275-service
 5) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1323-service
 6) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1348-service
 7) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1349-service
 8) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1384-service
 9) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1386-service
10) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1391-service
11) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1397-service
12) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1399-service
13) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1412-service
14) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1413-service
15) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1419-service
16) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-qa-1420-service
17) arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-service
#? 16
service: arn:aws:ecs:ap-northeast-1:************:service/dev-foo-bar-cluster/dev-foo-bar-qa-1420-service

# Select task from `aws ecs list-tasks`
1) arn:aws:ecs:ap-northeast-1:************:task/dev-foo-bar-cluster/********************************
#? 1
task: arn:aws:ecs:ap-northeast-1:************:task/dev-foo-bar-cluster/********************************

# Select container from `aws ecs describe-tasks`
1) container-foo
2) container-bar
3) container-hoge
4) container-piyo
#? 1
container: container-foo

# Show command
aws ecs execute-command --profile foo-bar --cluster dev-foo-bar-cluster --container container-foo --task arn:aws:ecs:ap-northeast-1:************:task/dev-foo-bar-cluster/******************************** --interactive --command '/bin/sh'

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.

# Start your session and run command from `aws ecs execute-command`
Starting session with SessionId: ecs-execute-command-*****************
/path/to/home # :)

```


## Source

Bash script([gist](https://gist.github.com/yuki777/640cba3e0a68587c36165b8a87d25390))

```bash
#!/bin/bash

# Bash script to run ecs-exec on Amazon ECS Fargate containers.
#
# Usage: See --help.
#
# Installation: Download the script and `chmod u+x the script`.
#  curl https://gist.githubusercontent.com/yuki777/640cba3e0a68587c36165b8a87d25390/raw/5bfa8242ba00ed336da76711d602e6df4f76a452/sssh -o sssh && chmod u+x sssh
#  ./sssh
#
# Prerequisites (validated)
# - aws cli
# - session-manager-plugin
# - jq
#
# Special thanks to contributor
# - leewc

set -eu

selectProfile(){
	# profile parameter not supplied.
	if [ -z ${profile+x} ]; then
		# only works with AWS CLIv2.
		select selected in `aws configure list-profiles`
		do
			break
		done
		echo $selected
	else
		echo $profile
	fi
}

params(){
	echo "$(profileParam) $(regionParam)"
}

profileParam() {
	[[ $profile ]] &>/dev/null && echo "--profile $profile"
}

regionParam() {
	[[ $region ]] &>/dev/null && echo "--region $region"
}

selectCluster(){
	select selected in $(aws ecs list-clusters $(params)|jq -r ".clusterArns[]"|sort|cut -d "/" -f 2)
	do
		break
	done
	echo $selected
}

selectService(){
	select selected in $(aws ecs list-services $(params) --cluster $cluster|jq -r ".serviceArns[]"|sort)
	do
		break
	done
	echo $selected
}

selectTask(){
	select selected in $(aws ecs list-tasks $(params) --cluster $cluster --service-name $service --desired-status RUNNING |jq -r '.taskArns[]'|sort)
	do
		break
	done
	echo $selected
}

selectContainer(){
	select selected in $(aws ecs describe-tasks $(params) --cluster $cluster --tasks $task | jq -r ".tasks[].containers[].name"|sort)
	do
		break
	done
	echo $selected
}

colorEcho(){
	red='\033[0;31m'
	green='\033[0;32m'
	yellow='\033[0;33m'
	reset='\033[0m'

	if echo $@ | egrep -q "prd|prod|production"; then
		color=$red
	elif echo $@ | egrep -q "stg|stage|staging|beta|devo"; then
		color=$yellow
	else
		color=$green
	fi

	echo -e "${color}$@${reset}"
}

echo_stderr() {
	echo -e "$@" >&2
}

die() {
	echo_stderr "$@"
	exit 1
}

validatePrereq() {
	command -v jq  &>/dev/null || die "jq not installed on host. Please install jq. See https://stedolan.github.io/jq/download/"
	command -v session-manager-plugin &>/dev/null || die "session-manager-plugin not installed. See https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html"
	command -v aws &>/dev/null || die "AWS CLI not found, AWS CLI version 1.16.12 or later must be installed. See https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"
	# Checks if AWS CLI is outdated or not., v1 of AWS CLI pipes to std error, redirect
	AWS_CLI_VERSION=$(aws --version 2>&1 | awk '{ print $1 }' | cut -d/ -f2)
	echo_stderr "You have AWS CLI v$AWS_CLI_VERSION installed."
	# Do a best effort check for v1 (so that it's at least 1.10 and up.
	[[ $AWS_CLI_VERSION =~ ^1.1[0-9] || $AWS_CLI_VERSION =~ ^2 ]] &>/dev/null || die "AWS CLI version 1.16.12 or later must be installed to support ecs-exec, Run 'aws --version' to see what you have. See https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"
}

function print_help() {
	cat >&2 <<-END

This script simplifies the process of getting the required information to drop into an
interactive shell script on your container hosted on Fargate/ECS.

Example:

./sssh --region us-west-2
./sssh --profile default

Supported input parameters:
 -r | --region  : AWS Region to fetch the cluster, service, task
 -p | --profile : AWS Profile for credentials and region.
 -c | --command : Command to execute, defaults to '/bin/sh'/

The default command executed on the selected container is '/bin/sh'.
If a region is not provided, the script will attempt to use your region set in the profile.
If you want to execute a different command or shell, you can pass it in like so:

./sssh --command '/bin/bash'

You need active (unexpired) AWS credentials, otherwise, the script will crash.

Updates on https://gist.githubusercontent.com/leewc/e4c3a16551b06c2b0b4640fa5a3d9c00

END
}

main(){
	command='/bin/sh'
	while [[ "$#" -gt 0 ]]; do
		case $1 in
			-h|--help)
				print_help
				exit
				;;
			-r|--region)
				shift
				region="${1:?Region must be specified in --region}"
				shift
				;;
			-p|--profile)
				shift
				profile="${1:?Profile must be specified in --profile}"
				shift
				;;
			-c|--command)
				shift
				command="${1:?Command must be specified in --command}"
				shift
				;;
			*)
				die "Unknown param $1"
				;;
		esac
	done

	echo_stderr "Validating pre-requisites...."
	validatePrereq

	# spaces matter :)
	if [[ $AWS_CLI_VERSION =~ ^2 ]] ; then
		echo_stderr "Select AWS Profile."
		profile=`selectProfile`
		colorEcho profile: $profile
	else echo_stderr "[INFO] AWS CLI is not v2, unable to select profile. --region or --profile must be set."
	fi
	echo_stderr

	echo_stderr "Select cluster."
	cluster=`selectCluster`
	colorEcho cluster: $cluster
	echo_stderr

	echo_stderr "Select service."
	service=`selectService`
	colorEcho service: $service
	echo_stderr

	echo_stderr "Select task."
	task=`selectTask`
	colorEcho task: $task
	echo_stderr

	echo_stderr "Select container."
	container=`selectContainer`
	colorEcho container: $container
	echo_stderr

	echo_stderr "Executing command (you might have to upgrade your AWS CLI if this fails)"
	cmd="aws ecs execute-command $(params) --cluster $cluster --container $container --task $task --interactive --command '$command'"
	colorEcho $cmd

	$cmd
}

# Execute main function and pass all params over
main $@
```