こんにちは、石川です。
今回は、Amazon WorkSpacesの起動と再起動をまとめて実行するbashスクリプトを整理してみます。
WorkSpacesが数台だけであれば、コンソールから操作してもそこまで大きな負担ではありません。
ただ、対象が複数台ある場合や、定期的に同じ作業を行う場合は、1台ずつ手で操作していくのは少し面倒です。
さらに、WorkSpacesは状態によって実行できる操作が異なるため、実務ではいきなり起動や再起動を実行するのではなく、事前に状態を確認してから処理する形にしておくと、かなり扱いやすくなります。
今回は、そうした実務向けの考え方も含めて、状態確認込みで一括実行できるbashスクリプトを紹介します。
なぜ一括スクリプトにしておくと便利なのか
WorkSpacesの運用では、以下のような場面で起動や再起動をまとめて実行したくなることがあります。
- メンテナンス前に対象端末をまとめて起動したい
- 作業後に対象端末をまとめて再起動したい
- 複数台に対して同じ操作を確実に実行したい
- 作業対象をファイルで管理して、漏れなく処理したい
こうしたとき、コンソールで1台ずつ選択していくよりも、対象のWorkSpace IDをファイルにまとめて、スクリプトで順番に処理する形にしておいた方が、かなり楽になります。
また、対象をファイルで残せるので、
「今回どのWorkSpaceに対して操作したのか」
が分かりやすいのも運用上のメリットです。
前提
まずは、対象のWorkSpace IDをテキストファイルにまとめておきます。
nano ws_ids.txt
ws-aaaaaaaa1
ws-bbbbbbbb2
ws-cccccccc3
このファイルをもとに、スクリプトが順番に処理していきます。
状態確認込みの一括実行スクリプト
nano workspace_bulk_action.sh
以下を記載します
#!/bin/bash
set -euo pipefail
INPUT_FILE="ws_ids.txt"
ACTION="${1:-}" # start または reboot
BATCH_SIZE=25
REQUESTS=()
if [[ "$ACTION" != "start" && "$ACTION" != "reboot" ]]; then
echo "Usage: $0 [start|reboot]"
exit 1
fi
flush_requests() {
if [ "${#REQUESTS[@]}" -eq 0 ]; then
return
fi
if [[ "$ACTION" == "start" ]]; then
echo "Starting ${#REQUESTS[@]} WorkSpaces..."
aws workspaces start-workspaces --start-workspace-requests "${REQUESTS[@]}"
else
echo "Rebooting ${#REQUESTS[@]} WorkSpaces..."
aws workspaces reboot-workspaces --reboot-workspace-requests "${REQUESTS[@]}"
fi
REQUESTS=()
}
while IFS= read -r ws_id; do
[[ -z "$ws_id" || "$ws_id" =~ ^# ]] && continue
result=$(aws workspaces describe-workspaces --workspace-ids "$ws_id" --query 'Workspaces[0].[State,WorkspaceProperties.RunningMode]' --output text)
read -r state running_mode <<< "$result"
if [[ "$ACTION" == "start" ]]; then
if [[ "$state" == "STOPPED" && ( "$running_mode" == "AUTO_STOP" || "$running_mode" == "MANUAL" ) ]]; then
echo "[OK] start target : $ws_id state=$state mode=$running_mode"
REQUESTS+=("WorkspaceId=$ws_id")
else
echo "[SKIP] start target: $ws_id state=$state mode=$running_mode"
fi
else
if [[ "$state" == "AVAILABLE" || "$state" == "UNHEALTHY" || "$state" == "REBOOTING" ]]; then
echo "[OK] reboot target : $ws_id state=$state"
REQUESTS+=("$ws_id")
else
echo "[SKIP] reboot target: $ws_id state=$state"
fi
fi
if [ "${#REQUESTS[@]}" -ge "$BATCH_SIZE" ]; then
flush_requests
fi
done < "$INPUT_FILE"
flush_requests
echo "Done."
実行例
起動したい場合は、以下のように実行します。
chmod +x workspace_bulk_action.sh
./workspace_bulk_action.sh start
再起動したい場合は、以下です。
./workspace_bulk_action.sh reboot
このスクリプトのポイント
今回のスクリプトで意識したポイントは、主に3つです。
1. 先に状態を確認していること
対象のWorkSpaceに対して、いきなり起動や再起動をかけるのではなく、まずdescribe-workspacesで状態を確認しています。
これにより、対象外のWorkSpaceは[SKIP]として流せるので、不要な失敗を減らしやすくなります。
2. 起動と再起動を分けて考えていること
WorkSpacesは、停止中なら起動、稼働中なら再起動、といったように、状態に応じて使うAPIが変わります。
ここを分けずにまとめてしまうと、後でエラーが増えやすいため、今回は引数で明確に分けています。
3. 作業対象をファイルで管理できること
対象をws_ids.txtに切り出しておくことで、
「今回どの端末を対象にしたのか」
が分かりやすくなります。
運用作業では、コマンドそのものよりも、どの対象に対して実行したかが後から追えることも意外と重要だと感じています。
まとめ
WorkSpacesの起動や再起動は、台数が増えるほどコンソール操作では少しずつ手間が大きくなります。
そのため、対象IDを一覧化し、状態確認をしてから一括実行する形にしておくと、実務ではかなり扱いやすくなります。
WorkSpacesを複数台管理している場合は、こうした一括実行の仕組みを一つ持っておくと便利だと思います。


