🐶

S3 ストレージクラスを監視して、クラウド破産を免れたい

2024/05/15に公開

目的

クラウドってうっかり誤って設定されてしまっていたことってあるよね。
みんなも経験あるよね!!(強気)

今回は、S3にアーカイブしたと思っていたファイルが”DeepArchive”になっていないと、
高い料金をせいきゅうされてしまうから、それを自動でチェックするプログラムを書いてみたよ

うっかりさんを助けるために、この記事を書きます。

前提条件

必要なリソース

  • Lambda
  • S3
  • EventBridge

手順

1. ポリシーを作る

「ポリシーの作成」ボタンを押して作成を開始してね。
ぽりしー
「JSON」を押してね。
JSON
JSONでポリシーを定義するね。
かすたむぽりしー

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "VisualEditor0",
			"Effect": "Allow",
			"Action": "s3:ListBucket",
			"Resource": "arn:aws:s3:::あなたのバケット名"
		},
		{
			"Sid": "VisualEditor1",
			"Effect": "Allow",
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::あなたのバケット名/*"
		}
	]
}

かすたむぽりしーをJSONで記入したら、保存してポリシーにわかりやすい名前をつけてね。
キラキラネームはだめだよ!!(だめ、ぜったい)

2. ロールを作る

「ロールを作成」ボタンを押す
ろーる
信頼されたエンティティタイプは、「AWS のサービス」を選択して、
ユースケースは、「Lambda」を選択して「次へ」を押してね。
ロール
メガネマークのところから、先ほど作ったポリシーを選択してね。
許可を追加
ロールにわかりやすい名前をつけて。保存してね。

3. Lambda関数を作る

わかりやすい名前をつけてね。
Pythonを選択して、2で作成したロールを設定してね。

ここにコードを書くよ

import boto3
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

BUCKET_NAME = 'S3のバケット名'
GMAIL_USER = 'メールアドレス'
GMAIL_PASSWORD = 'メールアドレスのアプリパスワード'
ALERT_EMAIL = '送り先メールアドレス'
AWS_S3_REGION = 'AWS S3のリージョン'

s3 = boto3.client('s3', region_name=AWS_S3_REGION)

def lambda_handler(event, context):
    paginator = s3.get_paginator('list_objects_v2')
    non_deep_archive_objects = []

    for page in paginator.paginate(Bucket=BUCKET_NAME):
        for obj in page.get('Contents', []):
            response = s3.head_object(Bucket=BUCKET_NAME, Key=obj['Key'])
            storage_class = response.get('StorageClass', 'STANDARD')
            if storage_class != 'DEEP_ARCHIVE':
                non_deep_archive_objects.append(obj['Key'])

    if non_deep_archive_objects:
        send_alert(non_deep_archive_objects)
    else:
        print("S3バケット内にDeep Archiveでないオブジェクトは見つかりませんでした")

def send_alert(non_deep_archive_objects):
    subject = "S3バケット内のDeep Archiveでないオブジェクトが見つかりました"
    body = f"S3バケット '{BUCKET_NAME}' 内の以下のオブジェクトが Deep Archive ストレージクラスではありません:\n" + "\n".join(non_deep_archive_objects)

    msg = MIMEMultipart()
    msg['From'] = GMAIL_USER
    msg['To'] = ALERT_EMAIL
    msg['Subject'] = subject
    msg.attach(MIMEText(body, 'plain'))

    try:
        server = smtplib.SMTP('smtp.gmail.com', 587)
        server.starttls()
        server.login(GMAIL_USER, GMAIL_PASSWORD)
        text = msg.as_string()
        server.sendmail(GMAIL_USER, ALERT_EMAIL, text)
        server.quit()
        print("メールが正常に送信されました!")
    except Exception as e:
        print(f"メールの送信に失敗しました: {e}")

# Lambda関数をテストする際に便利なエントリーポイント
if __name__ == "__main__":
    lambda_handler(None, None)

こぴぺしたら、
BUCKET_NAME = 'S3のバケット名'
GMAIL_USER = 'メールアドレス'
GMAIL_PASSWORD = 'メールアドレスのアプリパスワード'
ALERT_EMAIL = '送り先メールアドレス'
AWS_S3_REGION = 'AWS S3のリージョン'
の部分を適切な値に書き換えて、デプロイを押してね。

4. テストする

テストを作成する
テスト
呼び出すを押したらうごくよ!

うまく動いたら、ハードコーディングしているところを環境変数にかきなおしてね。

5. イベントブリッジを設定する

毎日同じ時間に動くように設定するよ。
「トリガーを追加」ボタンを押してね。


こんな感じに設定してみて、「追加」を押すよ

おわりに

これで安心だね!!

Discussion