DEV Community

Cover image for Bash script to make ECS Exec (aws ecs execute-command) useful
yuki777
yuki777

Posted on

4 1

Bash script to make ECS Exec (aws ecs execute-command) useful

Usage

# 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 # :)

Enter fullscreen mode Exit fullscreen mode

Source

Bash script(gist)

#!/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 $@
Enter fullscreen mode Exit fullscreen mode

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay