0
0

[Amazon Web Services]LambdaでEC2の定期停止設定してみた

Posted at

最近、個人AWSアカウントを活発に利用しており、EC2インスタンス台数が増加してきました。その中で、EC2利用後、ついついインスタンス停止を忘れてしまっており、余計なコストが発生しております。そこでLambdaを利用し、EC2の定期停止設定をしてみました。

LambdaによるEC2定期停止設定の前提

- 対象リージョンはバージニア北部であること(後続のコードを修正することで変更可能)
- 定期停止対象のEC2に対して、タグ[key:EC2Auto_Stop, value:true]が付与済みであること

Lambda実行用IAMポリシー作成

まずはLambda実行用IAMポリシーを作成していきます。

1.IAMコンソール>左ペイン「IAMポリシー」>右上「ポリシーの作成」を押下
image.png

2.[アクセス許可を指定]にて、JSONで下記の権限設定を実施し、「次へ」をクリック

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:Describe*",
                "ec2:Stop*"
            ],
            "Resource": "*"
        }
    ]
}

3.[確認して作成]にて以下のように値を入力し、「ポリシーの作成」をクリック

ポリシー名:EC2AutoStop_Lambda_Policy
説明:EC2AutoStop_Lambda_Policy

image.png

一般的に、Lambda用のIAMポリシーを作成する際は下記に留意する
- 最低でもログ出力用にCloudWatch Logsへのアクセス許可が必要となる
- 最小権限の原則
⇛Lambda実行用IAMポリシーは複数のLambda間で共有しないのがベター

Lambda実行用IAMロール作成

前節にて作成したIAMポリシーを使用し、Lambda実行用IAMロールを作成します。

4.IAMコンソール>左ペイン「IAMロール」>右上「ロールを作成」を押下

5.[信頼されたエンティティを選択]にて、Lambdaを選択して「次へ」を押下
image.png

6.[許可を追加]にて、EC2AutoStop_Lambda_Policyを選択して「次へ」を押下
image.png

7.[名前、確認、および作成」にて以下のように値を入力し、「ロールの作成」をクリック

ロール名:EC2AutoStop_Lambda_Role
説明:EC2AutoStop_Lambda_Role

EC2定期停止用のLambdaを作成

いよいよEC2定期停止用のLambdaを作成です。

8.Lambdaコンソール>左ペイン「関数」>右上「関数の作成」を押下

9.[関数の作成」にて以下の値を入力し、右下「関数の作成」を押下

関数名:EC2AutoStop_Lambda
ランタイム:Python3.12
アーキテクチャ:x86_64
実行ロール:EC2AutoStop_Lambda_Role

10.Lambdaコンソール>左ペイン「関数」>EC2AutoStop_Lambdaを選択

11.[コードソース]タブに移動し、下記の値を入力したのち「Deploy」を押下

import boto3

#定数定義
REGION = 'us-east-1' #定期停止対象EC2のリージョンに応じて変更してください

def lambda_handler(event, context):
    #EC2クライアントの作成
    ec2 = boto3.client('ec2', region_name=REGION)
    
    #タグ名:EC2Auto_Stop 値:true のEC2インスタンスIdを取得
    response = ec2.describe_instances(
        Filters=[
        {
            'Name': 'tag:EC2Auto_Stop',
            'Values': [
                'true',
            ],
        },
    ],
    )
    
    #print("EC2describeコマンドの出力結果↓")
    #print(response)
    
    # インスタンスIDのみ取得
    instance_ids = []
    for reservation in response["Reservations"]:
        for instance in reservation["Instances"]:
            instance_ids.append(instance["InstanceId"])
    
    #インスタンスIdの出力
    #print("インスタンスIdのみ出力")
    #print(instance_ids)
    
    #EC2インスタンス停止処理
    for instance_id in instance_ids:
        try:
            ec2.stop_instances(InstanceIds=[instance_id])
            print(f"{instance_id}の停止に成功しました")
        except ClientError as errorInstance:
            print(f"{instance_id}の停止に失敗しました")
            print({errorInstance})

    return 0

image.png

上記コードは、以下ウェブサイトを参考に記述しました。

【初心者向け】無料でPythonの基本文法を5時間で学ぼう!
https://qiita.com/AI_Academy/items/b97b2178b4d10abe0adb

Boto3 1.35.19 ドキュメント
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html

12.[設定]タブ>左ペイン「一般設定」>「編集」にて、実行タイムアウトを15分に変更

13.[テスト]タブに移動し、下記スクリーンショットのようにテスト設定を保存
image.png

14.テスト実行
image.png

image.png

Lambda定期実行用のEventルール作成

最後にLambda定期実行用のEventルールを作成します。

15.EventBridgeコンソール>左ペイン「ルール」>「ルールを作成」を押下

16.[ルールの詳細を定義]にて、下記スクリーンショットのように設定し「続行してルールを作成」を押下
image.png

17.[スケジュールを定義]にて、下記スクリーンショットのように設定し「次へ」を押下
image.png

18.[ターゲットを選択]にて、下記スクリーンショットのように設定し「次へ」を押下
image.png

19.[タグを設定]にて「次へ」を押下

20.[レビューと作成」にて「ルールの作成」を押下

終わり

LambdaでEC2の定期停止設定をしてみました。
自分が忘れっぽいだけかもしれませんが、EC2停止忘れってあるあるだと思っています。
特に個人環境は管理が雑になりがちですので、ちょっとした手間を大事にしたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0