跳到內容

Stop RDS more than 7 days

Scenario

RDS 如需長期關機不使用,每隔 7 天會進行自動開機,爾後需人工關機,因此透過 Lambda 方式,針對特定 Tag 的 RDS,定期七天開機 30 分鐘後再關機,達成此目的。

實做方式

  • 建立 IAM Role 提供 RDS 開關機權限
  • 設定要長期關閉的 RDS Tag,同時所有 RDS 成調整一致維護時間
  • 建立 Lambda Function 與設定定期開關的 Trigger
  • 測試是否能依設定開關機

執行步驟

建立 IAM Role

建立 Policy

點我開啟 IAM Policy 設定畫面後,點選建立 Policy 供後續 Role 使用

Create IAM Policy

點選 JSON 後,貼上以下 Policy 再點選下一步

1
{
2
"Version": "2012-10-17",
3
"Statement": [
4
{
5
"Sid": "VisualEditor0",
6
"Effect": "Allow",
7
"Action": [
8
"rds:StartDBCluster",
9
"rds:StopDBCluster",
10
"rds:ListTagsForResource",
11
"rds:DescribeDBInstances",
12
"rds:StopDBInstance",
13
"rds:DescribeDBClusters",
14
"rds:StartDBInstance"
15
],
16
"Resource": "*"
17
}
18
]
19
}

Input JSON Policy

輸入名稱後點選下一步

Name the Policy

建立 Role

接著點選建立 Role

Create IAM Role

選擇 Lambda 點選下一步

Choose Lambda service

選擇剛剛所建立的 Policy 與點選 AWSLambdaBasicExecutionRole 點選下一步

Select Policies

輸入 Role 名稱

Name the Role

確認所選擇的 Policy 有出現,點選建立

Confirm and Create Role

設定 RDS

設定 RDS Tag

進入 RDS 頁面後,點選欲長期關閉之 instance

Select RDS instance

點選 Tags 欄位,再點選 Manage tags新增 autostart=yes 與 autostop=yes 兩個 tags

Add RDS Tags

設定RDS 維護時間

設定 RDS 需開機狀態才能進行設定,點選 Modify 進行設定

Modify RDS

於設定末端設定維護時間,請留意此為 UTC 時間,非台灣時間,時間長度為 0.5 小時,其他欲長期關閉主機亦如法炮製設定,設定完後點選繼續,並選擇立即套用生效即可

Set Maintenance Window

建立 Lambda Function

建立開機 Lambda

至 Lambda Function 中點選建立

Create Lambda Function

輸入名稱,選擇 Python 3.11,架構選x86_64

Configure Lambda

選擇剛剛所建立的 Role 後點選建立

Select Role for Lambda

貼上以下程式碼,點選 Deploy

Deploy Lambda Code

1
import boto3
2
rds = boto3.client('rds')
3
4
def lambda_handler(event, context):
5
6
#Start DB Instances
7
dbs = rds.describe_db_instances()
8
for db in dbs['DBInstances']:
9
#Check if DB instance stopped. Start it if eligible.
10
if (db['DBInstanceStatus'] == 'stopped'):
11
try:
12
GetTags=rds.list_tags_for_resource(ResourceName=db['DBInstanceArn'])['TagList']
13
for tags in GetTags:
14
#if tag "autostart=yes" is set for instance, start it
15
if(tags['Key'] == 'autostart' and tags['Value'] == 'yes'):
16
result = rds.start_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
17
print ("Starting instance: {0}.".format(db['DBInstanceIdentifier']))
18
except Exception as e:
19
print ("Cannot start instance {0}.".format(db['DBInstanceIdentifier']))
20
print(e)
21
22
23
if __name__ == "__main__":
24
lambda_handler(None, None)

設定逾時時間為 10 秒,點選設定 -> 一般設定 -> 編輯

Edit Lambda Settings

設定 10 秒鐘後存檔即可

Set Timeout

設定定期開機觸發時間,點選 Add Trigger

Add Trigger

  1. 選擇 EventBridge
  2. 建立新規則
  3. 輸入規則名稱
  4. 選擇使用 cron表達式
  5. 官方建議輸入比 RDS 維護時間提前 30 分鐘,但這邊範例則為直接比照 RDS 維護時間輸入cron(0 18 ? * SUN *),時區一樣為 UTC,可點我參考 cron 表達式
  6. 點選增加

Configure Trigger

建立關機 Lambda

所有操作方式與上述開機相同,關機腳本如下

1
import boto3
2
rds = boto3.client('rds')
3
4
def lambda_handler(event, context):
5
6
#Stop DB instances
7
dbs = rds.describe_db_instances()
8
for db in dbs['DBInstances']:
9
#Check if DB instance is not already stopped
10
if (db['DBInstanceStatus'] == 'available'):
11
try:
12
GetTags=rds.list_tags_for_resource(ResourceName=db['DBInstanceArn'])['TagList']
13
for tags in GetTags:
14
#if tag "autostop=yes" is set for instance, stop it
15
if(tags['Key'] == 'autostop' and tags['Value'] == 'yes'):
16
result = rds.stop_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
17
print ("Stopping instance: {0}.".format(db['DBInstanceIdentifier']))
18
except Exception as e:
19
print ("Cannot stop instance {0}.".format(db['DBInstanceIdentifier']))
20
print(e)
21
22
if __name__ == "__main__":
23
lambda_handler(None, None)

測試

點選Test即可進行開機或關機測試

Test Lambda Function

REF How can I use a Lambda function to stop an Amazon RDS instance for longer than seven days?