AWSで起動しているインスタンスをPythonでチェックしてSlackに投稿する
AWSで起動しているインスタンスをPythonでチェックしてSlackに投稿する:
Pythonのお勉強とEC2インスタンス停止忘れ防止のため、起動しているEC2インスタンスをチェックしてSlackに投稿するようにしたメモ。
と基本的に同じ。
以下の先人の記事を参考に作成。
以下を参考にWebhook URLを取得する。
Pythonの前にAWS CLIで起動しているインスタンスを確認してみる。
AWS CLIをセットアップする。
インスタンスを確認する。
AWS Lambda上のPythonからSlackに投稿する。
IAMコンソールでRoleを作成する。
作成したRoleのARNを確認しておく。
作成するファイルは以下の3つ。
lambda-uploaderをインストールする。
アップロードする。
関数の設定で、トリガーとしてCloudWatch Eventsを追加する。
スケジュールを設定する。確認のためとりあえず
Slackに投稿されることを確認する。
上手く投稿できなかったら、CloudWatch Logsでログを確認する。上手く投稿が確認できたら、CloudWatch Eventsでスケジュールを
Pythonのお勉強とEC2インスタンス停止忘れ防止のため、起動しているEC2インスタンスをチェックしてSlackに投稿するようにしたメモ。
と基本的に同じ。
参考リンク
以下の先人の記事を参考に作成。
動作イメージ
Slackの準備
Webhook URLの取得
以下を参考にWebhook URLを取得する。
AWS CLI
Pythonの前にAWS CLIで起動しているインスタンスを確認してみる。AWS CLIをセットアップする。
pip3 install awscli aws configure
コマンド
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running"
Python + AWS Lambda
AWS Lambda上のPythonからSlackに投稿する。
Roleの作成
IAMコンソールでRoleを作成する。AWSLambdaBasicExecutionRole
、CloudWatchReadOnlyAccess
、AmazonEC2ReadOnlyAccess
のポリシーをアタッチする。作成したRoleのARNを確認しておく。
コード作成
作成するファイルは以下の3つ。├── lambda.json ├── lambda_function.py └── requirements.txt
lambda.json
はlambda-uploderが使用するJSON形式のLambda関数の定義ファイル。先ほど作成したRoleのARN、Slack Webhook URL、Slackチャンネル名を指定する。lambda-uploaderの使い方と、jsonの書き方は以下を参照。lambda.json
{ "name": "aws_instance_checker", "description": "My AWS instance checker.", "region": "ap-northeast-1", "runtime": "python3.7", "handler": "lambda_function.lambda_handler", "role": "arn:aws:iam::hogehoge", "timeout": 300, "memory": 128, "variables": { "SLACK_WEBHOOK_URL": "https://hooks.slack.com/services/hogehoge", "SLACK_CHANNEL": "#hogehoge" } }
lambda_function.py
が関数本体。以下を参考に作成。lambda_function.py
import datetime import os import json import boto3 import pytz import requests SLACK_WEBHOOK_URL = os.environ['SLACK_WEBHOOK_URL'] SLACK_CHANNEL = os.environ['SLACK_CHANNEL'] def get_instances(): """boto3を使って全てのリージョンで起動しているEC2インスタンスを取得する :return: instances """ # 全リージョンを取得 client = boto3.client('ec2') regions = client.describe_regions()['Regions'] instances = [] # 各リージョン毎に繰り返し for region in regions: client = boto3.client('ec2', region_name=region['RegionName']) response = client.describe_instances( Filters=[ { 'Name': 'instance-state-name', 'Values': [ 'running', ] }, ] ) reservations = response['Reservations'] if not reservations: continue for reservation in reservations: instance = dict() instance['id'] = reservation['Instances'][0]['InstanceId'] tags = reservation['Instances'][0]['Tags'] instance['name'] = 'null' for tag in tags: if tag['Key'] == 'Name': instance['name'] = tag['Value'] instance['type'] = reservation['Instances'][0]['InstanceType'] instance['region'] = region['RegionName'] instances.append(instance) return instances def build_message(instances): """SlackにPOSTするメッセージボディを作成する :param instances: :return: message """ if not instances: return None now = datetime.datetime.now(pytz.timezone('Asia/Tokyo')) text = '{}現在稼働しているEC2インスタンス一覧'.format(now.strftime('%Y年%m月%d日%H時%M分')) atachements_text = '' for instance in instances: atachements_text += 'name: {}, type: {}, id: {}, region: {}\n'.format( instance['name'], instance['type'], instance['id'], instance['region']) atachements = {'text': atachements_text, 'color': 'red'} message = { 'text': text, 'channel': SLACK_CHANNEL, 'attachments': [atachements], } return message def post_message(message): """SlackにPOSTする :param message: :return: """ response = requests.post(SLACK_WEBHOOK_URL, data=json.dumps(message)) response.raise_for_status() def lambda_handler(event, context): instances = get_instances() message = build_message(instances) if message: post_message(message)
requirements.txt
は使用するモジュールの定義。requirements.txt
boto3 pytz requests
アップロード
lambda-uploaderをインストールする。pip3 install lambda-uploader
$ lambda-uploader λ Building Package λ Uploading Package λ Fin $
スケジュール実行
関数の設定で、トリガーとしてCloudWatch Eventsを追加する。スケジュールを設定する。確認のためとりあえず
cron(* * * * ? *)
(毎分実行)を設定する。Slackに投稿されることを確認する。
上手く投稿できなかったら、CloudWatch Logsでログを確認する。上手く投稿が確認できたら、CloudWatch Eventsでスケジュールを
cron(0 * * * ? *)
(毎時)に変更する。
コメント
コメントを投稿