みなさん、AWSのコスト削減やっていますでしょうか?今回はうっかり見落としがちな、EIPの消し忘れを通知する仕組みをご紹介します。
はじめに
AWSを使用していると、Elastic IP(EIP)を割り当てることがあります。しかし、検証環境などにおいては、EIPを作ったもののそのままにしてしまっていることが見受けられます。
インスタンスに関連付けられていない未使用のEIPがあると、コストがかかるため、適切に管理することが重要です。本記事では、未使用のEIPを自動的にチェックして通知するLambda関数を作成する方法を紹介します。この仕組みを導入することで、コスト削減やリソースの最適化が図れます。
前提条件
AWSの運用を担当する立場を想定しているので、下記の必要なものを準備してください。
必要なもの
- AWSアカウント
- IAMロール(適切な権限が付与されていること)
- AWS管理コンソールへのアクセス
IAMロールとポリシーの設定
まずは、Lambda関数がEC2およびSNSにアクセスできるように、以下の権限を持つIAMポリシーとロールを作成します。
IAMポリシーの作成
- AWS管理コンソールにログインし、IAMサービスに移動します。
- 左側のナビゲーションペインで「ポリシー」を選択し、「ポリシーの作成」をクリックし、ポリシーエディタを「JSON」とし、以下のJSONポリシーを入力します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeAddresses",
"sns:Publish"
],
"Resource": "*"
}
]
}
- 「次へ」を押し、ポリシーに名前(例:
UnusedEIPLambdaPolicy
)を付けて「ポリシーの作成」ボタンをクリックします。他はデフォルトで構いませんが、必要に応じて追加してください。
IAMロールの作成
- 左側のナビゲーションペインで「ロール」を選択し、「ロールを作成」ボタンをクリックします。
- 信頼されたエンティティのタイプで「AWSサービス」を選択し、ユースケースでは「Lambda」を選択し、「次へ」をクリックします。
- 先ほど作成したポリシーにチェックを入れ、「次へ」を押下します。(例:
UnusedEIPLambdaPolicy
) - ロールに名前(例:
UnusedEIPLambdaRole
)を付けて「ロールを作成」ボタンをクリックします。
このロールは、Lambda関数がEC2およびSNSサービスにアクセスするために使用されます。
SNSトピックの作成
通知にはSNSによるメール通知を使用します。
SNSトピックの設定
- AWS管理コンソールにログインし、SNSサービスに移動します。
- 左メニューからトピックを選択し「トピックの作成」ボタンをクリックします。
- タイプは「スタンダード」を選択し、トピック名として「UnusedEIPNotifications」などを入力し、トピックARNをコピーします。
※Lambda関数の環境変数SNS_TOPIC_ARN
に、このARNを設定します。
SNSによる通知設定
- 作成したトピック画面で「サブスクリプションの作成」ボタンをクリックします。
- プロトコルとして「Email」を選択し、エンドポイントに通知を受け取りたいメールアドレスを入力します。
- 「サブスクリプションの作成」ボタンをクリックします。
- 登録したメールアドレスに確認メールが送信されるので、メール内のリンクをクリックして購読を確認します。
これで、SNSトピックに通知が送信された際に、設定したメールアドレスで通知を受け取ることができます。
Lambda関数の作成と設定
Lambda関数の作成
- AWS管理コンソールにログインし、Lambdaサービスに移動します。
- 「関数の作成」ボタンをクリックします。
- 関数名として「CheckUnusedEIPFunction」などを入力し、ランタイムとして「Python 3.x」(2024年5月時点ではPython 3.12)を選択します。
- 先ほど作成したIAMロールを選択し、「関数の作成」ボタンをクリックします。
環境変数の設定
作成したLambda関数に環境変数を設定します。SNSトピックのARNを環境変数SNS_TOPIC_ARN
として設定します。
- 作成したLambda関数の「設定」タブに移動します。
- 「環境変数」セクションにある「環境変数の編集」ボタンをクリックします。
- 「キー」に
SNS_TOPIC_ARN
を入力し、「値」に先ほどコピーしたSNSトピックのARN(例:arn:aws:sns:ap-northeast-1:123456789012:UnusedEIPNotifications
)を入力します。 - 「保存」ボタンをクリックして設定を保存します。
以上で、Lambda関数はSNSトピックに通知を送信するための情報を持つようになります。
コードの実装
Lambda関数に以下のコードを実装します。このコードは、未使用のEIPをチェックし、見つかった場合にSNSトピックに通知します。
import boto3
import os
def lambda_handler(event, context):
ec2 = boto3.client('ec2')
sns = boto3.client('sns')
topic_arn = os.environ['SNS_TOPIC_ARN']
addresses = ec2.describe_addresses()
for address in addresses['Addresses']:
if 'InstanceId' not in address and 'NetworkInterfaceId' not in address:
message = f"未使用のEIPが見つかりました: {address['PublicIp']}"
print(message)
sns.publish(
TopicArn=topic_arn,
Message=message,
Subject='未使用のEIP通知'
)
return {
'statusCode': 200,
'body': '未使用のEIPの通知が送信されました'
}
テストとデプロイ
では、作成した仕組みが実際に動作するかをテストしてみましょう。テストを行うことで、Lambda関数が期待通りに動作し、未使用のEIPを正しく検出して通知を送信できることを確認します。
Lambda関数のテスト
-
Lambda関数のコンソールでテストタブに移動する
- AWS管理コンソールにログインし、Lambdaサービスに移動します。
- 作成したLambda関数を選択し、詳細画面に移動します。
- 「テスト」タブに移動します。
-
テストイベントの設定
-
「テストイベントの設定」ボタンをクリックします。
-
テストイベントに名前を付け(例えば、「TestEvent」)、以下のような簡単なJSONデータを入力します。
{ "key1": "value1", "key2": "value2", "key3": "value3" }
-
このデータは実際の処理には影響を与えませんが、Lambda関数のトリガーとして使用されます。
-
-
テストの実行
- 「テスト」ボタンをクリックして、Lambda関数を実行します。
- 実行結果を確認し、関数が正常に動作しているかをチェックします。具体的には、未使用のEIPが見つかった場合、SNSトピックに通知が送信されることを確認します。
- Timeoutが発生する場合は、設定タブの一般設定から「編集」を押下し、タイムアウトを30秒などにします。
CloudWatchログの確認
Lambda関数の実行結果を詳細に確認するために、CloudWatchログを参照します。
- CloudWatchログの確認
- AWS管理コンソールでCloudWatchサービスに移動します。
- 左側のナビゲーションペインで「ロググループ」を選択し、Lambda関数のロググループを選びます(通常は関数名に基づいた名前になっています)。
- 最新のログストリームを開き、実行結果の詳細なログを確認します。
これにより、Lambda関数が正常に動作し、未使用のEIPを検出して通知を送信するプロセスが正しく実行されていることを確認できます。
定期実行の設定
EventBridgeを使用して、定期的にLambda関数を実行するスケジュールを設定します。
-
ルールの作成
-
AWS Eventbridgeに移動し、左メニューからスケジュールを選択し、「スケジュールの作成」をクリックします。
-
スケジュール名を入力し(例:
UnusedEIPSchedule
)、Cronまたはレート式を設定します。例:毎日午前3時に実行するCron式
cron(0 3 * * ? *)
-
トリガー日を確認して問題なければ、フレックスタイムウィンドウを「5分」などとし、「次へ」
-
-
ターゲットの設定
- テンプレート化したターゲットからAWS Lambda Invokeを選択します。
- Lambda関数として先ほど作成したLambda関数を選択し、「次へ」を押下。
-
設定 - オプション
- デフォルトで良いので「次へ」を押下
- 確認画面で「スケジュールを作成」ボタンをクリックして設定を保存します。
これで、定期的にLambda関数が実行され、未使用のEIPを自動的にチェックし、通知する仕組みが完成しました。
未使用EIPのリリース
ここからは応用です。未使用のEIPを通知するだけでなく、自動的にリリースすることで手間を減らすことができます。以下のコードを参考にして、EIPをリリースする機能を追加できます。
import boto3
import os
def lambda_handler(event, context):
ec2 = boto3.client('ec2')
sns = boto3.client('sns')
topic_arn = os.environ['SNS_TOPIC_ARN']
addresses = ec2.describe_addresses()
for address in addresses['Addresses']:
if 'InstanceId' not in address and 'NetworkInterfaceId' not in address:
message = f"未使用のEIPを解放しました: {address['PublicIp']}"
print(message)
sns.publish(
TopicArn=topic_arn,
Message=message,
Subject='未使用のEIP解放通知'
)
# 追記部分:EIP解放
ec2.release_address(AllocationId=address['AllocationId'])
return {
'statusCode': 200,
'body': '未使用のEIPが通知され、解放されました'
}
このコードでは、未使用のEIPが見つかった場合に、それを自動的にリリースします。この追加機能により、不要なコストを削減し、AWSリソースの最適化が図れます。
まとめ
この記事では、未使用のElastic IP(EIP)を自動的にチェックし、通知するAWS Lambda関数の作成方法を紹介しました。この仕組みにより、コストの削減やリソースの最適化が図れます。AWSリソースを効率的に管理するために、ぜひ導入してみてください。また、このコードだとシンプルすぎてEIP毎にメールが送られますので、その辺はまとめて通知するようにLambdaのロジックを工夫してみてください。
【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。
「フリーランスエンジニア」
近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。
「成功する人とそうでない人の違いは何か?」
私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。
比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。
多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、
エンベーダー編集部
エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。
関連記事
2020.02.25
完全未経験からエンジニアを目指す爆速勉強法
USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
- キャリア・学習法
- エンジニア
2022.12.30
【AWS】Amazon S3イベント通知の活用法
S3バケットで特定のイベントが発生したときにAWSの他のサービスに通知することが出来ます。
- AWS
2024.07.15
【Terraformハンズオン】CloudFrontにACMで発行したSSL証明書を紐付けてみよう
CloudFrontを作成する際、デフォルトのSSL証明書をアタッチすることが可能ですが、独自に発行したSSL証明書をアタッチすることでカスタムドメインを使用することができます。
- AWS
2023.08.30
Terraformの組み込み関数とは?elementやlookupなどの基本構文と使用例を学ぶ
こちらの記事では、Terraformの組み込み関数についての基本的な構文と使用例について解説します。
- インフラエンジニア
- AWS