- AWS
AWS CLIでEC2操作|describe-instancesと起動・停止
AWS CLI で EC2 を操作するときの基本は、aws ec2 describe-instances で一覧と状態を確認し、start-instances・stop-instances・reboot-instances・terminate-instances にインスタンス ID を渡す、という流れです。 describe-instances はそのままだと 1 台あたり 100 行を超える JSON を返すので、--query で必要な項目だけを取り出し、--filters で対象を絞るのがコツです。
この記事では、「ID・Name タグ・状態・種類・IP」を表で出すワンライナーを最初に示し、--filters の条件名の早見表、起動・停止・再起動・終了と wait の応答 JSON(PreviousState → CurrentState)、状態遷移の表、タグ指定で複数台をまとめて止めるスクリプト、--dry-run の出力、エラー文と原因までを、実行結果をそのまま載せて説明します。
確認環境:Ubuntu 24.04、AWS CLI 1.46.1、boto3 1.43.103、Python 3.11。AWS の API をローカルで再現するツール(moto 5.2.3)で実行しました。掲載するコマンドは、ローカル向けの接続先指定を外して AWS でそのまま使える形にしています。
AWS CLI の EC2 操作 早見表
まず、やりたいことからコマンドを引ける表です。 i-xxxx の部分はインスタンス ID で、スペース区切りで複数並べられます。
| やりたいこと | コマンド | 応答 |
|---|---|---|
| 一覧を表で見る | aws ec2 describe-instances --query '…' --output table(次の節) |
表 |
| 実行中のものだけ見る | --filters Name=instance-state-name,Values=running を足す |
絞り込んだ結果 |
| Name タグで探す | --filters "Name=tag:Name,Values=web-*" を足す |
絞り込んだ結果 |
| 1 台の状態だけ知る | aws ec2 describe-instances --instance-ids i-xxxx --query 'Reservations[0].Instances[0].State.Name' --output text |
running など |
| 起動する | aws ec2 start-instances --instance-ids i-xxxx |
StartingInstances |
| 停止する | aws ec2 stop-instances --instance-ids i-xxxx |
StoppingInstances |
| 再起動する | aws ec2 reboot-instances --instance-ids i-xxxx |
出力なし |
| 終了(削除)する | aws ec2 terminate-instances --instance-ids i-xxxx |
TerminatingInstances |
| 起動が終わるまで待つ | aws ec2 wait instance-running --instance-ids i-xxxx |
出力なし |
| 停止が終わるまで待つ | aws ec2 wait instance-stopped --instance-ids i-xxxx |
出力なし |
| 実行せずに権限だけ確かめる | 各コマンドに --dry-run を足す |
DryRunOperation |
状態(State.Name)は 6 種類です。数字は State.Code の値です。
| 状態 | コード | 意味 | インスタンスの利用料金 |
|---|---|---|---|
pending |
0 | 起動の準備中 | かからない |
running |
16 | 実行中 | かかる |
stopping |
64 | 停止の準備中 | かからない(休止の準備中はかかる) |
stopped |
80 | 停止中。いつでも起動できる | かからない |
shutting-down |
32 | 終了の準備中 | かからない |
terminated |
48 | 終了済み。起動できない | かからない |
料金の列は Amazon EC2 ユーザーガイド(Amazon EC2 instance state changes)の記載です。停止中もボリュームの利用料金はかかります(stop-instances のリファレンス)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「AWS CLIでEC2操作|describe-instancesと起動・停止」
インスタンス一覧を表で出すワンライナー
次の 1 行で、ID・Name タグ・状態・種類・IP が表になります。 今回は説明用に 4 台(web-01、web-02、batch-01、Name タグなしの 1 台)を用意しました。
aws ec2 describe-instances \
--query 'Reservations[].Instances[].{ID:InstanceId,Name:Tags[?Key==`Name`]|[0].Value,State:State.Name,Type:InstanceType,PrivateIP:PrivateIpAddress,PublicIP:PublicIpAddress}' \
--output table
------------------------------------------------------------------------------------------------
| DescribeInstances |
+---------------------+-----------+-----------------+-----------------+-----------+------------+
| ID | Name | PrivateIP | PublicIP | State | Type |
+---------------------+-----------+-----------------+-----------------+-----------+------------+
| i-3df4a515b28813aa5| web-01 | 10.176.8.189 | 54.214.62.204 | running | t3.micro |
| i-46c6786516445a138| web-02 | 10.104.219.140 | 54.214.105.171 | running | t3.micro |
| i-279405888125529b9| batch-01 | 10.151.197.48 | None | stopped | t3.small |
| i-a82a1805e1d9668b3| None | 10.71.72.109 | 54.214.86.59 | running | t3.micro |
+---------------------+-----------+-----------------+-----------------+-----------+------------+
結果から読み取れることが 3 つあります。
{見出し:項目}の形で書くと、見出しつきの表になります。 列は見出しのアルファベット順に並びます(ID、Name、PrivateIP、PublicIP、State、Type)。- Name タグが無いインスタンスは
Noneと表示されます。 - 停止中のインスタンスはパブリック IP が
Noneです。
列の順番を自分で決めたいときは、{ } の代わりに [ ] で並べます。見出しは付きませんが、書いた順に出ます。
aws ec2 describe-instances \
--query 'Reservations[].Instances[].[InstanceId,Tags[?Key==`Name`]|[0].Value,State.Name,InstanceType,PrivateIpAddress,PublicIpAddress]' \
--output table
------------------------------------------------------------------------------------------------
| DescribeInstances |
+---------------------+-----------+----------+-----------+------------------+------------------+
| i-3df4a515b28813aa5| web-01 | running | t3.micro | 10.176.8.189 | 54.214.62.204 |
| i-46c6786516445a138| web-02 | running | t3.micro | 10.104.219.140 | 54.214.105.171 |
| i-279405888125529b9| batch-01 | stopped | t3.small | 10.151.197.48 | None |
| i-a82a1805e1d9668b3| None | running | t3.micro | 10.71.72.109 | 54.214.86.59 |
+---------------------+-----------+----------+-----------+------------------+------------------+
シェルスクリプトで加工するなら --output text(タブ区切り)が扱いやすい形です。
aws ec2 describe-instances \
--query 'Reservations[].Instances[].[InstanceId,Tags[?Key==`Name`]|[0].Value,State.Name]' \
--output text
i-3df4a515b28813aa5 web-01 running
i-46c6786516445a138 web-02 running
i-279405888125529b9 batch-01 stopped
i-a82a1805e1d9668b3 None running
--query の式を分解して読む
ワンライナーの --query は JMESPath という JSON 用の問い合わせ言語で書かれています。部品ごとに意味を整理します。
| 部品 | 意味 |
|---|---|
Reservations[] |
最上位の Reservations 配列を 1 つずつ取り出す |
.Instances[] |
各 Reservation の中の Instances 配列を取り出して 1 本の配列に平らにする |
.{ID:InstanceId, …} |
各インスタンスから、見出しつきで項目を選ぶ |
.[InstanceId, …] |
各インスタンスから、順番どおりに項目を選ぶ(見出しなし) |
State.Name |
入れ子の値はドットでたどる |
Tags[?Key==`Name`] |
Tags 配列から Key が Name の要素だけに絞る |
|[0].Value |
絞った結果の 1 件目の Value を取る |
式の中でバッククォートを使うので、全体はシングルクォートで囲みます。
元の JSON の形(どこに何があるか)
describe-instances をそのまま実行すると、今回の環境では 1 台で 129 行の JSON が返りました。主要なキーだけを抜き出すと、次の構造です。
{
"Reservations": [
{
"ReservationId": "r-153e110eaf58d42c8",
"OwnerId": "123456789012",
"Instances": [
{
"InstanceId": "i-3df4a515b28813aa5",
"InstanceType": "t3.micro",
"State": { "Code": 16, "Name": "running" },
"PrivateIpAddress": "10.176.8.189",
"PublicIpAddress": "54.214.62.204",
"Tags": [
{ "Key": "Name", "Value": "web-01" },
{ "Key": "Env", "Value": "dev" }
],
"Placement": { "AvailabilityZone": "ap-northeast-1a" },
"VpcId": "vpc-c0dddd23e9a22bbe0",
"SubnetId": "subnet-cdc627277e29a834e",
"LaunchTime": "2026-10-03T09:44:24.000Z",
"StateTransitionReason": ""
}
]
}
]
}
インスタンスは Reservations → Instances の 2 段の配列の中にあります。 --query の先頭が Reservations[].Instances[] になるのはこのためです。
| 取り出したい項目 | --query に書くキー |
|---|---|
| インスタンス ID | InstanceId |
| 状態 | State.Name(数字は State.Code) |
| インスタンスタイプ | InstanceType |
| プライベート IP / パブリック IP | PrivateIpAddress / PublicIpAddress |
| アベイラビリティーゾーン | Placement.AvailabilityZone |
| VPC / サブネット | VpcId / SubnetId |
| 起動日時 | LaunchTime |
| 状態が変わった理由 | StateTransitionReason |
| AMI の ID | ImageId |
--filters の条件名 早見表
--filters は Name=条件名,Values=値 の形で書き、AWS 側で絞り込んでから結果を返します。 AWS CLI のリファレンス(describe-instances)に載っている条件名のうち、よく使うものを表にしました。
| 条件名 | 絞り込む対象 | 書き方の例 |
|---|---|---|
instance-state-name |
状態 | Name=instance-state-name,Values=running |
tag:キー |
指定したキーのタグの値 | "Name=tag:Name,Values=web-*" |
tag-key |
タグのキーがあるかどうか | Name=tag-key,Values=Env |
instance-type |
インスタンスタイプ | Name=instance-type,Values=t3.small |
vpc-id |
VPC | Name=vpc-id,Values=vpc-xxxx |
subnet-id |
サブネット | Name=subnet-id,Values=subnet-xxxx |
availability-zone |
アベイラビリティーゾーン | Name=availability-zone,Values=ap-northeast-1a |
private-ip-address |
プライベート IPv4 アドレス | Name=private-ip-address,Values=10.0.1.15 |
ip-address |
パブリック IPv4 アドレス | Name=ip-address,Values=203.0.113.10 |
image-id |
AMI の ID | Name=image-id,Values=ami-xxxx |
instance.group-id |
セキュリティグループの ID | Name=instance.group-id,Values=sg-xxxx |
key-name |
キーペアの名前 | Name=key-name,Values=my-key |
architecture |
アーキテクチャ(x86_64、arm64 など) |
Name=architecture,Values=arm64 |
4 つの条件を実行した結果
実行中のインスタンスの ID だけを取り出します。
aws ec2 describe-instances \
--filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[].InstanceId' --output text
i-3df4a515b28813aa5 i-46c6786516445a138 i-a82a1805e1d9668b3
Name タグが web- で始まるものを探します。値には * のワイルドカードが使えました。
aws ec2 describe-instances \
--filters "Name=tag:Name,Values=web-*" \
--query 'Reservations[].Instances[].[InstanceId,Tags[?Key==`Name`]|[0].Value]' \
--output text
i-3df4a515b28813aa5 web-01
i-46c6786516445a138 web-02
インスタンスタイプで絞ります。
aws ec2 describe-instances \
--filters Name=instance-type,Values=t3.small \
--query 'Reservations[].Instances[].[InstanceId,InstanceType]' --output text
i-279405888125529b9 t3.small
VPC で絞って台数を数えます。length() は配列の要素数を返す関数です。
aws ec2 describe-instances \
--filters Name=vpc-id,Values=vpc-c0dddd23e9a22bbe0 \
--query 'length(Reservations[].Instances[])'
4
条件を組み合わせる(AND と OR)
複数の Name=… を並べると「かつ(AND)」、1 つの Values= にカンマで並べると「または(OR)」になります。
# Env タグが dev、かつ 状態が running または stopped
aws ec2 describe-instances \
--filters Name=tag:Env,Values=dev Name=instance-state-name,Values=running,stopped \
--query 'Reservations[].Instances[].[InstanceId,State.Name]' --output text
i-3df4a515b28813aa5 running
i-46c6786516445a138 running
# Env タグが dev または prod、かつ 種類が t3.small
aws ec2 describe-instances \
--filters Name=tag:Env,Values=dev,prod Name=instance-type,Values=t3.small \
--query 'Reservations[].Instances[].InstanceId' --output text
i-279405888125529b9
条件に合うものが無いときは、エラーではなく空の配列が返ります。
aws ec2 describe-instances --filters Name=tag:Name,Values=nothing
{
"Reservations": []
}
--filters と --query の使い分け
| 項目 | --filters |
--query |
|---|---|---|
| 絞り込む場所 | AWS 側(サーバー側) | 手元の CLI(クライアント側) |
| 役割 | どのインスタンスを返すか | 返ってきた JSON のどの項目を表示するか |
| 処理の順番 | 先 | あと |
| 台数が多いとき | 返るデータが減るので有利 | 全件を受け取ってから処理する |
AWS CLI ユーザーガイド(Filtering output)にも、サーバー側の絞り込みが先に処理され、その結果に --query が適用されると書かれています。「対象は --filters、表示項目は --query」と分けて書くのが基本です。
--query だけでも状態で絞れますが、全件を受け取ってからの処理になります。
aws ec2 describe-instances \
--query 'Reservations[].Instances[?State.Name==`stopped`][].InstanceId' \
--output text
i-279405888125529b9
起動・停止・再起動・終了の応答 JSON
start・stop・terminate の応答には、直前の状態(PreviousState)と現在の状態(CurrentState)が入っています。 順に実行します。
停止する(stop-instances)
aws ec2 stop-instances --instance-ids i-3df4a515b28813aa5
{
"StoppingInstances": [
{
"InstanceId": "i-3df4a515b28813aa5",
"CurrentState": {
"Code": 64,
"Name": "stopping"
},
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}
コマンドはすぐに返り、状態は running → stopping になりました。この時点ではまだ停止の途中です。 止まり切るまで待つには wait を使います。
aws ec2 wait instance-stopped --instance-ids i-3df4a515b28813aa5
wait は何も出力せず、条件を満たすと終了します。停止後の状態を確認します。
aws ec2 describe-instances --instance-ids i-3df4a515b28813aa5 \
--query 'Reservations[].Instances[].[State.Name,PublicIpAddress,PrivateIpAddress,StateTransitionReason]'
[
[
"stopped",
null,
"10.176.8.189",
"User initiated (2026-10-03 09:45:01 UTC)"
]
]
停止するとパブリック IP は null になり、プライベート IP は残ります。 StateTransitionReason には、利用者の操作で止まったことと時刻が記録されます。
起動する(start-instances)と wait instance-running
aws ec2 start-instances --instance-ids i-3df4a515b28813aa5
{
"StartingInstances": [
{
"InstanceId": "i-3df4a515b28813aa5",
"CurrentState": {
"Code": 0,
"Name": "pending"
},
"PreviousState": {
"Code": 80,
"Name": "stopped"
}
}
]
}
stopped → pending になりました。running になるまで待ちます。
aws ec2 wait instance-running --instance-ids i-3df4a515b28813aa5
aws ec2 describe-instances --instance-ids i-3df4a515b28813aa5 \
--query 'Reservations[].Instances[].State'
[
{
"Code": 16,
"Name": "running"
}
]
起動し直したあとに一覧を出すと、web-01 のパブリック IP は 54.214.62.204 から 54.214.32.108 に変わっていました。停止と起動をはさむとパブリック IP は新しくなります(Elastic IP を付けている場合は変わりません。Amazon EC2 ユーザーガイド)。
wait のリファレンスによると、wait instance-running は describe-instances を 15 秒ごとに呼び、40 回確認しても条件を満たさなければ終了コード 255 で終わります。スクリプトでは次のように続けて書けます。
aws ec2 start-instances --instance-ids i-3df4a515b28813aa5
aws ec2 wait instance-running --instance-ids i-3df4a515b28813aa5 && echo "起動しました"
起動しました
| wait のサブコマンド | 待つ条件 |
|---|---|
instance-running |
状態が running になる |
instance-stopped |
状態が stopped になる |
instance-terminated |
状態が terminated になる |
instance-status-ok |
インスタンスのステータスチェックが ok になる |
system-status-ok |
システムのステータスチェックが ok になる |
instance-exists |
インスタンスが存在する |
running になった直後は、OS の起動がまだ終わっていないことがあります。SSH 接続などを続けて行うスクリプトでは、instance-status-ok まで待つと安定します。ステータスチェックの結果は describe-instance-status で見られます。
aws ec2 describe-instance-status --instance-ids i-3df4a515b28813aa5 \
--query 'InstanceStatuses[].[InstanceState.Name,InstanceStatus.Status,SystemStatus.Status]' \
--output text
running ok ok
左から、インスタンスの状態、インスタンスのステータスチェック、システムのステータスチェックです。
再起動する(reboot-instances)
aws ec2 reboot-instances --instance-ids i-3df4a515b28813aa5
reboot-instances は成功しても何も出力しません。 状態は running のままで、PreviousState・CurrentState の応答もありません。再起動では、同じホスト上にとどまり、パブリック IP も保たれます(Amazon EC2 ユーザーガイド)。
終了する(terminate-instances)
terminate-instances はインスタンスを削除する操作で、元に戻せません。 実行前に ID と Name タグを必ず確認します。
aws ec2 terminate-instances --instance-ids i-a82a1805e1d9668b3
{
"TerminatingInstances": [
{
"InstanceId": "i-a82a1805e1d9668b3",
"CurrentState": {
"Code": 32,
"Name": "shutting-down"
},
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}
aws ec2 wait instance-terminated --instance-ids i-a82a1805e1d9668b3
aws ec2 describe-instances --instance-ids i-a82a1805e1d9668b3 \
--query 'Reservations[].Instances[].[InstanceId,State.Name,State.Code,StateTransitionReason]'
[
[
"i-a82a1805e1d9668b3",
"terminated",
48,
"User initiated (2026-10-03 09:45:46 UTC)"
]
]
終了したインスタンスは、しばらくの間 terminated の状態で一覧に残ります(AWS CLI のリファレンスでは、通常 1 時間未満とされています)。一覧から外したいときは、--filters Name=instance-state-name,Values=running,stopped のように状態で絞ります。
終了保護を付けておく
うっかり終了させたくないインスタンスには、終了保護を付けられます。上の終了を行う前に、同じインスタンスで試した結果です。
aws ec2 modify-instance-attribute \
--instance-id i-a82a1805e1d9668b3 --disable-api-termination
この状態で terminate-instances を実行すると、次のメッセージで止まります。
An error occurred (OperationNotPermitted) when calling the TerminateInstances operation: The instance 'i-a82a1805e1d9668b3' may not be terminated. Modify its 'disableApiTermination' instance attribute and try again.
保護を外すときは --no-disable-api-termination を指定します。
状態遷移の表(どの操作でどう変わるか)
4 つの操作による状態の移り変わりを、応答 JSON の PreviousState → CurrentState とあわせて整理します。
| 操作 | 実行できる状態 | 応答の PreviousState → CurrentState | 最終的な状態 | 待つコマンド |
|---|---|---|---|---|
start-instances |
stopped |
stopped → pending |
running |
wait instance-running |
stop-instances |
running |
running → stopping |
stopped |
wait instance-stopped |
reboot-instances |
running |
応答なし | running のまま |
—(状態は変わらない) |
terminate-instances |
running、stopped |
running → shutting-down(停止中からは stopped → shutting-down) |
terminated |
wait instance-terminated |
stateDiagram-v2
[*] --> pending: run-instances
pending --> running
running --> stopping: stop-instances
stopping --> stopped
stopped --> pending: start-instances
running --> running: reboot-instances
running --> shutting_down: terminate-instances
stopped --> shutting_down: terminate-instances
shutting_down --> terminated
terminated --> [*]
再起動・停止・終了で何が保たれるかは、Amazon EC2 ユーザーガイドの比較が参考になります。
| 項目 | 再起動 | 停止 → 起動 | 終了 |
|---|---|---|---|
| ホスト | 同じホストのまま | 新しいホストに移る(同じ場合もある) | — |
| プライベート IPv4 | 保たれる | 保たれる | — |
| パブリック IPv4 | 保たれる | 新しくなる(Elastic IP は除く) | — |
| Elastic IP | 関連付けたまま | 関連付けたまま | 関連付けが外れる |
| インスタンスストアのデータ | 保たれる | 消える | 消える |
| ルートボリューム | 保たれる | 保たれる | 既定では削除される |
| メモリの内容 | 消える | 消える | 消える |
stop-instances には、次のオプションもあります(stop-instances のリファレンス)。
| オプション | 動き |
|---|---|
--hibernate |
起動時に休止を有効にしたインスタンスを休止させる。休止できない場合は通常の停止になる |
--force |
強制的に停止する。まず通常のシャットダウンを試み、時間内に終わらなければ強制的に止める |
--dry-run |
実行せずに、必要な権限があるかだけを確かめる |
タグ指定で複数台をまとめて止める
「タグで ID を集める → その ID を stop-instances に渡す」の 2 段構えにすると、台数が増えても同じコマンドで止められます。 Env タグが dev で実行中のものを止める例です。
IDS=$(aws ec2 describe-instances \
--filters Name=tag:Env,Values=dev Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[].InstanceId' --output text)
aws ec2 stop-instances --instance-ids $IDS \
--query 'StoppingInstances[].[InstanceId,PreviousState.Name,CurrentState.Name]' \
--output table
------------------------------------------------
| StopInstances |
+----------------------+----------+------------+
| i-3df4a515b28813aa5 | running | stopping |
| i-46c6786516445a138 | running | stopping |
+----------------------+----------+------------+
stop-instances の応答にも --query が使えるので、「どれが、どの状態からどの状態になったか」を表で残せます。$IDS はスペース(タブ)区切りの ID を複数の引数として渡したいので、ここではクォートで囲みません。
起動も同じ形です。
aws ec2 start-instances --instance-ids $IDS \
--query 'StartingInstances[].[InstanceId,PreviousState.Name,CurrentState.Name]' \
--output text
i-3df4a515b28813aa5 stopped pending
i-46c6786516445a138 stopped pending
スクリプトにまとめる(対象が 0 台のときの分岐つき)
対象が 1 台も無いときに空の ID で stop-instances を呼ばないよう、分岐を入れたスクリプトです。
#!/bin/bash
# 使い方: ./stop_by_tag.sh Env dev
KEY=$1; VALUE=$2
IDS=$(aws ec2 describe-instances \
--filters "Name=tag:$KEY,Values=$VALUE" "Name=instance-state-name,Values=running" \
--query 'Reservations[].Instances[].InstanceId' --output text)
if [ -z "$IDS" ]; then
echo "対象のインスタンスはありません(tag:$KEY=$VALUE, running)"
exit 0
fi
echo "停止対象: $IDS"
aws ec2 stop-instances --instance-ids $IDS \
--query 'StoppingInstances[].[InstanceId,PreviousState.Name,CurrentState.Name]' --output text
aws ec2 wait instance-stopped --instance-ids $IDS
echo "停止を確認しました"
./stop_by_tag.sh Env dev
停止対象: i-3df4a515b28813aa5 i-46c6786516445a138
i-3df4a515b28813aa5 running stopping
i-46c6786516445a138 running stopping
停止を確認しました
./stop_by_tag.sh Env none
対象のインスタンスはありません(tag:Env=none, running)
停止後に、止まったものと理由を一覧で確認できます。
aws ec2 describe-instances \
--filters Name=instance-state-name,Values=stopped \
--query 'Reservations[].Instances[].[InstanceId,Tags[?Key==`Name`]|[0].Value,StateTransitionReason]' \
--output table
-------------------------------------------------------------------------------
| DescribeInstances |
+----------------------+---------+--------------------------------------------+
| i-3df4a515b28813aa5 | web-01 | User initiated (2026-10-03 09:53:46 UTC) |
| i-46c6786516445a138 | web-02 | User initiated (2026-10-03 09:53:46 UTC) |
+----------------------+---------+--------------------------------------------+
boto3 で同じことをする
Python から行う場合の完成形です。一覧の取得は paginator で回し、停止の完了は waiter で待ちます。
import boto3
from botocore.exceptions import ClientError
ec2 = boto3.client("ec2", region_name="ap-northeast-1")
def list_instances(filters=None):
rows = []
paginator = ec2.get_paginator("describe_instances")
for page in paginator.paginate(Filters=filters or []):
for r in page["Reservations"]:
for i in r["Instances"]:
name = next((t["Value"] for t in i.get("Tags", []) if t["Key"] == "Name"), "-")
rows.append((i["InstanceId"], name, i["State"]["Name"], i["InstanceType"]))
return rows
for row in list_instances([{"Name": "tag:Env", "Values": ["dev"]}]):
print(*row)
ids = [r[0] for r in list_instances([
{"Name": "tag:Env", "Values": ["dev"]},
{"Name": "instance-state-name", "Values": ["running"]},
])]
if ids:
res = ec2.stop_instances(InstanceIds=ids)
for s in res["StoppingInstances"]:
print(s["InstanceId"], s["PreviousState"]["Name"], "->", s["CurrentState"]["Name"])
ec2.get_waiter("instance_stopped").wait(InstanceIds=ids)
print("停止を確認:", len(ids), "台")
try:
ec2.stop_instances(InstanceIds=["i-0123456789abcdef0"])
except ClientError as e:
print("エラー:", e.response["Error"]["Code"])
web-01 が停止中、web-02 が実行中の状態で実行した結果です。
i-3df4a515b28813aa5 web-01 stopped t3.small
i-46c6786516445a138 web-02 running t3.micro
i-46c6786516445a138 running -> stopping
停止を確認: 1 台
エラー: InvalidInstanceID.NotFound
--dry-run で実行前に確かめる
--dry-run を付けると、実際には操作せず、権限があるかどうかだけを確かめられます。
aws ec2 stop-instances --instance-ids i-3df4a515b28813aa5 --dry-run
An error occurred (DryRunOperation) when calling the StopInstances operation: Request would have succeeded, but DryRun flag is set.
「An error occurred」と表示されますが、DryRunOperation は「権限があり、実行すれば成功する」という意味です。 終了コードは 255 でした。terminate-instances や start-instances でも同じ形で返ります。
An error occurred (DryRunOperation) when calling the TerminateInstances operation: Request would have succeeded, but DryRun flag is set.
| --dry-run の結果 | 意味 | 次にすること |
|---|---|---|
DryRunOperation |
必要な権限があり、実行すれば成功する | --dry-run を外して実行 |
UnauthorizedOperation |
この操作を行う権限がない | IAM ポリシーと、使っている認証情報を確認 |
エラーコードの意味は Amazon EC2 API リファレンス(Error codes)の記載です。終了コードが 0 にならないので、スクリプトで判定するときはメッセージに DryRunOperation が含まれるかどうかを見ます。
if aws ec2 terminate-instances --instance-ids i-a82a1805e1d9668b3 --dry-run 2>&1 \
| grep -q DryRunOperation; then
echo "権限あり。実行できます"
fi
権限あり。実行できます
エラー文と原因のまとめ
エラーは An error occurred (エラーコード) when calling the 操作名 operation: 説明 の形で返ります。 かっこの中のエラーコードで原因を切り分けます。
InvalidInstanceID.NotFound
存在しない ID を指定した例です。
aws ec2 stop-instances --instance-ids i-0123456789abcdef0
An error occurred (InvalidInstanceID.NotFound) when calling the StopInstances operation: The instance ID 'i-0123456789abcdef0' does not exist
describe-instances でも同じエラーコードになります。
An error occurred (InvalidInstanceID.NotFound) when calling the DescribeInstances operation: The instance ID 'i-0123456789abcdef0' does not exist
ID が合っているのにこのエラーが出るときは、リージョンが違うことがよくあります。インスタンスはリージョンごとに管理されているので、--region や設定ファイルのリージョンを確認します。API リファレンスには、作成した直後のインスタンスで、ID がまだ行き渡っていないときにも出ることがあると書かれています。
--instance-ids の付け忘れ
aws ec2 stop-instances
aws: error: the following arguments are required: --instance-ids
これは AWS に送る前に CLI が止めるエラーです。
エラーコードの一覧
| エラーコード | 意味・出る場面 | 確認すること |
|---|---|---|
InvalidInstanceID.NotFound |
指定したインスタンスが存在しない | ID の打ち間違い、リージョン、終了済みで一覧から消えていないか |
InvalidInstanceID.Malformed |
ID の形式が正しくない | i- で始まる完全な ID を渡しているか(Name タグを渡していないか) |
IncorrectInstanceState |
その操作ができない状態にある | describe-instances で現在の状態を確認し、wait で遷移を待ってから実行 |
OperationNotPermitted |
許可されていない操作(終了保護が有効なインスタンスの終了など) | 終了保護(disableApiTermination)の設定 |
UnauthorizedOperation |
操作する権限がない | IAM ポリシー、使っているプロファイル |
UnsupportedOperation |
対応していない操作(インスタンスストアをルートにしたインスタンスの停止など) | インスタンスの種類やルートデバイスの種類 |
InstanceLimitExceeded |
同時に実行できるインスタンス数の上限に達した | 上限の確認と、使っていないインスタンスの整理 |
DryRunOperation |
--dry-run を付けた。権限はあり、実行すれば成功する |
--dry-run を外す |
意味の列は Amazon EC2 API リファレンス(Error codes)の説明をもとにしています。IncorrectInstanceState の例として、同リファレンスは「ユーザーデータなど一部の属性は、停止中でないと変更できない」ことを挙げています。停止や起動の直後に次の操作を続けるときは、wait をはさんで状態が落ち着いてから実行すると、このエラーを避けられます。
よくある質問
Q. describe-instances で Name タグを表示するにはどう書きますか?
A. --query の中で Tags[?Key==`Name`]|[0].Value と書きます。Tags 配列から Key が Name の要素を選び、その 1 件目の Value を取り出す式です。Name タグが無いインスタンスは None と表示されます。
Q. stop-instances を実行したのに、状態が stopped になりません。
A. コマンドは停止を受け付けた時点で返るので、応答の CurrentState は stopping です。止まり切るまで待つには aws ec2 wait instance-stopped --instance-ids … を続けて実行します。
Q. インスタンス名(Name タグ)で起動・停止できますか?
A. start-instances や stop-instances が受け取るのはインスタンス ID です。Name タグで操作したいときは、describe-instances --filters "Name=tag:Name,Values=名前" で ID を取り出し、その結果を --instance-ids に渡します。
Q. 停止(stop)と終了(terminate)の違いは何ですか?
A. 停止は電源を切った状態で、あとから start-instances で起動できます。終了はインスタンスの削除で、起動し直すことはできず、ルートボリュームも既定では削除されます。
まとめ
- 一覧は
describe-instancesに--queryと--output tableを付けると、ID・Name タグ・状態・種類・IP の表になります。 - 対象は
--filters(サーバー側)、表示項目は--query(手元側)で絞ります。複数のName=は AND、Values=のカンマ区切りは OR です。 - start・stop・terminate の応答には PreviousState と CurrentState が入り、reboot は何も出力しません。
- コマンドは受け付けた時点で返るので、完了を待つときは
aws ec2 wait instance-running/instance-stoppedを使います。 - 停止と起動をはさむとパブリック IP は新しくなり、プライベート IP は保たれます。
- タグで ID を集めてから
--instance-idsに渡すと、複数台をまとめて操作できます。対象 0 台の分岐を入れておくと安心です。 --dry-runのDryRunOperationは「実行すれば成功する」の意味。エラーは、かっこの中のエラーコードで切り分けます。
参考・出典
- AWS CLI コマンドリファレンス「ec2 describe-instances」 https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html
- 同「ec2 stop-instances」 https://docs.aws.amazon.com/cli/latest/reference/ec2/stop-instances.html
- 同「ec2 wait instance-running」 https://docs.aws.amazon.com/cli/latest/reference/ec2/wait/instance-running.html
- AWS CLI ユーザーガイド「Filtering output in the AWS CLI」 https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-filter.html
- Amazon EC2 ユーザーガイド「Amazon EC2 instance state changes」 https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html
- Amazon EC2 API リファレンス「Error codes for the Amazon EC2 API」 https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「AWS CLIでEC2操作|describe-instancesと起動・停止」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。