AWS EC2のインスタンスを起動・停止するためのPythonスクリプト

AWSのEC2インスタンスは動かしっ放しだと当然お金がかさみますので、使う時だけ起動、使い終わったら停止させたいですよね。いちいちAWSコンソールにログインして操作するのも大変面倒ですので、起動・停止するためのスクリプトを作りました。作成にあたって、Claude 3.5 Sonnetに手伝ってもらいました。

::: note info
起動スクリプト、停止スクリプトともIAMによる権限設定が必要です(後述)。
:::
# 事前準備
```
pip install boto3
```
# 起動スクリプト
```python:EC2_Start.py
import boto3
# EC2クライアントを作成
ec2 = boto3.client(
    'ec2',
    region_name='ap-northeast-3', #リージョンIDを記述
    aws_access_key_id='xxxxxxxxxxxxxxxxxx',#本当は直接記述しない方がいいのですが
    aws_secret_access_key='yyyyyyyyyyyyyyyyyyyyyyyyyyyyy'#本当は直接記述しない方がいいのですが
    )

# 操作対象のインスタンスIDのリスト
instance_ids = ['i-aaaaaaaaa', 'i-bbbbbbbbb', 'i-ccccccccc', 'i-ddddddddd']

response = ec2.start_instances(InstanceIds=instance_ids)
print("インスタンスを起動しました:", response['StartingInstances'])

# すべてのインスタンスが running 状態になるまで待機
waiter = ec2.get_waiter('instance_running')
print("インスタンスが完全に起動するのを待っています...")
waiter.wait(InstanceIds=instance_ids)

# 起動完了後、各インスタンスの状態を確認
response = ec2.describe_instances(InstanceIds=instance_ids)
for reservation in response['Reservations']:
    for instance in reservation['Instances']:
        print(f"インスタンス {instance['InstanceId']} は {instance['State']['Name']} 状態です。")

```
# 停止スクリプト
```python:EC2_End.py
import boto3

# EC2クライアントを作成
ec2 = boto3.client('ec2',
                    region_name='ap-northeast-3', #リージョンIDを記述
                    aws_access_key_id='xxxxxxxxxxxxxxxx', #本当は直接記述しない方がいいのですが
                    aws_secret_access_key='yyyyyyyyyyyyyyyyyyyyyyy' #本当は直接記述しない方がいいのですが
                )

# 操作対象のインスタンスIDのリスト
instance_ids = ['i-aaaaaaaaa', 'i-bbbbbbbbb', 'i-ccccccccc', 'i-ddddddddd']

response = ec2.stop_instances(InstanceIds=instance_ids)
print("インスタンスの停止を開始しました:", response['StoppingInstances'])

# すべてのインスタンスが stopped 状態になるまで待機
waiter = ec2.get_waiter('instance_stopped')
print("インスタンスが完全に停止するのを待っています...")
waiter.wait(InstanceIds=instance_ids)

# 停止完了後、各インスタンスの状態を確認
response = ec2.describe_instances(InstanceIds=instance_ids)
for reservation in response['Reservations']:
    for instance in reservation['Instances']:
        print(f"インスタンス {instance['InstanceId']} は {instance['State']['Name']} 状態です。")
```

# IAMで必要な権限を設定
(1) まず、IAM(Identity and Access Management)の`IAM>ユーザー`にてVPNのエンドポイントを操作する専用のアカウントを作っておきます。今回は`EC2_StartStop`という名前にしておきました。
(2) 次に、アクセスキーを作成し、アクセスキーとシークレットアクセスキーを記録しておきます。
(3) `EC2_StartStop`にアタッチする専用のポリシーを作ります。今回は`EC2_StartStop`という名前にしました。以下のJSONを丸々貼り付ける様にすれば大丈夫なはずです。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceStatus"
            ],
            "Resource": "*"
        }
    ]
}
```

::: note info
権限については以下の通りです。（参照[「Amazon のアクション、リソース、および条件キー EC2」](https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_amazonec2.html)）
StartInstances:停止したインスタンスを起動する許可を付与
StopInstances:インスタンスを停止する許可を付与
DescribeInstances:1 つ以上のインスタンスを記述する許可を付与
DescribeInstanceStatus:1 つ以上のインスタンスのステータスを記述する許可を付与
:::

(4) ユーザー`EC2_StartStop`に許可ポリシー`EC2_StartStop`をアタッチします。
(5) アクセスキー、シークレットアクセスキーを設定します。