Photo by Kari Shea on Unsplash
(この記事はあしたのクラウド のインフラ移行に関する連載記事です)
こんにちは。最近、副業を始めたこともあり ( 弊社は副業OKです ) 何かと忙しくなりブログ更新が滞ってましたが、改めてアウトプットを継続していく気持ちの @snaka です。
ECS 上で動作しているアプリケーションの調査を行う際に ECS Exec は何かと便利ですよね。このブログの別の記事でも紹介しました。
今回はその ECS Exec をより便利に使うためのスクリプトをご紹介します。
🙏 Acknowledgements
この記事で紹介するスクリプトの原形は (私ではなく) 社内メンバーが作ってくれました。 初版から環境の変更等への対応を経て現在の状態になりました。
この場を借りて感謝を捧げます 🙏
😥 ECS Exec に渡すオプションを調べるのがめんどくさい
ECS Exec 便利ですが、ただ... ちょっと指定するオプションの数が多くて面倒くさくないですか?
たとえば、オプションとして --cluster
, --task
, --container
を指定する必要があります。
ただ、 --task
で指定する Task ID は起動する毎に採番されるのでその都度 Task ID を調べる必要があります。そうして調べた Task ID を使って以下のように AWS CLI でコマンドを実行します。
$ aws ecs execute-command --cluster hoge --task abcdefg0123456789 --container app --interactive --command '/bin/bash'
この「現在稼働している Task の ID を取得する」という作業もひっくるめて面倒を見てくれるスクリプトを用意しました。
⚙️ ecs exec + shell 起動 = ecsh
スクリプトの名前は ecsh
としました。
ecs exec
と shell
を足して ecsh
です。
前提条件
スクリプトの動作的には AWS CLI を叩いているだけなので、AWS CLI がインストールされていてクレデンシャルなどが設定されていることが必要です。
スクリプト
以下にスクリプトを掲載します。
#!/usr/bin/env sh check_cmd() { which session-manager-plugin 1>/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Not found Session Manager Plugin" echo "Install please" exit 1 fi which aws 1>/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Not found aws-cli" echo "Install please" exit 1 fi } usage() { cmd=`basename "$0"` echo "Usage: ${cmd} (OPTION cluster|profile) [OPTION service|container|region] ..." echo "-C, --cluster: Part of the cluster name (REQUIRED)" echo "-s, --service: Service name (default 'app')" echo "-c, --container: Container name (default 'app')" echo "-p, --profile: AWS profile name (use environment variable 'AWS_PROFILE' as the default value)" echo "-r, --region: AWS region name (default 'ap-northeast-1')" } check_cmd service='app' container='app' region='ap-northeast-1' profile=$AWS_PROFILE while [ "$#" -gt 0 ]; do option=$1 shift arg=$1 shift case $option in -C | --cluster) cluster=$arg ;; -s | --service) service=$arg ;; -c | --container) container=$arg ;; -p | --profile) profile=$arg ;; -r | --region) region=$arg ;; -h | --help) usage exit 0 ;; *) usage exit 1 ;; esac done if [ -z $cluster ] || [ -z $profile ]; then usage exit 1 fi profile_region="--profile ${profile} --region ${region}" # cluster cluster_arn=`aws ecs list-clusters --output text ${profile_region} | grep ${cluster} | ruby -ne 'puts $_.split[-1]'` if [ $? -ne 0 ]; then exit 1 fi cluster_name=`echo $cluster_arn | ruby -ne 'puts $_.split("/")[-1]'` if [ -z $cluster_name ]; then echo "Cannot find a cluster name that containes '${cluster}' as part of it." exit 1 fi echo "cluster_name: $cluster_name" # task task=`aws ecs list-tasks --cluster ${cluster_name} --service-name ${service} --output text ${profile_region} | ruby -ne 'puts $_.split[-1]'` if [ $? -ne 0 ]; then exit 1 fi task_id=`echo $task | ruby -ne 'puts $_.split("/")[-1]'` if [ -z $task_id ]; then echo "Cannot find the runnnig tasks in the service '${service}'." exit 1 fi echo "service: ${service}" echo "task_id: ${task_id}" aws ecs execute-command --cluster ${cluster_name} --task $task_id --container ${container} --interactive --command '/bin/bash' ${profile_region}
🕵️♂️ 使い方
Usage の内容を見れば、だいたい使い方は想像がつくと思います。
Usage: ecsh (OPTION cluster|profile) [OPTION service|container|region] ... -C, --cluster: Part of the cluster name (REQUIRED) -s, --service: Service name (default 'app') -c, --container: Container name (default 'app') -p, --profile: AWS profile name (use environment variable 'AWS_PROFILE' as the default value) -r, --region: AWS region name (default 'ap-northeast-1')
クラスタ名 (--cluster
) は必須*1です。指定された文字列をクラスタ名の一覧から部分一致で検索し、該当するクラスタ名の中から最後尾のクラスタに接続します。
使用例1
hoge-cluster
クラスタで稼働している app
サービスの app
コンテナに接続するする例です。
ecsh --cluster hoge-cluster
サービス名およびコンテナ名のデフォルトは app
なので、そのように配置されているコンテナには --cluster
の指定だけで接続できます。
使用例2
hoge-cluster
クラスタで稼働している batch
サービスの sidekiq
コンテナに接続する例です。
ecsh --cluster hoge-cluster --service batch --container sidekiq
サービス名およびコンテナ名が app
以外の場合は、オプションによる指定が可能です。
👋 さいごに
エンジニアが開発や運用を行う上で「ちょっとめんどくさい」手順ってよくあることです。
そして、そういう「ちょっとめんどくさい」はつい放置されがちで、そのうち「めんどくさい」自分自身が慣れてしまってそれが当たり前になってしまうことがあると思います。
そういった「めんどくさい」作業 ( トイル*2 ) を潰していくことは地味ですが SRE として大切な活動だなぁ、と改めて感じました。
ゆくゆくは SRE 活動の中から生まれた、このように運用をちょっとだけ楽にするツールを OSS で公開できたらなー、と妄想しております。
あしたのチームではプロダクトの成長と品質を支える SRE を募集中です。 一緒にトイルの撲滅に協力したい方いらっしゃったら 求人一覧 のページよりご応募ください 🙋♂️
*1:Usage で 'OPTION' と言いつつ '必須' というのは変なので、そのうち直します...