💣
使い捨ての EC2 インスタンスをコマンド一つで起動する
動作確認や、あのオプションFreeBSDだと使えたんだっけとか、一瞬だけまっさらな環境が欲しくなることは割と良くあるので、スクリプト一つで起動から終了(削除)まで一気通貫でできるようにしてみました。
下記スクリプトを実行すると、インスタンスを起動し、SSHログインします。SSHをexitするとインスタンスを終了します。
スクリプト実行前の準備として、以下が必要です:
- aws cli がインストールされていること
- aws cli から EC2 ホストを作成できる状態になっていること
セキュリティグループやSSH鍵は都度使い捨てのものを登録するので、これら以外の準備は不要です。
REGION, ARCH/TYPE, AMI_NAME/AMI_OWNER だけいじれば良いはずです。
onetime-ec2.sh
#!/bin/bash
REGION=ap-northeast-1
ARCH=x86_64
TYPE=t2.micro
#ARCH=arm64
#TYPE=t4g.micro
AMI_NAME='amzn2-ami-hvm-2.0*'
AMI_OWNER=amazon
#AMI_NAME='FreeBSD 12*'
#AMI_OWNER=782442783595 # FreeBSD releng アカウントらしい。marketplaceのはsubscribe操作が必要なのでこちらを使う
random=$(ruby -e "print (0...16).map{ ('a'..'z').to_a[rand(26)] }.join")
keyname=onetime-ec2_$random
secgroup=onetime-ec2_$random
workdir=$(mktemp -d)
sshkey=$workdir/ssh.pem
trap atexit EXIT
atexit() {
read -n1 -p "インスタンスを削除しますか? (y/N):" yn
case "$yn" in
[yY])
echo
# インスタンスに関連付けられているセキュリティグループは
# 削除できないので、default に付け替えておく
secid=$(aws ec2 describe-security-groups --group-names default \
| jq -r .SecurityGroups[0].GroupId)
aws ec2 modify-instance-attribute --instance-id $instance_id --groups $secid
status=$(aws ec2 terminate-instances --instance-ids $instance_id \
| jq -r .TerminatingInstances[0].CurrentState.Name
)
echo 終了リクエストを送信しました。現在のステータス:$status
aws ec2 delete-key-pair --key-name $keyname
aws ec2 delete-security-group --group-id $secgroup_id
;;
*)
echo
echo インスタンスは起動したままなので、適宜削除してください
echo ssh鍵は $sshkey にあります
echo "aws ec2 terminate-instances --instance-ids $instance_id"
echo "aws ec2 delete-key-pair --key-name $keyname"
echo "aws ec2 delete-security-group --group-id $secgroup_id"
;;
esac
}
echo -n セキュリティグループを作成します...
my_ip=$(curl --silent https://checkip.amazonaws.com)
secgroup_id=$(aws ec2 create-security-group --group-name $secgroup \
--description "created by $0" \
| jq -r .GroupId)
aws ec2 authorize-security-group-ingress --group-id $secgroup_id \
--protocol tcp --port 22 --cidr $my_ip/32 > /dev/null
echo "done: $secgroup_id"
echo -n キーペアを作成します...
aws ec2 create-key-pair --key-name $keyname --query KeyMaterial --output text > $sshkey
chmod 400 $sshkey
echo done
# Image ID を取得する
#image_id=$(aws ec2 describe-images --region $REGION \
# --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-$ARCH-gp2" \
# --query 'reverse(sort_by(Images, &CreationDate))[0]' \
# --owners amazon \
# --output json | jq -r .ImageId)
#image_id=$(aws ec2 describe-images --region $REGION \
# --filters "Name=name,Values=FreeBSD 12*" "Name=architecture,Values=$ARCH" \
# --query 'reverse(sort_by(Images, &CreationDate))[0]' \
# --output json | jq -r .ImageId)
image_id=$(aws ec2 describe-images --region $REGION \
--filters "Name=name,Values=$AMI_NAME" "Name=architecture,Values=$ARCH" \
--query 'reverse(sort_by(Images, &CreationDate))[0]' \
--owners $AMI_OWNER \
--output json | jq -r .ImageId)
echo -n インスタンスを起動します
instance_id=$(aws ec2 run-instances --image-id $image_id \
--count 1 \
--instance-type $TYPE \
--key-name $keyname \
--security-group-ids $secgroup_id | jq -r .Instances[0].InstanceId)
# 起動するまで10分ほど待つ
for i in $(seq 1 30); do
state=$(aws ec2 describe-instances --instance-id $instance_id \
| jq -r .Reservations[0].Instances[0].State.Name)
if [ x"$state" = x"running" ]; then
break
fi
echo -n .
sleep 5
done
if [ $i -eq 30 ]; then
echo インスタンスの起動に失敗したぽい。
echo 適宜後片付けしてください:
echo "aws ec2 terminate-instances --instance-ids $instance_id"
exit 1
fi
echo done: $instance_id
dns_name=$(aws ec2 describe-instances --instance-id $instance_id \
| jq -r .Reservations[0].Instances[0].PublicDnsName)
echo $dns_name に接続します
# sshd が起動していないことがあるので、何回かリトライする
# known_hosts を汚さないよう /dev/null を使う
for i in $(seq 1 15); do
ssh $dns_name \
-l ec2-user -i $sshkey \
-o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no && break
sleep 5
done
実行結果:
$ ./onetime-ec2.sh
セキュリティグループを作成します...done: sg-024b79bd374d4a1e4
キーペアを作成します...done
インスタンスを起動します......done: i-0ae62a5d67d458535
ec2-18-182-34-84.ap-northeast-1.compute.amazonaws.com に接続します
ssh: connect to host ec2-18-182-34-84.ap-northeast-1.compute.amazonaws.com port 22: Connection refused
Warning: Permanently added 'ec2-18-182-34-84.ap-northeast-1.compute.amazonaws.com,18.182.34.84' (ECDSA) to the list of known hosts.
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|
https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-31-9-124 ~]$ exit
ログアウト
Connection to ec2-18-182-34-84.ap-northeast-1.compute.amazonaws.com closed.
インスタンスを削除しますか? (y/N):y
終了リクエストを送信しました。現在のステータス:shutting-down
Discussion