0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Lambdaで特定のサブネットのインスタンスを自動停止する方法

Last updated at Posted at 2023-07-28

はじめに

当チームではテスト環境等の社内利用用途を目的としたEC2インスタンスは業務時間内しか利用しないことが多いため、深夜帯や休日に稼働し続け無駄なコストがかかってしまうことがあります。
そういった不要なコストを抑えるためにテスト環境専用のサブネットを用意し、定時でサブネット内のすべてのインスタンスを停止する機能があると便利だなと思っていました。
件数が少ない時期はAmazon EventBridgeでルールを作成し個別で自動停止の設定をしていましたが、件数が増えるにつれ一括の設定が必要になり構築することにしました。

今回はLambdaを使って構築をしましたので設定方法を記述します。

構築イメージ

AWSサービス全体の構築イメージは以下の図の通りです。
image.png
今回設定方法を記述するのは以下の工程です。

  • AWS EventBridgeで毎日PM10:00に指定のLambdaを実行するルールを設定する
  • Lambdaで対象のサブネット配下にあるEC2インスタンスすべてを停止する関数を設定する
  • IAM RoleでLambdaがEC2インスタンスを操作する権限を付与する

やってみる

AWS EventBridgeの設定

ルールを新規作成します。
UIに従って設定していくので特に難しい点はないと思います。
Cronが日本時間と9時間差があるので注意です。
image.png

ターゲットは作成するLambdaを選択します。
image.png

Lambdaの設定

停止対象のサブネットIDにあるインスタンスを配列で取得し、すべて停止する処理をpythonで記述します。
IAMRoleが正しく設定されていないとインスタンスの情報を取得できないのでお気を付けください。

import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    subnet_id = 'subnet-xxxxxxxxxxx'  # 停止対象のサブネットIDを指定
    
    response = ec2.describe_instances(
        Filters=[
            {'Name': 'subnet-id', 'Values': [subnet_id]},
            {'Name': 'instance-state-name', 'Values': ['running']}
        ]
    )
    
    instance_ids = []
    for reservation in response['Reservations']:
        for instance in reservation['Instances']:
            print(instance)
            instance_ids.append(instance['InstanceId'])

    if instance_ids:
        stop_response = ec2.stop_instances(InstanceIds=instance_ids)
        print(stop_response)
        return stop_response
    
    else:
        return null

トリガーの設定をします。
EventBridgeで作成したルールを設定してください。
image.png

IAM Roleの設定

インスタンスの表示・停止権限を付与します。
以下のコードを設定したIAMポリシーをIAM Roleに紐づけます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EC2DescribeInstances",
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*"
        },
        {
            "Sid": "EC2StopInstances",
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:DescribeInstances"
            ],
            "Resource": "*"
        }
        ]
}

以上の設定をすることで毎日PM22:00に対象サブネット内のインスタンスが自動停止されます。

おわりに

今までインスタンスを個別で管理していたので工数がかかっていたのですが、サブネット単位で管理できると大分工数削減につながるなと感じました。
また、野良インスタンスがずっと起動しっぱなしで不要なコストがかかってしまうことも回避できるので有用だと思いました。
本稿の内容だけで運用・管理できるわけではないので明確なオペレーションを策定していきたいと思います。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?