カテゴリー
インフラ

AWS EC2 リザーブドインスタンスの有効期限をチェックする

はじめに

AWS EC2リザーブドインスタンスの有効期限は1年または3年です。有効期限が迫ってきても、気づかない場合があります。今回、ClowdWatch Eventsをトリガー(1日毎に実行)としてLambda関数を実行し、指定したしきい値以下になったリザーブドインスタンス1件毎に、期限が迫ってきている旨をSNSに通知するLambda関数を作成しました。

ソースコード

Threshold(目的のしきい値)とTopicARN(通知先のSNS TopicのARN)はLambda関数の環境変数で指定するようにしました。

import boto3
import json
import logging
import os
from datetime import datetime, timezone

logger = logging.getLogger()
logger.setLevel(logging.INFO)

ec2client = boto3.client('ec2')
snsclient = boto3.client('sns')

def lambda_handler(event, context):
    try:
        Threshold = int(os.environ['Threshold'])
    except KeyError as e:
        logger.error('env error: Specify Threshold')
        raise e
    except ValueError as e:
        logger.error('env error: Specify Threshold with base 10 integer')
        raise e
    try:
        TopicARN = os.environ['TopicARN']
    except KeyError as e:
        logger.error('env error: Specify TopicARN')
        raise e

    res = ec2client.describe_reserved_instances(
        Filters=[{
            'Name': 'state',
            'Values': ['active']
        }])
    if len(res['ReservedInstances']) == 0:
        logger.info('no-op by no reserved instances')
        return {}
    
    now = datetime.now(timezone.utc)
    published = False
    for instance in res['ReservedInstances']:
        days = (instance['End'] - now).days
        if days <= Threshold:
            snsclient.publish(
                TopicArn=TopicARN,
                Subject='[Warn] EC2 ReservedInstance will expire in {} days'.format(days),
                Message=json.dumps({
                    'ReservedInstancesId': instance['ReservedInstancesId'],
                    'End': instance['End'].isoformat(sep='T')
                })
            )
            published = True
    if published:
        logger.info('published')
        return {}

    logger.info('no-op by no problems')
    return {}

このプログラムで要注意なのは、ここで扱う日付型の変数はすべて aware である、という点です。具体的には now の取り扱いで、単に now = datetime.now() とすると、now は naive な日付として扱われます。一方、boto3 を通して得られる日付型変数(具体的には instance[‘END’] )は aware です。naive な日付と aware な日付とを計算しようとすると、エラー “can’t subtract offset-naive and offset-aware datetimes” が発生します。

リファレンス

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください