如何使用 Step Functions 将 Amazon RDS 实例停止 7 天以上?
我想使用 Amazon Step Functions 将 Amazon Relational Database Service (Amazon RDS) 停止 7 天以上。
简短描述
默认情况下,您一次最多可以将 Amazon RDS 数据库实例停止七天时间。七天后,实例会重新启动,以免错过任何维护更新。
要将您的实例停止超过 7 天,您可以使用 Step Functions 来自动执行工作流,而不会错过维护时段。
**注意:**有关替代解决方案,请参阅如何使用 Amazon Lambda 函数将 Amazon RDS 实例停止 7 天以上?
解决方法
配置 IAM 权限
创建一个 Amazon Identity and Access Management (IAM) 策略,用于允许 Step Functions 启动和停止实例并检索有关该实例的信息:
-
打开 IAM 控制台。
-
在导航窗格中,选择策略。然后,选择创建策略。
3. 选择 JSON 选项卡。然后,输入以下策略以便授予所需的 IAM 权限:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "rds:DescribeDBInstances", "rds:StopDBInstance", "rds:StartDBInstance" ], "Resource": "*" } ] }
4. 选择下一步: 标签。
- (可选)要添加标签,请选择添加标签,然后为键和值字段输入相应的值。
6. 选择下一步: 审核。
- 输入策略的名称。例如,输入 step-functions-start-stop-rds-policy。要审核已为策略授予的权限,请参阅摘要部分。
8. 选择创建策略。
有关更多信息,请参阅使用 JSON 编辑器创建策略。
创建 IAM 角色并附加所需的策略
1. 打开 IAM 控制台。
-
在导航窗格中,选择角色。然后,选择创建角色。
-
对于选择受信任实体的类型,选择亚马逊云科技服务。
4.在其他亚马逊云科技服务的用例下拉列表中,选择 **Step Functions **。然后,选择 Step Functions 选项。
5. 选择下一步。
注意:请勿在添加权限页面上执行任何操作。首先创建角色,然后编辑默认权限。
6. 选择下一步。
- 对于角色名称,输入角色的名称。例如,输入 step-functions-start-stop-rds-role。
(可选)更新角色描述。
(可选)要添加标签,请在键和值字段中输入相应的值。
8. 选择创建角色。这样会让您返回到角色列表。
-
在搜索框中,输入您创建的角色的名称。然后,选择该角色以查看其详细信息。
-
在权限选项卡中,选择添加权限下拉列表。然后,选择附加策略。
-
在配置 IAM 权限部分中,输入您创建的策略的名称。例如,输入 step-functions-start-stop-rds-policy。当您看到此策略显示为一个选项时,请将其选中。
-
在权限选项卡中,选择 AWSLambdaRole 亚马逊云科技托管策略,然后选择删除。
有关更多信息,请参阅为亚马逊云科技服务创建角色(控制台)。
为数据库实例添加标签
1. 打开 Amazon RDS 控制台。
2. 在导航窗格中,选择数据库。
-
选择要自动启动和停止的数据库实例。
-
选择标签选项卡。
-
选择添加。对于标签键,输入 autostart。对于值,输入 yes。
-
选择添加其他标签。对于标签键,输入 autostop。对于 “值”,输入 yes。
-
要保存这些标签,请选择添加。
有关更多信息,请参阅添加、列出和删除标签。
创建状态机以启动和停止已标记的数据库实例
1. 打开 Step Functions 控制台。
-
在导航窗格中,选择状态机。然后,选择创建状态机。
-
选择用代码编写工作流。
-
将默认类型保留为标准。
-
在定义编辑器中,删除示例 JSON 定义。然后,输入以下状态机定义:
{ "Comment": "State Machine Definition to start and stop RDS DB instances", "StartAt": "Describe DBInstances to Start", "States": { "Describe DBInstances to Start": { "Type": "Task", "Parameters": {}, "Resource": "arn:aws:states:::aws-sdk:rds:describeDBInstances", "Next": "Iterate on Instances to Start", "Retry": [ { "ErrorEquals": [ "Rds.InternalFailure", "Rds.ServiceUnavailable", "Rds.ThrottlingException", "Rds.SdkClientException" ], "BackoffRate": 2, "IntervalSeconds": 1, "MaxAttempts": 2 } ] }, "Iterate on Instances to Start": { "Type": "Map", "ItemProcessor": { "ProcessorConfig": { "Mode": "INLINE" }, "StartAt": "Format Array before Start", "States": { "Format Array before Start": { "Type": "Pass", "Next": "Check If Instance stopped, if no Tags or if Tags contains 'autostart=yes'", "Parameters": { "DbInstanceStatus.$": "$.DBInstance.DbInstanceStatus", "DbInstanceIdentifier.$": "$.DBInstance.DbInstanceIdentifier", "TagList.$": "$.DBInstance.TagList", "TagsArrayLength.$": "States.ArrayLength($.DBInstance.TagList)", "TagContainsKey.$": "States.ArrayContains($.DBInstance.TagList,$.LookingFor)" } }, "Check If Instance stopped, if no Tags or if Tags contains 'autostart=yes'": { "Type": "Choice", "Choices": [ { "Not": { "Variable": "$.DbInstanceStatus", "StringEquals": "stopped" }, "Next": "Instance is not in 'stopped' status" }, { "Variable": "$.TagsArrayLength", "NumericEquals": 0, "Next": "No Tags found to Start" }, { "Variable": "$.TagContainsKey", "BooleanEquals": true, "Next": "Tags found Start DBInstance" } ], "Default": "No Tags found to Start" }, "Tags found Start DBInstance": { "Type": "Task", "Parameters": { "DbInstanceIdentifier.$": "$.DbInstanceIdentifier" }, "Resource": "arn:aws:states:::aws-sdk:rds:startDBInstance", "Retry": [ { "ErrorEquals": [ "Rds.InternalFailure", "Rds.ServiceUnavailable", "Rds.ThrottlingException", "Rds.SdkClientException" ], "BackoffRate": 2, "IntervalSeconds": 1, "MaxAttempts": 2 } ], "Catch": [ { "ErrorEquals": [ "States.ALL" ], "Next": "Failed to Start DBInstance" } ], "ResultSelector": { "message": "Instance Started", "DbInstanceIdentifier.$": "$.DbInstance.DbInstanceIdentifier" }, "End": true }, "Failed to Start DBInstance": { "Type": "Pass", "Parameters": { "message": "Failed to start instance", "DbInstanceIdentifier.$": "$.DbInstanceIdentifier" }, "End": true }, "No Tags found to Start": { "Type": "Pass", "End": true, "Parameters": { "message": "No Tags found to Start", "DbInstanceIdentifier.$": "$.DbInstanceIdentifier" } }, "Instance is not in 'stopped' status": { "Type": "Pass", "End": true, "Parameters": { "message": "Instance is not in 'stopped' status", "DbInstanceIdentifier.$": "$.DbInstanceIdentifier" } } } }, "InputPath": "$.DbInstances", "Next": "Wait for 1 hour and 30 minutes", "ItemSelector": { "LookingFor": { "Key": "autostart", "Value": "yes" }, "DBInstance.$": "$$.Map.Item.Value" } }, "Wait for 1 hour and 30 minutes": { "Type": "Wait", "Seconds": 5400, "Next": "Describe DBInstances to Stop" }, "Describe DBInstances to Stop": { "Type": "Task", "Parameters": {}, "Resource": "arn:aws:states:::aws-sdk:rds:describeDBInstances", "Retry": [ { "ErrorEquals": [ "Rds.InternalFailure", "Rds.ServiceUnavailable", "Rds.ThrottlingException", "Rds.SdkClientException" ], "BackoffRate": 2, "IntervalSeconds": 1, "MaxAttempts": 2 } ], "Next": "Iterate on Instances to Stop" }, "Iterate on Instances to Stop": { "Type": "Map", "ItemProcessor": { "ProcessorConfig": { "Mode": "INLINE" }, "StartAt": "Format Array before Stop", "States": { "Format Array before Stop": { "Type": "Pass", "Next": "Check If Instance available, if no Tags or if Tags contains 'autostop=yes'", "Parameters": { "DbInstanceStatus.$": "$.DBInstance.DbInstanceStatus", "DbInstanceIdentifier.$": "$.DBInstance.DbInstanceIdentifier", "TagList.$": "$.DBInstance.TagList", "TagsArrayLength.$": "States.ArrayLength($.DBInstance.TagList)", "TagContainsKey.$": "States.ArrayContains($.DBInstance.TagList,$.LookingFor)" } }, "Check If Instance available, if no Tags or if Tags contains 'autostop=yes'": { "Type": "Choice", "Choices": [ { "Not": { "Variable": "$.DbInstanceStatus", "StringEquals": "available" }, "Next": "Instance is not in 'available' status" }, { "Variable": "$.TagsArrayLength", "NumericEquals": 0, "Next": "No Tags found to Stop" }, { "Variable": "$.TagContainsKey", "BooleanEquals": true, "Next": "Tags found Stop DBInstance" } ], "Default": "No Tags found to Stop" }, "Tags found Stop DBInstance": { "Type": "Task", "Parameters": { "DbInstanceIdentifier.$": "$.DbInstanceIdentifier" }, "Resource": "arn:aws:states:::aws-sdk:rds:stopDBInstance", "Retry": [ { "ErrorEquals": [ "Rds.InternalFailure", "Rds.ServiceUnavailable", "Rds.ThrottlingException", "Rds.SdkClientException" ], "BackoffRate": 2, "IntervalSeconds": 1, "MaxAttempts": 2 } ], "Catch": [ { "ErrorEquals": [ "States.ALL" ], "Next": "Failed to Stop DBInstance" } ], "ResultSelector": { "message": "Instance Stopped", "DbInstanceIdentifier.$": "$.DbInstance.DbInstanceIdentifier" }, "End": true }, "Failed to Stop DBInstance": { "Type": "Pass", "Parameters": { "message": "Failed to stop instance", "DbInstanceIdentifier.$": "$.DbInstanceIdentifier" }, "End": true }, "No Tags found to Stop": { "Type": "Pass", "End": true, "Parameters": { "message": "No Tags found to Stop", "DbInstanceIdentifier.$": "$.DbInstanceIdentifier" } }, "Instance is not in 'available' status": { "Type": "Pass", "End": true, "Parameters": { "message": "Instance is not in 'available' status", "DbInstanceIdentifier.$": "$.DbInstanceIdentifier" } } } }, "InputPath": "$.DbInstances", "Next": "Workflow Finished", "ItemSelector": { "LookingFor": { "Key": "autostop", "Value": "yes" }, "DBInstance.$": "$$.Map.Item.Value" } }, "Workflow Finished": { "Type": "Succeed" } } }
注意:出于测试目的,您可以修改等待 1 小时 30 分钟状态下的秒字段。此外,您还可以更改此值以延长或缩短维护时段。
6. 选择下一步。
-
输入状态机名称。例如,输入 step-functions-start-stop-rds-state-machine。
-
在权限下,选择选择现有角色。然后,选择您创建的 IAM 角色。例如,选择 step-functions-start-stop-rds-role。
-
(可选)要添加标签,请在键和值字段中输入相应的值。
-
选择创建状态机。
执行工作流测试
要对处于已停止状态的已标记数据库实例执行功能测试,请完成以下步骤:
1. 打开 Step Functions 控制台。
-
在导航窗格中,选择状态机。
-
选择您为启动数据库实例而创建的状态机。
-
选择开始执行。
注意:此解决方法不需要事件有效负载。在开始执行对话框下,您可以删除事件有效负载或保留默认事件。 -
选择开始执行。
创建计划
要为已标记的数据库实例计划每周维护时段,请创建 EventBridge 规则。此规则会在维护时段前 30 分钟自动启动数据库实例。
在以下示例用例中,维护时段是星期日的 22:00–22:30。示例规则会在每个星期日的 21:30 启动数据库实例。
-
打开 EventBridge 控制台。
-
在创建状态机以启动和停止已标记的数据库实例部分中,选择您之前创建的状态机。
-
在总线下,选择规则。
-
从下拉列表中选择默认事件总线。
-
选择创建规则。
-
对于规则名称,输入要创建的规则的名称。例如,输入 step-functions-start-stop-rds-rule。
-
对于规则类型,选择计划。对于此页面上的其他值,请保留默认设置。
-
选择继续使用 EventBridge 调度器。
-
对于定期计划,选择出现次数。然后,对于计划类型,选择基于 cron 的计划。
-
为自动计划添加 cron 表达式。例如,输入 cron(30 21 ? * SUN *)。
-
对于弹性时间范围,选择关闭。
12. 选择下一步。
-
选择常用 API,然后选择 StartExecution。
-
在 StartExecution 下,选择您创建的状态机。例如,选择 step-functions-start-stop-rds-state-machine。保留输入的默认值 {}。
15. 选择下一步。
-
在重试策略和死信队列 (DLQ) 下,清除重试策略以将其停用。
-
在权限下,保留默认选项: 为此计划创建新角色。
**注意:**EventBridge 会创建一个要担任的新角色并为您的特定工作流启动 StartExecution API。
-
选择下一步。
-
在计划详细信息下,确认接下来的 10 个调用日期是否与您的预期计划日期相符。
-
选择创建计划。
当 EventBridge 调用规则时,它会开始 Step Functions 工作流。这会在维护时段前 30 分钟启动数据库实例。然后,工作流会在维护时段完成 30 分钟后停止数据库实例。例如,工作流在 21:30 启动您的数据库实例。维护时段是在 22:00–22:30。然后,工作流会在 23:00 停止您的实例。
相关内容
- AWS 官方已更新 25 天前
- AWS 官方已更新 2 年前
- AWS 官方已更新 3 年前
- AWS 官方已更新 2 年前