Lambda+EventBridge(CloudWatch Events)でEC2とRDS(Aurora)を自動で起動/停止させる
EC2
EC2を作成しておく
起動、停止を行うためのEC2インスタンスを1台起動しておきます。
Lambda関数を作成する
Lambda関数を作成します。言語は何でもいいですが、Python3.8にして、実行ロールは「基本的な Lambda アクセス権限で新しいロールを作成」を選択します。これは後ほど編集します。
作成できたら、ソースコードを以下のように編集しDeployボタンで保存します。eventが入力値で、actionというキーの値が"start"
だったら起動、"stop"
だったら停止するようにします。
regionとinstancesは作成したEC2に合わせて編集してください。
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の設定については次のドキュメントが参考になります。
ターゲットには先程作成したlambda関数を指定します。
jsonでテストイベントで指定したように{"action": "start"}
を設定します。
タグは特に設定せず、保存します。
EC2を事前に停止しておいて、時間になったらLambdaが実行されてEC2が起動していたら、成功です。
Lambdaが正しく動いているかはCloudwatchにlambdaのロググループが作成されているはずなので、ログが残っているかをチェックします。
同様に次は停止用のルールを作成します。
先程と異なるのは、ルール名、cronの時間、jsonを{"action": "stop"}
に設定するくらいです。
cronの時間後にEC2が停止していたら成功です。
RDS(Aurora)
RDS(Aurora)を作成しておく
起動、停止を行うためのAuroraクラスターをインスタンスは1台で起動しておきます。
Lambda関数を作成する
EC2のときとほぼ同様です。
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が自動で起動・停止してくれます。
参考
Discussion