📑

Lambda+EventBridge(CloudWatch Events)でEC2とRDS(Aurora)を自動で起動/停止させる

2022/08/23に公開

EC2

EC2を作成しておく

起動、停止を行うためのEC2インスタンスを1台起動しておきます。

Lambda関数を作成する

Lambda関数を作成します。言語は何でもいいですが、Python3.8にして、実行ロールは「基本的な Lambda アクセス権限で新しいロールを作成」を選択します。これは後ほど編集します。

作成できたら、ソースコードを以下のように編集しDeployボタンで保存します。eventが入力値で、actionというキーの値が"start"だったら起動、"stop"だったら停止するようにします。
regionとinstancesは作成したEC2に合わせて編集してください。

lambda_function.py
import boto3

region = 'us-west-1'
instances = ['EC2のインスタンスID']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    if event['action'] == "start":
        ec2.start_instances(InstanceIds=instances)
        print('started your instances: ' + str(instances))   
    elif event['action'] == "stop":
        ec2.stop_instances(InstanceIds=instances)
        print('stopped your instances: ' + str(instances))
    
    return event['action']

テストイベントを作成し保存しておきます。

{
  "action": "stop"
}

IAMロールを編集する

Lambda関数の作成はできましたが、これだけでテストを実行しても失敗します。

An error occurred (UnauthorizedOperation) when calling the StopInstances operation: You are not authorized to perform this operation.

LambdaからEC2への権限が足りていないので、IAMロールを編集します。
Lmabda関数の設定タブから使用しているIAMロールを確認できます。

IAMロールの設定画面から許可を追加>インラインポリシーを作成
を選択します。

jsonで以下のように編集します。確認でサクッと使うだけ場合は、"Resource":"*"とかでも。
lightkun-ec2-start-stop-policyという名前で保存します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:Start*",
                "ec2:Stop*"
            ],
            "Resource": "arn:aws:ec2:[EC2が起動しているリージョン名]:[AWSアカウントID]:instance/[EC2のインスタンスID]"
        }
    ]
}

これで、再度Lambda関数に戻ってテストを実行してみます。実行後、EC2が停止していることを確認できれば成功です。

今後はEC2を起動するようにテストイベントを以下のように編集します。

{
  "action": "start"
}

保存して、再度テストを実行し、EC2が起動していることを確認できれば成功です。

EventBridge(CloudWatch Events)を作成する

起動停止はできたので、これを自動化させるため、EventBridge(CloudWatch Events)を作成します。

EventBridge>ルール>ルールの作成
から作成していきます。

今回は毎日5:30(UTC)にEC2を起動するように設定します。

cronの設定については次のドキュメントが参考になります。

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-create-rule-schedule.html#eb-cron-expressions

ターゲットには先程作成したlambda関数を指定します。

jsonでテストイベントで指定したように{"action": "start"}を設定します。

タグは特に設定せず、保存します。

EC2を事前に停止しておいて、時間になったらLambdaが実行されてEC2が起動していたら、成功です。
Lambdaが正しく動いているかはCloudwatchにlambdaのロググループが作成されているはずなので、ログが残っているかをチェックします。

同様に次は停止用のルールを作成します。
先程と異なるのは、ルール名、cronの時間、jsonを{"action": "stop"}に設定するくらいです。

cronの時間後にEC2が停止していたら成功です。

RDS(Aurora)

RDS(Aurora)を作成しておく

起動、停止を行うためのAuroraクラスターをインスタンスは1台で起動しておきます。

Lambda関数を作成する

EC2のときとほぼ同様です。

lambda_function.py
import boto3

region = 'us-west-1'
db_cluster_identifier = '[AuroraのDBクラスター識別子]'
rds = boto3.client('rds', region_name=region)

def lambda_handler(event, context):
    if event['action'] == "start":
        rds.start_db_cluster(DBClusterIdentifier=db_cluster_identifier)
        print('started your cluster: ' + str(db_cluster_identifier))   
    elif event['action'] == "stop":
        rds.stop_db_cluster(DBClusterIdentifier=db_cluster_identifier)
        print('stopped your cluster: ' + str(db_cluster_identifier))
    
    return event['action']

テストイベントを作成し保存しておきます。

{
  "action": "stop"
}

IAMロールを編集する

Lambda関数に既にアタッチしてあるIAMロールにlightkun-rds-start-stop-policyという名前のインラインポリシーを追加します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "rds:StartDBCluster",
                "rds:StopDBCluster"
            ],
            "Resource": "arn:aws:rds::[RDSが起動しているリージョン名]:[AWSアカウントID]:cluster/[AuroraのDBクラスター識別子]"
        }
    ]
}

これで、再度Lambda関数に戻ってテストを実行してみます。実行後、RDSが停止していることを確認できれば成功です。

今後はRDSを起動するようにテストイベントを以下のように編集します。

{
  "action": "start"
}

保存して、再度テストを実行し、RDSが起動していることを確認できれば成功です。

EventBridge(CloudWatch Events)を作成する

EventBridgeもEC2とほぼ同じような設定です。
まずはRDSを起動させるルールを作成します。

停止のルールも作成します。

これでRDSが自動で起動・停止してくれます。

参考

https://aws.amazon.com/jp/premiumsupport/knowledge-center/start-stop-lambda-eventbridge/

https://www.blog.danishi.net/2021/04/20/post-4852/

株式会社ゆめみ

Discussion