【Lambda】EC2インスタンスやRDSの自動起動/停止設定を実現する

  • 2019年6月2日
  • 2019年7月15日
  • AWS
AWS

こんにちわ。PythonもLambdaも名前しか知らないますのです。
AWSのEC2インスタンスのコスト削減でインスタンスの停止を行いました。
しかし、手動ではどうしても忘れてしまうという状況に。。。面倒ですしね。
そこでEC2やRDSのインスタンスを、指定した時間に起動、停止する設定をLambdaで実現出来るということで試してみました。

利用するAWSの機能

  • Lambda
  • IAM Role
  • CloudWatch Events

Lambda関数を作成する

  1. Lambda>関数の作成をクリック
  2. 関数の作成画面:一から作成を選択

Lambda関数を実行する時間をCloudWatch Eventsで設定する

続いて関数の作成画面からインスタンスを自動停止させる設定を行います。
今回はこんな感じの設定で進めていきます。

  • 関数名:StopEC2Instance
  • ランタイム:Python 3.7
  • アクセス権限:基本的な Lambda アクセス権限で新しいロールを作成
    ※既にIAM Roleを作成している場合、ここで割り当てることも出来ます。

Lambda管理画面より、作成した「StopEC2Instance」をクリックします。
トリガーの設定や起動時間等の設定画面が出てきます。

トリガーの追加:CloudWatch Eventsを選択

続いてトリガーの設定を行います。
今回は以下のように設定しました。

  • ルール:新規ルールの作成
  • ルール名:StopEC2Instance
  • ルールの説明:StopEC2Instance
  • ルールタイプ:スケジュール式 cron(0 12 ? * MON-FRI *)
    ※今回は月曜日〜金曜日の日本時間21時に停止するスケジュールで設定しています。
Lambdaの時間はUTCで指定する必要があるので注意です。日本時間の朝9時前の場合ですと、曜日も変わってくるので曜日ずれちゃうとかあるのでお気をつけください。
Lambda cron設定の参考https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/tutorial-scheduled-events-schedule-expressions.html

EC2/RDSインスタンスを自動で停止する関数を作成する

続いてPythonでインスタンスを停止する関数を記載します。
「StopEC2Instance」をクリックすると、画面下に関数を入力する画面が表示されます。

  • EC2インスタンスを自動停止する関数

import boto3

region = ‘ap-northeast-1’

instances = [‘インスタンスID’,’インスタンスID’]def lambda_handler(event, context):
ec2 = boto3.client(‘ec2’, region_name=region)
ec2.stop_instances(InstanceIds=instances)
print(‘stopped instances: ‘ + str(instances))

  • RDS(Cluster)を自動停止する関数

import boto3

def lambda_handler(event, context):
dbinstances = [‘RDS DB インスタンス識別子’,’RDS DB インスタンス識別子’]rds = boto3.client(‘rds’)
result = rds.stop_db_cluster(DBClusterIdentifier = dbinstances)
print(result)
return 0

  • RDS(インスタンス)を自動停止する関数

import boto3

def lambda_handler(event, context):
dbinstances = [‘RDS DB インスタンス識別子’,’RDS DB インスタンス識別子’]rds = boto3.client(‘rds’)
result = rds.stop_db_instance(DBInstanceIdentifier = dbinstance)
print(result)
return 0

EC2、RDS、RDSクラスターそれぞれの停止方法です。
resultの部分が異なります!停止対象になるものをお好みで設定してくださいね。

EC2/RDSインスタンスを自動起動する関数を作成する

インスタンスを自動停止するLambda関数が作成できました!
続いて、インスタンスを自動起動するLambda関数を作成します。

作り方は自動停止までとほぼ同じです。
以下の2つを自動開始用に「StartEC2Instance」として新たに作成します。

  • Lambda関数を作成する
  • Lambda関数を実行する時間をCloudWatch Eventsで設定する

作成した「StartEC2Instance」をクリックし、以下のPythonの関数を入力します。

  • EC2インスタンスを自動起動する関数

import boto3

region = ‘ap-northeast-1’

instances = [‘インスタンスID’,’インスタンスID’]def lambda_handler(event, context):
ec2 = boto3.client(‘ec2’, region_name=region)
ec2.start_instances(InstanceIds=instances)
print(‘started instances: ‘ + str(instances))

  • RDS(Cluster)を自動起動する関数

import boto3

def lambda_handler(event, context):
dbinstances = [‘RDS DB インスタンス識別子’,’RDS DB インスタンス識別子’]rds = boto3.client(‘rds’)
result = rds.start_db_cluster(DBClusterIdentifier = dbinstance)
print(result)
return 0

  • RDS(インスタンス)を自動起動する関数

import boto3

def lambda_handler(event, context):
dbinstances = [‘RDS DB インスタンス識別子’,’RDS DB インスタンス識別子’]rds = boto3.client(‘rds’)
result = rds.start_db_instance(DBInstanceIdentifier = dbinstance)
print(result)
return 0

IAM Roleに必要な権限を設定する

最後に、これまで作ったLambda関数を自動で実行させるためのIAM Roleを設定します。

IAM管理画面>ロール>[StopEC2Instance….] or [StartEC2Instance…]を選択します。

※Lambda関数の実行ロールで「基本的な Lambda アクセス権限で新しいロールを作成」を選んだ場合、作成したLambda関数の名称で検索すると表示されます。
  1. 「ポリシーをアタッチします」をクリック
  2. ポリシーのフィルター:AmazonEC2FullAccessで検索
  3. AmazonEC2FullAccessを選択し、「ポリシーのアタッチ」をクリック
  4. 下図のような画面になればアタッチ成功です。
  5. Start/Stopどちらも設定して完了です。
RDSの場合は、「AmazonRDSFullAccess」をアタッチします。
ポリシーは実行に必要なものだけ設定することを推奨しています。必要以上に設定しないよう注意が必要です。
わたしの環境ではEC2、RDS別々で作成したので、IAMRoleに別々で設定しました。
以上の設定を行うことで、インスタンスの自動起動、停止を実現できました!
動作ログについては「CloudWatch Events」のログで確認することができますので、設定した時間が過ぎたら確認してみましょう。

余談や感想的な何か

アラートの設定を「Simple Notification Service(SNS)」で出来るようで、一応そちらも実装。
インスタンスタイプの変更も出来るようで、Lambdaは結構便利だなぁと感じた次第です。Pythonワカラン。。。って毛嫌いしていましたが覚えて損は無さそう。

ちなみに今回始めて触ったので起動と停止を別々で作りましたが、一緒にすることも出来るみたい。
試してみたい方はこちら参考にしてみるといいかもです。

できるだけシンプルな仕組みで簡単にEC2の自動起動・停止を実現したい!

最新情報をチェックしよう!