😊

AWS EC2接続:SSH踏み台 vs SSM性能比較 - AI活用で効率的に検証してみた

こちらは primeNumber AI Native Summer Calendarの記事です。

本日の担当は、CTO の kekekenta (@kekekenta) です。
他の記事も読みたい人は カレンダー を見てください!


実際の課題:EC2開発環境のSSM接続が遅い

背景:開発効率を阻害するSSMの遅さ

TROCCO/COMETAでは、各開発者がAWS EC2上に開発環境を構築して利用しています。セキュリティを重視してAWS SSM(AWS Systems Manager Session Manager)で接続していましたが、日常的に以下の問題に悩まされていました:

具体的な課題:

  • ファイルのアップロード・ダウンロードが遅い
  • VSCodeのRemote-SSH経由での作業でもレスポンスが悪い
  • UI表示のレスポンスが悪く、動作検証に時間がかかる
  • 開発体験にストレスを感じる場面が増加

「なんとなく遅い」から「定量的な検証」へ

疑問:

  • 本当にSSMが遅いのか?
  • SSH踏み台経由の方が速いのか?
  • どの程度の差があるのか?

この疑問を解決するため、AI活用で検証スクリプトを作成し、定量的な比較を行いました。

AI活用による性能検証

SSHとSSMの性能検証を行う場合、scpなどの転送を行うコマンドを実行してtimeコマンドで計測することをまず考えると思います。
一方で、複数回実行して集計方法を考える必要性や、SSHとSSMそれぞれの方式で動作検証を行うなど、いくつか方法を考える必要があります。
そこで、再現性を確保するためにも、簡単なBashスクリプトを書いて性能を行うことを考えました。

スクリプト作成の個人的課題

残念ながら、私はBashスクリプトを書くことが得意ではありません。
動作検証のたびに何度もコマンドを実行してエラーを修正する作業は、大変苦痛です。
たまにしか書かないことから、いつまで経っても書き方が覚えらず、毎度ネットで書き方を検索しています。

そこで、AIを活用したスクリプト作成を考えました。

AI(Claude)による0→1のスクリプト生成

今回は、以下のようなプロンプトでClaude CodeにBashスクリプトを書いてもらいました。(実際のスクリプトは記事の最後に記載)

プロンプト:

「SSH/SCPのパフォーマンステストを行うBashスクリプトを作成してください。
ホスト名は、SSHはec2-dev-through-bastion、SSMはec2-dev-through-ssmです。
10MBのファイルがEC2上に置かれているので、それをscpでDLする速度を10回計測して、外れ値を除外した平均を出したいです。」

結果:

  • 約5分で完成度の高いスクリプトが完成
  • 想定以上の機能が実装された
  • 一発でほぼ期待通りに動作

検証概要

検証環境

  • 踏み台サーバー: publicサブネットのt2.micro
  • ターゲット: privateサブネットのEC2開発環境
  • テストファイル: 10MB
  • 計測方法: 各接続方式で10回計測、外れ値(min/max)除外

回線環境

  • 回線: Down 209.35 Mbps / Up 190.78 Mbps / Latency 7.41ms

検証結果

パフォーマンステスト結果

今回の検証環境では、SSHがSSMの約3倍高速であることがわかりました

接続方式 平均レイテンシー 転送速度 性能比
SSH踏み台経由 955ms 87.8 Mbps 3.04倍高速
SSM接続 2,903ms 28.9 Mbps ベースライン

スクリプト実行例

SSH 接続のレイテンシー計測

through-bastion /tmp/10mb_test_file
Running iteration 1...
Iteration 1: Latency = 1663 ms
Running iteration 2...
Iteration 2: Latency = 914 ms
Running iteration 3...
Iteration 3: Latency = 967 ms
Running iteration 4...
Iteration 4: Latency = 912 ms
Running iteration 5...
Iteration 5: Latency = 930 ms
Running iteration 6...
Iteration 6: Latency = 1015 ms
Running iteration 7...
Iteration 7: Latency = 957 ms
Running iteration 8...
Iteration 8: Latency = 977 ms
Running iteration 9...
Iteration 9: Latency = 939 ms
Running iteration 10...
Iteration 10: Latency = 942 ms

--- SCP Latency Statistics (ms) ---
Trimmed Latencies: 914 930 939 942 957 967 977 1015
Average Latency: 955.12 ms

社内ツールとしてのBashスクリプト開発は、AIを活用すべき

社内でしか利用しないようなツールの開発は、AIにとって最高の活躍場所だと思います

プロダクト開発との違い:

  • プロダクト開発: 保守性、拡張性、長期運用を考慮した100点を目指す必要
  • 検証・分析ツール: 80点でも、目的を達成できれば十分

AIの真価:

  • 0→80点のスピードが異常に速い
  • 80→100点は時間がかかるが、検証用途なら80点で事足りる
  • 完璧を求めない割り切りが生産性を爆上げする

実際に生成されたスクリプトの完成度

Claudeが生成したスクリプトには、期待以上の機能が含まれていました:

想定していた機能:

  • SCP実行時間の計測
  • 10回の繰り返し測定
  • 平均値の計算

実際に生成された機能:

  • ✅ 依存関係の自動チェック(scp, bc, perl)
  • ✅ SSH接続の事前テスト
  • ✅ ファイル存在確認
  • ✅ 詳細な統計計算(最小値、最大値、中央値、外れ値除外平均)
  • ✅ ファイルサイズの自動取得と表示
  • ✅ 転送速度(Mbps)の自動計算
  • ✅ エラーハンドリングとタイムアウト設定
  • ✅ 進捗表示とユーザビリティ
  • ✅ 設定のカスタマイズ機能

自分で手で書いた場合はリッチな進捗表示などは絶対やらないですが、AIはこういった優先度が低いけどあったら嬉しいなということをほぼゼロコストで実現してくれる点が最高です。

2025/08時点では、80点でリリースできる領域をみつけるのがAI活用の勝ち筋

先ほど書いたように、プロダクト開発では100点に近いものが求められます。
一方で、既存プロダクトにおいてAIがそこまで持って行くのは現時点では難しいと考えています。
弊社でも、AIにすべてやらせるのではなく、80点以降は手で書いたほうが速いというのが共通見解になっています。

逆に、「80点で十分」という割り切りができる領域こそが、AI活用の最大の価値だと感じます。
その一つが社内ツールです。
弊社でも、こういったBashスクリプト以外にも、社内向けのChrome拡張などをVibe Codingで開発する事例がいくつか出てきています。

また、データ分析においても80点で十分という領域は存在します。
Jupyter NotebookのPythonコードがその一つです。
私自身、直近はプロダクトのデータ分析をColabとGemini使って進めております。
pundasを使ったコードを書くのが苦手だったのですが(たまにしか書かない言語は本当に苦手)、Colab上でGeminiに対して分析のゴールを伝えるとPythonコードを生成してくれて、分析の要件さえ満たせればいいので80点でもほぼ修正無しで分析が行えます。
分析自体は100点である必要がありますが、そのために生成されるコードは要件さえ満たしていれば良く、80点で十分です。
たまにユニークするべきところを考慮していなかったりするので、集計方法について指摘する程度で、コードについて指摘することはほぼありません。

最終的な解決策:Tailscaleへの移行

検証結果を受けての決断

パフォーマンステストの結果、SSH踏み台がSSMより1.7〜3.0倍高速であることが判明しました。しかし、踏み台サーバーの運用にも課題がありました:

SSH踏み台の課題:

  • 踏み台サーバーの維持管理コスト
  • セキュリティグループの複雑な設定
  • 踏み台サーバーの可用性管理
  • インスタンス料金(小額だが継続的)

Tailscaleという第三の選択肢

検証の過程で、より良い解決策としてTailscaleに辿り着きました:

Tailscaleの利点:

  • 高速: SSH踏み台並みの性能
  • セキュア: End-to-Endの暗号化
  • シンプル: 踏み台サーバー不要
  • コスト効率: 個人利用は無料
  • 管理簡単: GUIでのデバイス管理

移行後の体感

パフォーマンス:

  • SSM接続時の「もどかしさ」が完全に解消
  • ローカル開発とほぼ同等の体感速度
  • 大容量ファイルの転送もストレスフリー

運用面:

  • 踏み台サーバーの廃止によるコスト削減
  • セキュリティグループ設定の簡素化
  • 接続の安定性向上

私の分析結果をもとに、プロダクトSREのチームがさらなる再現検証と、導入の決定、エンジニア全員へのTailscale展開を短期間で進めてくれました。運用フローも整備されており、新しく入った方もすぐにTailscaleでEC2開発環境に接続できるようになっています。

これまでSSMで苦労してきたエンジニアからも、大絶賛です。

まとめ

AIを活用した技術検証は、インフラ運用の様々な場面で威力を発揮します。「面倒だから後回し」にしていた検証作業も、AIの力を借りれば手軽に実行できる時代になりました。

皆さんも日常の「なんとなく遅い」「なんとなく使いにくい」を、AIを活用して定量的に検証してみてはいかがでしょうか?思わぬ改善点や最適解が見つかるかもしれません。


付録: 検証用スクリプト

#!/bin/bash

# 使用例:
# $ bash ssh-vs-ssm-performance-test.sh ec2-dev-through-bastion /path/to/remote/file

# 引数のチェック
if [ $# -lt 2 ]; then
    echo "Usage: $0 <SSH_HOST> <REMOTE_FILE>"
    exit 10
fi


# 設定
SSH_HOST="$1"
REMOTE_FILE="$2"  # リモートファイルのパス
LOCAL_PATH="/tmp/performance_test"          # ローカルに保存するパス
ITERATIONS=10                          # 計測回数

# レイテンシーを記録する配列
latencies=()

# 現在時刻をミリ秒単位で取得する関数(perlを使用)
get_timestamp_ms() {
    perl -MTime::HiRes=time -e 'printf("%.0f\n", time * 1000)'
}

# scpを10回実行して時間を計測
for ((i=1; i<=ITERATIONS; i++)); do
    echo "Running iteration $i..."
    start_time=$(get_timestamp_ms)  # 開始時間をミリ秒単位で記録
    scp "${SSH_HOST}:${REMOTE_FILE}" "${LOCAL_PATH}" > /dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "Error during SCP on iteration $i"
        continue
    fi
    end_time=$(get_timestamp_ms)  # 終了時間をミリ秒単位で記録
    latency=$((end_time - start_time))
    echo "Iteration $i: Latency = ${latency} ms"
    latencies+=("$latency")
done

# 統計を計算
if [ ${#latencies[@]} -gt 2 ]; then
    # 配列をソート
    sorted_latencies=($(printf '%s\n' "${latencies[@]}" | sort -n))

    # 外れ値(minとmax)を除外
    trimmed_latencies=("${sorted_latencies[@]:1:${#sorted_latencies[@]}-2}")

    # 平均値を計算
    total=0
    for latency in "${trimmed_latencies[@]}"; do
        total=$(echo "$total + $latency" | bc)
    done
    avg_latency=$(echo "scale=2; $total / ${#trimmed_latencies[@]}" | bc)

    # 結果を表示
    echo ""
    echo "--- SCP Latency Statistics (ms) ---"
    echo "Trimmed Latencies: ${trimmed_latencies[*]}"
    echo "Average Latency: $avg_latency ms"
else
    echo "Not enough data to calculate statistics (need more than 2 successful transfers)."
fi
株式会社primeNumber

Discussion