🧭

aws ssmで接続先のインスタンスIDを迷わないために

2024/05/28に公開

はじめに

AWS SSMでEC2インスタンスに接続する際,インスタンスIDを指定しなければなりませんが,いつもインスタンスIDがわからなくなります.
過去の実行コマンドをhistoryから呼び出していましたが,複数のインスタンスに接続することがあると,意図しないインスタンスに接続してしまうこともしばしばです.
もっとわかりやすい方法で迷わずに接続できるよう,.zshrcに関数を定義することにしました.

方法

そもそもインスタンスIDのようなランダムな数値を入力するのがミスの元で,覚えるのは不可能です.
そこで,インスタンスIDの入力を必要としないコマンドを定義します.

前提

  • aws-vaultを使用
  • fzfがインストールされていること

前提

  • aws-vaultを使用
  • fzfがインストールされていること

.zshrcに関数を定義

.zshrcに以下の関数を定義しました.

# インスタンスを選択してssmセッションを開始する
function start-ssm-session() {
    local profile_name=$1
    local instance_id=$2

    # プロファイル一覧を選択する関数
    function select_profile() {
        local profiles=$(aws-vault list | awk '{print $1}' | tail -n +2 | fzf --prompt="Select profile: " --height=20% --reverse)
        echo $profiles
    }

    # プロファイル名が指定されていない場合は選択
    if [[ -z "$profile_name" ]]; then
        profile_name=$(select_profile)
        if [[ -z "$profile_name" ]]; then
            echo "No profile selected"
            return 1
        fi
    fi

    if [[ -z "$profile_name" ]]; then
        echo "Usage: start_ssm_session <profile-name> [instance-id]"
        return 1
    fi

    if [[ -z "$instance_id" ]]; then
        # EC2 インスタンスの情報を取得して fzf で選択
        local instance=$(aws-vault exec $profile_name -- aws ec2 describe-instances \
            --query 'Reservations[*].Instances[*].[InstanceId, Tags[?Key==`Name`].Value | [0]]' \
            --output text | fzf --prompt="Select instance: " --height=20% --reverse)

        # インスタンスIDを抽出
        instance_id=$(echo $instance | awk '{print $1}')
    fi

    if [[ -n "$instance_id" ]]; then
        echo "Starting SSM session with instance ID: $instance_id"
        aws-vault exec $profile_name -- aws ssm start-session --target $instance_id
    else
        echo "No instance selected"
    fi

    unset select_profile
}

各処理が何をしているのかを見ていきます.

まず,aws-vaultのプロファイル取得処理です.
実行時引数にプロファイルが渡されなかった場合はaws-vault listを実行して設定されているプロファイル一覧を取得し,結果をfzfに渡すことで検索と選択をできるようにしています.

    # プロファイル一覧を選択する関数
    function select_profile() {
        local profiles=$(aws-vault list | awk '{print $1}' | tail -n +2 | fzf --prompt="Select profile: " --height=20% --reverse)
        echo $profiles
    }

    # プロファイル名が指定されていない場合は選択
    if [[ -z "$profile_name" ]]; then
        profile_name=$(select_profile)
        if [[ -z "$profile_name" ]]; then
            echo "No profile selected"
            return 1
        fi
    fi

次にEC2インスタンスIDの取得です.
aws ec2 describe-instancesを実行して接続可能なEC2インスタンス一覧の情報を取得します.
取得した情報のインスタンスIDとインスタンス名をfzfに渡し,こちらも検索と選択をできるようにしています.

    if [[ -z "$instance_id" ]]; then
        # EC2 インスタンスの情報を取得して fzf で選択
        local instance=$(aws-vault exec $profile_name -- aws ec2 describe-instances \
            --query 'Reservations[*].Instances[*].[InstanceId, Tags[?Key==`Name`].Value | [0]]' \
            --output text | fzf --prompt="Select instance: " --height=20% --reverse)

        # インスタンスIDを抽出
        instance_id=$(echo $instance | awk '{print $1}')
    fi

最後にaws ssm start-sessionを実行してSSM接続します.

    if [[ -n "$instance_id" ]]; then
        echo "Starting SSM session with instance ID: $instance_id"
        aws-vault exec $profile_name -- aws ssm start-session --target $instance_id
    else
        echo "No instance selected"
    fi

使用方法

Usage: start-ssm-session [profile-name [instance-id]]

具体的な例:

$ start-ssm-session
$ start-ssm-session your-profile-name
$ start-ssm-session your-profile-name your-instance-id

profile-nameinstance-idはオプションです.
profile-nameの指定がなければプロファイル一覧が表示され,選択できます.
instance-idの指定がなければ,profile-nameに設定されているロールでアクセス可能なインスタンス一覧が表示され,選択できます.

実際の使用例は以下のようになります.
インスタンスIDとインスタンス名が表示されています.

結果

SSM接続が楽になりました!

Discussion