はじめに
AWSのEC2の料金削減を目的としたスクリプトです。業務利用よりも個人での利用を想定しています。
多くの方が、料金削減のためにEC2を必要なタイミングでのみ起動し、不要なタイミングではシャットダウンするということをされているかと思いますが、
その場合ssh接続する際にAWSコンソール画面などから手動で起動する作業が必要となるかと思います。
また、local環境からssh接続するためには、Global IPを指定する必要があります。Elastic IP(EIP)を付与することで、毎回同じGlobal IPを指定してssh接続が可能となりますが、AWSではEIPはインスタンス停止中にも料金が発生するという課題があります。
この問題を解決するために、EIPを付与せずに動的にGlobal IPが付与されるEC2インスタンスに対して、
AWSコンソール画面を使わずにCLIで起動→ssh接続まで一貫して行うスクリプトを作成しました。
前提
- EC2にEIPが付与されていないこと
- ※付与されていてもこのスクリプトは動作しますが、冗長です
- AWS CLIが導入済みであること
- EC2にssh接続するためのキーペア(秘密鍵、pemファイルなど)が用意されていること
解決方法
以下の処理の流れのスクリプトを作成しました。
- インスタンスIDを指定して、現在のインスタンス起動状態を取得し、未起動であればEC2を起動する。
- 起動状態になったらグローバルIPを取得する
- 取得したグローバルIPとキーペアを用いて、ssh接続する。
作成したBashのスクリプト
#!/bin/bash
set -euxo pipefail
# コマンドライン引数からインスタンスID、キーペアを取得
INSTANCE_ID="$1"
KEY_PAIR="$2"
# インスタンスの状態を取得
state=$(aws ec2 describe-instances \
--instance-ids "${INSTANCE_ID}" \
--query 'Reservations[0].Instances[0].State.Name' \
--output text)
# インスタンスが起動していない場合は起動する
if [[ "${state}" != "running" ]]; then
echo "Starting EC2 instance..."
aws ec2 start-instances --instance-ids "${INSTANCE_ID}" >/dev/null
fi
# インスタンスが起動するまで待機する
echo "Waiting for EC2 instance to start..."
aws ec2 wait instance-running --instance-ids "${INSTANCE_ID}"
# グローバルIPアドレスを取得する
GLOBAL_IP=$(aws ec2 describe-instances \
--instance-ids "${INSTANCE_ID}" \
--query 'Reservations[0].Instances[0].PublicIpAddress' \
--output text)
# ssh接続を試行する
echo "Connecting to EC2 instance..."
ssh -i "${KEY_PAIR}" ec2-user@"${GLOBAL_IP}"
使い方
以下のように引数を指定します。
- 第一引数:EC2のインスタンスID (ex.
i-1234567890abcd
) - 第二引数:キーペア(pemファイルなど)のパス (ex.
~/.ssh/hogehoge.pem
)
実行コマンドサンプル
./start-and-ssh-ec2.sh i-1234567890abcd ~/.ssh/hogehoge.pem
結論
以上のようなスクリプトを作成することで、EC2インスタンスの起動とssh接続を自動化し、コンソール画面からの操作を省略することができます。
特にEIPを付与せずにGIPを動的に付与する場合には、インスタンス停止中の料金課題も回避することができます。
(実際にいくら削減できるか?というところまでは未計算ですが...)
また、本スクリプトをaliasに登録するなどして、利用の手間を更に軽減させることができます。
最終行の ssh -i "${KEY_PAIR}" ec2-user@"${GLOBAL_IP}"
はログインユーザー名をハードコードしていますが、必要に応じて書き換えたり、こちらもコマンドライン引数として扱っても良いかもしれません。
実際に利用する際は、EC2インスタンスをシャットダウンするためのスクリプトを作成し、併せて利用するのが便利そうですね。