はじめに
- ケチなので、EC2を使い終わるたびにインスタンスを停止しておきたい。が、マネジメントコンソールから毎回ポチポチするのは面倒。
- AWS EC2 は、停止→再起動するとグローバルIP(とFQDN)が変動する仕様のため、次回接続時にいちいちマクロを書き換えるのも面倒。
ということで、AWS CLIを使って、以下をできるようにしたい。windows環境のためpowershellでの実行を前提とする。
- EC2 インスタンスの一覧取得・起動・停止
- 特定のタグ(
my-ec2
)を持つEC2にアクセス
AWS CLIの導入
以下の記事を参照。
https://udemy.benesse.co.jp/development/system/aws-cli.html
EC2 インスタンスの一覧取得・起動・停止
一覧取得
- aws cliでEC2インスタンスの一覧を取得し、jqで
InstanceID
,PublicDnsName
,State
,Tags
の情報のみ抜き出す。 - 【注】powershellでjqを利用する場合、
"
にエスケープ(\"
)をつけておかないとjqのコンパイルが通らないことに注意。
describe-instances.ps1
aws ec2 describe-instances | jq '.Reservations[].Instances[] | {InstanceId:.InstanceId, PublicDnsName:.PublicDnsName, State:.State.Name, Tags:.Tags[]|select (.Key == \"Name\")|.Value}' -C
PS > describe-instances.ps1
{
"InstanceId": "i-070cf1a9d8241xxxx",
"PublicDnsName": "ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
"State": "running",
"Tags": "my-ec2"
}
{
"InstanceId": "i-08fb1aa857e70xxxx",
"PublicDnsName": "",
"State": "terminated",
"Tags": "test-tobedestracted"
}
起動
-
コマンドが覚えられないため自分用に以下ラッパーを作成。 - インスタンスIDを指定して起動。
- すでにマネジメントコンソールで一度作成済みのインスタンスを想定。
start-instance.ps1
$instance_id = $Args[0]
aws ec2 start-instances --instance-ids $instance_id
PS > .\start-instance.ps1 i-070cf1a9d8241xxxx
i-070cf1a9d824128ab
{
"StartingInstances": [
{
"CurrentState": {
"Code": 0,
"Name": "pending"
},
"InstanceId": "i-070cf1a9d8241xxxx",
"PreviousState": {
"Code": 80,
"Name": "stopped"
}
}
]
}
停止
stop-instance.ps1
$instance_id = $Args[0]
aws ec2 stop-instances --instance-ids $instance_id
PS > .\stop-instance.ps1 i-070cf1a9d8241xxxx
{ {
"StoppingInstances": [
{
"CurrentState": {
"Code": 64,
"Name": "stopping"
},
"InstanceId": "i-070cf1a9d8241xxxx",
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}
特定のタグを持つEC2にアクセス
- 本題。
- 特定のタグ(→
my-ec2
)を持つEC2にアクセスする。
ssh-ec2.ps1
# 各EC2の情報を取得。aws cliでEC2インスタンスの一覧を取得し、jqで`InstanceID`, `PublicDnsName`, `State`, `Tags`の情報のみ抜き出す。
$ec2_status= aws ec2 describe-instances | jq '[.Reservations[].Instances[] | {InstanceId:.InstanceId, PublicDnsName:.PublicDnsName, State:.State.Name, Tags:.Tags[]|select (.Key == \"Name\")|.Value}]'
# 各EC2の状態を画面にも表示
echo $ec2_status | jq '.' -C
# EC2の数を数える
$existing_instances_count = $($ec2_status | jq '[.[]| select(.State == \"running\" )] | length')
# 普段1インスタンスしか利用していないため、念のためそうでない場合は通知
If($existing_instances_count -eq 0){
echo "no running instance exists"
return 0
} elseif ($existing_instances_count -ge 2){
$output = $existing_instances_count + " running instances exist... is it ok?"
echo $output
}
# my-ec2のタグを持つEC2の`PublicDNSName`を取得。(一つしか存在しない前提)
$PublicDnsName = $($ec2_status | jq -r '.[] | select(.Tags == \"my-ec2\") | .PublicDnsName')
$output = "connect to " + $PublicDnsName
echo $output
Read-Host "Press Enter to continue..."
# my-ec2のタグを持つEC2にsshで接続
ssh ec2-user@$PublicDnsName -i "key.pem"
おわりに
時々runningのインスタンスがいないかチェックして、通知できると捗りそうだが、そのぐらいの機能はAWSの機能としてありそう・・・