【実務で使えるLambda】describe_instancesで色々やってみる

# はじめに
実際に実務で扱ったLambdaの汎用的なコードを備忘録として残しています。
(※機密情報は載せてないのでご安心ください)

# インスタンスIDをリストで取得してみる
とりあえずこれをコピペすればOK
```python
import boto3

client = boto3.client('ec2', region_name='ap-northeast-1') # リージョンは任意

instances = client.describe_instances()

instance_ids = [] # 空のリストを用意

for reservation in instances['Reservations']:
     for instance in reservation['Instances']:
         instance_id = instance['InstanceId']
         instance_ids.append(instance_id)
```

# インスタンスに付いているタグ名をリストで取得してみる
さっき取得した`instance_ids`を使う

```python
tag_names = []

for instance_id in instance_ids:
    tags_info = client.describe_instances(
            Filters=[
                {
                    'Name': 'tag-key',
                    'Values':['Name']
                },
                {
                    'Name': 'instance-id',
                    'Values':[instance_id]
                }
            ]
        )['Reservations'][0]['Instances'][0]['Tags']
        for res in tags_info :
            if res['Key'] == "Name":
                tag_name = res['Value']
                tag_names.append(tag_name)
```

# リスト取得したインスタンスIDに対して「停止」「起動」をする
`instance_ids`を使う

```python
# 停止
ec2.stop_instances(InstanceIds=instance_ids)

# 起動
ec2.start_instances(InstanceIds=instance_ids)
```

:::note info
2024.2.1から特定のサービスに割り当てられているかどうかに関わらず、すべてのパブリックIPv4 アドレスの利用に対して1IPアドレスあたり 0.005 USD/時間が課金になったため、コストの面で注意が必要になった。
:::

https://aws.amazon.com/jp/blogs/news/new-aws-public-ipv4-address-charge-public-ip-insights/

https://aws.amazon.com/jp/about-aws/whats-new/2024/02/aws-free-tier-750-hours-free-public-ipv4-addresses/

# (CloudWatch)describe_alarmsを組み合わせて、設定されているCloudWatchアラーム一覧を取得してみる
`instance_ids`を使う

```python
for instance_id in instance_ids:
    tags_info = ec2.describe_instances(
        Filters = [
            {
                'Name' : 'tag-key',
                'Values' : ['Name']
            },
            {
                'Name' : 'instance-id',
                'Values' : [instance_id]
            }
        ]
    )['Reservations'][0]['Instances'][0]['Tags']
    for res in tags_info:
        if res['Key'] == "Name":
            tag_name = res['Value']

    alarm_list = cloudWatch.describe_alarms(
        AlarmNamePrefix = tag_name
        )['MetricAlarms']
```

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudwatch/client/describe_alarms.html

# CloudWatchアラーム設定されている特定期間のメトリクスを取得してみる
```python
import datetime
from dateutil.relativedelta import relativedelta

alarm_values = []

for instance_id in instance_ids:
    tags_info = ec2_client.describe_instances(
        Filters = [
            {
                'Name' : 'tag-key',
                'Values' : ['Name']
            },
            {
                'Name' : 'instance-id',
                'Values' : [instance_id]
            }
        ]
    )['Reservations'][0]['Instances'][0]['Tags']
    for res in tags_info:
        if res['Key'] == "Name":
            tag_name = res['Value']

    alarm_list = cw_client.describe_alarms(
        AlarmNamePrefix = tag_name
        )['MetricAlarms']

    for alarmList in alarm_list:
        values_list = []
        alarm_value = cw_client.get_metric_statistics(
            Namespace = alarmList['Namespace'],
            MetricName = alarmList['MetricName'],
            Dimensions = alarmList['Dimensions'],
            StartTime = datetime.datetime.now() - relativedelta(days=1) + datetime.timedelta(hours=9),
            EndTime = datetime.datetime.now() + datetime.timedelta(hours=9),
            Period = 1800,
            Statistics = [
                'Maximum',
            ]
        )

        if len(alarm_value) != 0:
            for value in alarm_value['Datapoints']:
                values_list.append(value['Maximum'])
                # print(value['Maximum'])

        alarm_values.append(values_list)

print(alarm_values)
```

<details><summary>取得データ</summary>

```
[[0.344827586207367,
  0.491803278688077,
  0.508474576270724,
  0.500000000000303,
  0.33898305084792,
  0.500000000000303,
  0.499999999999545,
  0.344827586207367,
  0.508474576270724,
  0.508474576271495,
  0.344827586206583,
  0.33898305084792,
  0.508474576271495,
  0.344827586206583,
  0.344827586206583,
  0.508474576270724,
  0.33898305084792,
  0.508474576270724,
  0.500000000000303,
  0.508474576271495,
  0.499999999999545,
  1.83333333333394,
  0.500000000000303,
  0.344827586206583,
  0.344827586206583,
  0.508474576271495,
  0.500000000000303,
  0.344827586206583,
  0.66666666666606,
  0.508474576270724]]
```
</details>

:::note info
メトリクス取得の関数に`get_metric_data`もあるが、無料利用枠の範囲外となるため、`get_metric_statistics`を使用
:::

https://repost.aws/ja/knowledge-center/cloudwatch-getmetricdata-api#

# おわりに
定期的に更新していこうと思います。

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2/client/describe_instances.html