ちょっと話題の記事

EC2やRDS、ELBの停止忘れ、削除し忘れを防ぐ!LambdaScheduleイベント #reinvent

2015.10.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

この記事は古いのでこちらを御覧ください!!

コンニチハ。千葉です。

突然ですが、開発環境などで使っているEC2やRDS、ELBを停止し忘れた、消し忘れた!という経験をお持ちの方へ。

私、よくパソコン抱っこしながら寝落ちするのですが、ELBを作成しっぱなし、課金発生してた!ということがあります。

無駄にお金を払わないように、インスタンス停止や不要なリソースの削除はコマメに行いたいところです。

そんな中、新しくLambdaScheduleイベントがリリースされました。これは使うしかない!ということで、リソースの状況を教えてくれるツールを作ってみました。

構成

money-info-0

Lambdaで1日1回スケジュールをトリガーに発火させます。 そこで、EC2、RDS、ELBの起動状況を取得、SNS経由からメールで通知してくれます。

リソースが起動している場合は、こんな感じでメールがきます。逆にリソースが起動していない時は、メールは来ません!

money-info-13

作ってみた

SNSの作成

まず、メール送信するためにSNSトピックを作成します。

SNSの画面から、[Topics] > [Create new topic]を選択します。

money-info-1

[Topic name]と[Display name]を入力します。

money-info-2

リソース状況の通知先のメールアドレスを設定します。先ほど作成した、トピックにチェックを入れ、[Actions] > [Subscribe to topic]を選択します。

money-info-3

[Email]を選択し、通知先のメールアドレスを入力します。

money-info-4

先ほど入力したメール宛に、購読するかの確認メールが来ます。[Confirm subscription]をクリックして購読登録します。

money-info-12

SNS側でメールアドレスが購読状態になっているかを確認します。トピック一覧より、対象トピックのARNをクリックします。 また、ARNは後で使うのでメモっておきます。

money-info-5

[Subscription ID]が[arn:aws:sns:〜]、[Endpoint]に登録したメールアドレスが表示されているかを確認します。

これで、SNSの作成は完了です。

money-info-6

Lambdaファンクションの作成

今回は、Pythonでコードを記述します。 それではLambdaファンクションを作成していきます。

[Create a Lambda function]をクリックし、Lambdaファンクションを作成していきます。

money-info-14

[Skip]をクリックします。

money-info-8

[Name]、[Description]を入力し、[Python]を選択します。

money-info-15

[Lambda function code]には、下記のコードを入力します。

[TOPIC_ARN]には、先ほど作成したSNSトピックのARN(先ほどメモしたもの)を入力します。

import boto3

TOPIC_ARN = 'arn:aws:sns:ap-northeast-1:XXXX:XXXX'

def lambda_handler(event, context):
try:
# Check for EC2
ec2 = boto3.client('ec2')
ec2_resp = ec2.describe_instances(Filters=[{'Name':'instance-state-name','Values':['running']}] )

ec2_count = len(ec2_resp['Reservations'])

if not ec2_count == 0:
send_message.append("[EC2 is running!!]")
for i in range(0, ec2_count):
send_message.append(ec2_resp['Reservations'][i]['Instances'][0]['Tags'][0]['Value'])
send_message.append("")

# Check for ELB

elb = boto3.client('elb')
elb_resp = elb.describe_load_balancers()

elb_count = len(elb_resp['LoadBalancerDescriptions'])

if not elb_count == 0:
send_message.append("[ELB is running!!]")
for i in range(0, elb_count):
send_message.append(elb_resp['LoadBalancerDescriptions'][i]['LoadBalancerName'])
send_message.append("")

# Check for RDS

rds = boto3.client('rds')
rds_resp = rds.describe_db_instances()

rds_count = len(rds_resp['DBInstances'])

if not rds_count == 0:
send_message.append("[RDS is running!!]")
for i in range(0, rds_count):
send_message.append(rds_resp['DBInstances'][i]['DBInstanceIdentifier'])
send_message.append("")

# Send mail

send_subject = "[AWS]Money Save"
send_message = ["Please check resources...\n"]

for i in send_message:
print(i)

sns = boto3.client('sns')

sns_resp = sns.publish(
TopicArn = TOPIC_ARN,
Message = "\n".join(send_message),
Subject = send_subject
)
return 0
except Exception as e:
print(e)
print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
raise e

[Lambda function handler and role] > [Role]にて、今回用のRoleを作成します。

[Basic execution role]を選択します。

money-info-9

ロールの作成画面が表示されます。(chromeではポップアップの許可が必要だったため、適宜許可します)

[IAM ロール]は[新しいIAMロールの作成]を選択、[ロール名]を入力します。

[編集] > [OK]をクリックします。

money-info-10

ポリシードキュメントには、以下を入力します。

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"rds:DescribeDBInstances",
"elasticloadbalancing:DescribeLoadBalancers",
"sns:Publish",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}

[Advanced settings]で、Lambda実行時間のタイムアウトを[30秒]にします。

[Next]をクリックします。

money-info-11

設定内容を確認し、[Create function]をクリックします。

money-info-16

テスト実行してみます。[Save and test]をクリックします。

money-info-17

Lambdaファンクションが実行されます。下にスクロールし、実行結果を確認し[succeeded]となっていることを確認します。

money-info-18

ここで、

  • EC2インスタンスが"起動"している
  • ELBが"存在"している
  • RDSインスタンスが"存在"している

場合、登録したメールアドレスにメールが来ます。

money-info-13

あとは、1日1回スケジュール実行するようにトリガーの設定をして終わりです。

[Event sources]タブを選択し、[Add event source]をクリックします。

money-info-19

[Ebvent source type]で[Scheduled Event]を選択。[Schedule expression]で[rate(1 day)]を選択します。

[Submit]をクリックして設定完了です。

money-info-20

あとは、リソースが起動している場合は日時でメールが来ます。

さいごに

Lambdaスケジュール、とっても便利です。スナップショット等、cron専用に立てていたサーバの代替としても利用できそうです。