サイトアイコン 協栄情報ブログ

複数のAWS WorkSpacesをCloudShellでまとめて作成する方法

こんにちは、石川です。
今回は、AWS WorkSpacesをCloudShellで自動作成する手順を紹介します。

はじめに

WorkSpacesを運用していると、新規利用者の追加や検証環境の準備などで、複数のWorkSpacesをまとめて作成したい場面があります。
ただし、AWSマネジメントコンソールから1台ずつ手動で作成する方法では、入力ミスや設定漏れが発生しやすく、件数が増えるほど作業負荷も大きくなります。

本記事では、CloudShellとAWS CLIを活用し、WorkSpacesを自動で作成する方法を紹介します。

第1章:手動作成の限界

WorkSpacesを1台ずつ手動で作成する場合、ユーザー名、バンドル、ディレクトリ、実行モードなど、複数の項目を都度確認しながら設定する必要があります。
少数であれば対応可能ですが、対象が増えると設定ミスや作成漏れのリスクが高まります。

また、同じ条件で複数台を払い出したい場合でも、GUI操作では同じ内容を何度も繰り返すことになり、作業時間がかかります。
特に、検証環境の準備や利用者追加が重なるタイミングでは、自動化による効率化が有効です。

この課題を解決するために、CloudShell上で安全にWorkSpacesを自動作成できるスクリプトを準備しました。

第2章:CloudShellで自動作成する仕組み

今回のスクリプトのポイントは、作成対象を事前に整理したうえで、CloudShellからAWS CLIでWorkSpacesを作成する設計です。

WorkSpacesの作成は、ユーザーや設定値を誤ると、そのまま不要な端末払い出しや再作成対応につながる可能性があります。
そのため、事前に対象ユーザーや必要なパラメータを整理し、スクリプトからまとめて実行する形にしています。

なお、スクリプトは以下のような仕組みで動作します:

CloudShellはAWS CLIが標準で利用できるため、ローカル端末に特別な環境を準備しなくても、そのまま作業を開始できます。
IAM権限が適切に付与されていれば、すぐに実行できる点もメリットです。

第3章:スクリプト例(安全に自動作成)

ここでは、実際に使用しているスクリプトの流れを紹介します。
CloudShell上で対象情報を準備し、WorkSpacesを自動作成する構成になっています。

手順1. CloudShellを起動

まず、AWSマネジメントコンソールからCloudShellを起動します。
CloudShell上で作業することで、ローカル環境にAWS CLIをインストールしていなくても、そのまま実行可能です。

手順2. 対象情報を準備

作成対象となるユーザー情報や、WorkSpaces作成時に必要な設定値を整理したファイルを用意します。
ここで指定した内容をもとに、自動でWorkSpacesを払い出します。

nano workspaces_users.txt


ishikawa
yamada

手順3. スクリプトを作成

続いて、WorkSpacesを自動作成するスクリプトをCloudShell上に作成します。

nano create_check_workspaces.sh
#!/bin/bash

user_list="workspaces_users.txt" #テキストファイルにユーザネームを記載
DIRECTORY_ID="d-xxxxxxx" #ディレクトリIDを記載
BUNDLE_ID="wsb-xxxxx" #バンドルIDを記載
KMS_KEY_ALIAS="arn:aws:kms:ap-northeast-1:xxxxx" #KMSキーを記載

if [ ! -f "$user_list" ]; then
  echo "Error: File $user_list not found!"
  exit 1
fi

echo "=== WorkSpaces の作成を開始 ==="

declare -A created_workspaces
declare -A existing_workspaces
declare -A failed_workspaces

while IFS= read -r username; do
  if [ -n "$username" ]; then
    echo "Checking if WorkSpace already exists for user: $username"

    # WorkSpace が既に存在するかチェック
    workspace_id=$(aws workspaces describe-workspaces --directory-id "$DIRECTORY_ID" --query "Workspaces[?UserName=='$username'].WorkspaceId" --output text)

    if [[ -n "$workspace_id" && "$workspace_id" != "None" ]]; then
      echo "✅ WorkSpace already exists: $workspace_id for $username"
      existing_workspaces["$workspace_id"]="$username"
      continue
    fi

    echo "Creating WorkSpace for user: $username"

    # WorkSpaces の作成リクエスト
    workspace_id=$(aws workspaces create-workspaces --workspaces "[{
        \"DirectoryId\": \"$DIRECTORY_ID\",
        \"UserName\": \"$username\",
        \"BundleId\": \"$BUNDLE_ID\",
        \"WorkspaceProperties\": {
          \"RunningMode\": \"AUTO_STOP\",
          \"RunningModeAutoStopTimeoutInMinutes\": 120,
          \"RootVolumeSizeGib\": 80,
          \"UserVolumeSizeGib\": 10
        },
        \"Tags\": [{ \"Key\": \"Cost\", \"Value\": \"CommonOpe\" }],
        \"RootVolumeEncryptionEnabled\": true,
        \"UserVolumeEncryptionEnabled\": true,
        \"VolumeEncryptionKey\": \"$KMS_KEY_ALIAS\"
      }]" --query "Workspaces[0].WorkspaceId" --output text 2>&1)

    # エラーチェック
    if [[ $? -ne 0 ]]; then
      echo "❌ WorkSpace creation failed for: $username"
      echo "Error: $workspace_id"
      failed_workspaces["$username"]="FAILED"
      continue
    fi

    # WorkSpace ID の再取得(Noneの場合のみ再試行)
    if [[ -z "$workspace_id" || "$workspace_id" == "None" ]]; then
      workspace_id=$(aws workspaces describe-workspaces --directory-id "$DIRECTORY_ID" --query "Workspaces[?UserName=='$username'].WorkspaceId" --output text)

      if [[ -z "$workspace_id" || "$workspace_id" == "None" ]]; then
        echo "⚠️ WorkSpace ID が取得できなかったため、5 秒後に再試行"
        sleep 5
        workspace_id=$(aws workspaces describe-workspaces --directory-id "$DIRECTORY_ID" --query "Workspaces[?UserName=='$username'].WorkspaceId" --output text)
      fi
    fi

    if [[ -n "$workspace_id" && "$workspace_id" != "None" ]]; then
      echo "✅ WorkSpace created: $workspace_id for $username"
      created_workspaces["$workspace_id"]="$username"
    else
      echo "❌ WorkSpace creation failed for: $username"
      failed_workspaces["$username"]="FAILED"
    fi

    sleep $(awk -v min=0.4 -v max=0.6 'BEGIN{srand(); print min+rand()*(max-min)}')
  fi
done < "$user_list"

echo "=== WorkSpaces の作成を開始しました!: $(date) ==="

# ステータス確認のため、最大 30 分待機
max_wait_time=3600  # 60 分(秒)
interval=180  # 3 分ごとにチェック
elapsed_time=0

echo "=== WorkSpaces のステータスが AVAILABLE になるまでチェックを開始 ==="

while [ "$elapsed_time" -lt "$max_wait_time" ]; do
  echo "Checking WorkSpaces status... (Elapsed: $elapsed_time sec)"

  all_done=true
  for workspace_id in "${!created_workspaces[@]}"; do
    status=$(aws workspaces describe-workspaces --workspace-ids "$workspace_id" --query "Workspaces[0].State" --output text)

    if [[ "$status" != "AVAILABLE" && "$status" != "FAILED" ]]; then
      all_done=false
    fi

    if [[ "$status" == "FAILED" ]]; then
      echo "❌ WorkSpace ID: $workspace_id - Status: FAILED"
      failed_workspaces["${created_workspaces[$workspace_id]}"]="FAILED"
      unset created_workspaces["$workspace_id"]
    else
      echo "✅ WorkSpace ID: $workspace_id - Status: $status"
    fi
  done

  if [ "$all_done" = true ]; then
    echo "All WorkSpaces are AVAILABLE or FAILED. Proceeding with final status check."
    break
  fi

  sleep "$interval"
  ((elapsed_time+=interval))
done

# WorkSpaces の最終ステータス確認
echo "=== WorkSpaces の最終ステータス確認 ==="
echo "-----------------------------------------------------------------------------------------------------------------"
echo "| User          | WorkSpace ID      | Computer Name  | Cost Tag  | Bundle ID  | Bundle Name          | Status  |"
echo "-----------------------------------------------------------------------------------------------------------------"

# **バンドルIDとバンドル名のマッピングを取得**
declare -A bundle_names
while IFS=$'\t' read -r bundle_id bundle_name; do
  bundle_names["$bundle_id"]="$bundle_name"
done < <(aws workspaces describe-workspace-bundles --query "Bundles[*].[BundleId, Name]" --output text)

# **作成した WorkSpaces + 既存の WorkSpaces の最終ステータスを確認**
for workspace_id in "${!created_workspaces[@]}" "${!existing_workspaces[@]}"; do
  username="${created_workspaces[$workspace_id]:-${existing_workspaces[$workspace_id]}}"

  workspace_info=$(aws workspaces describe-workspaces --workspace-ids "$workspace_id" \
    --query "Workspaces[0].[WorkspaceId, ComputerName, BundleId, State]" --output text)

  if [ -n "$workspace_info" ]; then
    computer_name=$(echo "$workspace_info" | awk '{print $2}')
    bundle_id=$(echo "$workspace_info" | awk '{print $3}')
    status=$(echo "$workspace_info" | awk '{print $4}')

    cost_tag=$(aws workspaces describe-tags --resource-id "$workspace_id" \
      --query "TagList[?Key=='Cost'].Value" --output text 2>/dev/null)
    if [[ $? -ne 0 || -z "$cost_tag" ]]; then
      cost_tag="N/A"
    fi

    bundle_name="${bundle_names[$bundle_id]}"
    if [ -z "$bundle_name" ]; then
      bundle_name="Unknown"
    fi

    printf "| %-12s | %-16s | %-14s | %-8s | %-10s | %-20s | %-7s |\n" \
      "$username" "$workspace_id" "$computer_name" "$cost_tag" "$bundle_id" "$bundle_name" "$status"
  else
    echo "| $username | No WorkSpace found |"
  fi
done

echo "--------------------------------------------------------------------------------------------------------"

# **失敗した WorkSpaces のリスト表示**
if [ ${#failed_workspaces[@]} -gt 0 ]; then
  echo "=== ❌ 作成に失敗した WorkSpaces ==="
  for user in "${!failed_workspaces[@]}"; do
    echo "❌ $user - FAILED"
  done
else
  echo "✅ 作成失敗した WorkSpaces はありません。全て作成に成功しています! 🎉"
fi

echo "--------------------------------------------------------------------------------------------------------"
echo "=== WorkSpaces の作成と確認が完了しました: $(date) ==="

手順4. 実行権限を付与

作成したスクリプトに対して、実行権限を付与します。

chmod +x create_check_workspaces.sh

手順5. スクリプトを実行

準備ができたら、CloudShell上でスクリプトを実行します。

./create_check_workspaces.sh

実行後は、CloudShellの出力結果を確認することで、処理が正常に行われたかを把握できます。
必要に応じて、作成後のWorkSpaces情報をCLIで確認し、対象ユーザーに正しく払い出されているかを確認します。

最後に

以上、CloudShellを活用してWorkSpacesを自動作成する方法の紹介でした。
WorkSpacesの作成を手動で行う場合、件数が増えるほど作業負荷とミスのリスクが高くなりますが、CLIスクリプトで自動化することで、安全かつ効率的に対応できるようになります。

特に、複数ユーザーへの一括払い出しや、定型的な作成作業が多い環境では、自動化の効果が大きいです。
ぜひ、ご自身の環境に合わせて活用してみてください。

モバイルバージョンを終了