AWS CLI で複数の EC2 インスタンスをまとめて起動・停止する
2020-10-15前回の JAWS-UG CLI 専門支部で、シェルの for 文と AWS CLI コマンドを組み合わせた操作があったので、同じパターンを使って複数の EC2 インスタンスを起動・停止してみます。
目次
概要
AWS CLI を使って複数の EC2 インスタンスを起動・停止します。 “複数の” というのは、今回は “特定のタグキーと値を持つ EC2 インスタンス” ということにします。
使用する AWS CLI のバージョンは、現時点 (2020/10/15) で最新の 2.0.56
です。
$ aws --version
aws-cli/2.0.56 Python/3.7.4 Darwin/19.6.0 exe/x86_64
やってみる
早速やってみます。手順としては、まず特定のタグキーと値を持つ EC2 インスタンスを複数準備して、その後 まとめて起動と停止を実施します。
EC2 インスタンスの作成
EC2 インスタンスの作成には、 ec2 run-instances
コマンドを使います。 今回 “特定のタグキーと値” として指定するのは StartStopByCLI
というタグキーと TRUE
という値とします。
AMI イメージは Amazon Linux 2 を指定するので、最新のイメージ ID を取得します。
$ EC2_IMAGE_ID=$(aws ec2 describe-images \
--owners amazon \
--filters 'Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2' \
--query 'reverse(sort_by(Images,&CreationDate))[1].ImageId' \
--output text) \
&& echo ${EC2_IMAGE_ID}
ami-0053d11f74e9e7f52
ami-0053d11f74e9e7f52
という AMI イメージ ID が取得できました。この AMI イメージで複数の EC2 インスタンスを作成します。
インスタンスタイプは、時間あたりのコストが低い t3a.nano
を指定します。
$ EC2_INSTANCE_TYPE="t3a.nano"
タグで指定する文字列もあらかじめ変数に保持しておきます。
$ RESOURCE_TAG_SPEC="ResourceType=instance,Tags=[{Key=StartStopByCLI,Value=TRUE}]"
これらの条件で、 3 つのインスタンスを作成してみます。
$ aws ec2 run-instances \
--image-id ${EC2_IMAGE_ID} \
--instance-type ${EC2_INSTANCE_TYPE} \
--tag-specifications ${RESOURCE_TAG_SPEC} \
--count 3
ステータスを確認します。
$ aws ec2 describe-instances \
--filters Name=tag-key,Values=StartStopByCLI Name=tag-value,Values=TRUE \
--query 'Reservations[*].Instances[].{InstanceID:InstanceId,Status:State.Name}'
[
{
"InstanceID": "i-0a7f9d2965a2177f6",
"Status": "running"
},
{
"InstanceID": "i-044041fb5a5d40623",
"Status": "running"
},
{
"InstanceID": "i-0d2ab038f784f9156",
"Status": "running"
}
]
これで対象のインスタンスが作成できました。ちなみに、それ以外のインスタンスも含めてステータスを確認してみると、
$ aws ec2 describe-instances \
--query 'Reservations[*].Instances[].{InstanceID:InstanceId,Status:State.Name,LaunchTime:LaunchTime}'
[
{
"InstanceID": "i-0539ee02588c12499",
"Status": "stopped",
"LaunchTime": "2020-09-10T09:03:47+00:00"
},
{
"InstanceID": "i-0a7f9d2965a2177f6",
"Status": "running",
"LaunchTime": "2020-10-15T01:44:26+00:00"
},
{
"InstanceID": "i-044041fb5a5d40623",
"Status": "running",
"LaunchTime": "2020-10-15T01:44:26+00:00"
},
{
"InstanceID": "i-0d2ab038f784f9156",
"Status": "running",
"LaunchTime": "2020-10-15T01:44:26+00:00"
}
]
今回作成したインスタンスの他に、一つ停止しているインスタンスが存在しているという状態です。
まとめて起動・停止する
では、先ほど作成したインスタンスを対象にして、 CLI コマンドでまとめて起動・停止してみます。現時点でインスタンスは起動しているので、まずはまとめて停止させてみます。
EC2 インスタンスの停止
EC2 インスタンスを停止するには、 ec2 stop-instances
コマンドを使います。その際にインスタンス ID を指定する必要があるので、 ec2 describe-instances
コマンドで取得したインスタンス ID を渡します。これを、シェルの for 文を使って一気にやってしまいます。
対象のインスタンス ID のリストは次のコマンドでします。
$ aws ec2 describe-instances \
--filters Name=tag-key,Values=StartStopByCLI Name=tag-value,Values=TRUE \
--query 'Reservations[*].Instances[].InstanceId' \
--output text
[
"i-0a7f9d2965a2177f6",
"i-044041fb5a5d40623",
"i-0d2ab038f784f9156"
]
これを for 文で回して、各インスタンスに対して ec2 stop-instance
を実行します。
$ for i in $(
aws ec2 describe-instances \
--filters Name=tag-key,Values=StartStopByCLI Name=tag-value,Values=TRUE \
--query 'Reservations[*].Instances[].InstanceId' \
--output text
); do
aws ec2 stop-instances \
--instance-ids ${i}
done
ステータスを確認してみます。
$ aws ec2 describe-instances \
--filters Name=tag-key,Values=StartStopByCLI Name=tag-value,Values=TRUE \
--query 'Reservations[*].Instances[].{InstanceID:InstanceId,Status:State.Name}'
[
{
"InstanceID": "i-0a7f9d2965a2177f6",
"Status": "stopped"
},
{
"InstanceID": "i-044041fb5a5d40623",
"Status": "stopped"
},
{
"InstanceID": "i-0d2ab038f784f9156",
"Status": "stopped"
}
]
停止できてますね。
EC2 インスタンスの起動
では、今度は対象のインスタンスをまとめて起動してみます。起動するには ec2 start-instances
コマンドを使います。
$ for i in $(
aws ec2 describe-instances \
--filters Name=tag-key,Values=StartStopByCLI Name=tag-value,Values=TRUE \
--query 'Reservations[*].Instances[].InstanceId' \
--output text
); do
aws ec2 start-instances \
--instance-ids ${i}
done
今度は全インスタンスのステータスを確認してみます。
$ aws ec2 describe-instances \
--query 'Reservations[*].Instances[].{InstanceID:InstanceId,Status:State.Name,LaunchTime:LaunchTime}'
[
{
"InstanceID": "i-0539ee02588c12499",
"Status": "stopped",
"LaunchTime": "2020-10-08T09:02:05+00:00"
},
{
"InstanceID": "i-0a7f9d2965a2177f6",
"Status": "running",
"LaunchTime": "2020-10-15T02:01:28+00:00"
},
{
"InstanceID": "i-044041fb5a5d40623",
"Status": "running",
"LaunchTime": "2020-10-15T02:01:30+00:00"
},
{
"InstanceID": "i-0d2ab038f784f9156",
"Status": "running",
"LaunchTime": "2020-10-15T02:01:31+00:00"
}
]
対象のインスタンスのみが起動しています。
for 文使わなくてもいいのでは
途中で気付きましたが、インスタンスの起動・停止をするコマンドは *-instances
という形で複数形になっているんです。そして、インスタンス ID を指定するオプションも --instance-ids
と、複数形になっています。つまり、今回のように for 文でインスタンスを一つずつ処理する必要はなかったわけです。
つまり、次のようにすれば起動・停止のコマンドは一回実行するだけでいいんですよね。
$ TARGET_INSTANCES=$(
aws ec2 describe-instances \
--filters Name=tag-key,Values=StartStopByCLI Name=tag-value,Values=TRUE \
--query 'Reservations[*].Instances[].InstanceId'
) \
&& aws ec2 stop-instances \
--instance-ids ${TARGET_INSTANCES}
{
"StoppingInstances": [
{
"CurrentState": {
"Code": 64,
"Name": "stopping"
},
"InstanceId": "i-044041fb5a5d40623",
"PreviousState": {
"Code": 16,
"Name": "running"
}
},
{
"CurrentState": {
"Code": 64,
"Name": "stopping"
},
"InstanceId": "i-0a7f9d2965a2177f6",
"PreviousState": {
"Code": 16,
"Name": "running"
}
},
{
"CurrentState": {
"Code": 64,
"Name": "stopping"
},
"InstanceId": "i-0d2ab038f784f9156",
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}
まとめ
AWS CLI を使って特定のタグキーと値を持つ EC2 インスタンスをまとめて起動・停止してみた話でした。
当初はシェルの for 文で各インスタンスごとに起動・停止を実行する想定でしたが、それぞれのコマンドのドキュメントを見れば複数インスタンスに対して同時に起動・停止を行うことができることがわかりました。一回の CLI コマンド実行で複数のインスタンスを処理できるのであればそのほうがコマンドの実行回数が少なくなるのでシンプルですが、 for を使った再帰処理の復習になったので、良かったことにします…。
最後に使用したインスタンスを削除しておしまいです。
$ TARGET_INSTANCES=$(
aws ec2 describe-instances \
--filters Name=tag-key,Values=StartStopByCLI Name=tag-value,Values=TRUE \
--query 'Reservations[*].Instances[].InstanceId'
) \
&& aws ec2 terminate-instances \
--instance-ids ${TARGET_INSTANCES}
ちなみに、同じようなことを以前に AWS SDK for Python (boto3) で実行した話については下記の記事で書いてます。
comments powered by Disqus