ステップ関数を使用して Amazon RDS インスタンスを 7 日以上停止するにはどうすればいいですか?

所要時間6分
0

AWS Step Functions を使用して Amazon Relational Database Service (Amazon RDS) を 7 日間以上停止したいです。

簡単な説明

デフォルトでは、Amazon RDS データベースインスタンスを一度に最大 7日間停止することができます。7 日後、インスタンスはメンテナンスの更新を見逃さず再起動します。

インスタンスを 7 日以上停止する場合は、Step Functions を使用すればメンテナンス期間を逃さずにワークフローを自動化することができます。

**注:**別の解決策については、「 AWS Lambda 関数を使用して Amazon RDS インスタンスを 7日以上停止する方法を教えてください」を参照してください。

解決方法

IAM 権限の設定

Step Functions がインスタンスを起動および停止し、インスタンスの情報を取得できるようにする AWS ID およびアクセス管理 (IAM) ポリシーを作成します。

  1. IAM コンソールを開きます。

  2. ナビゲーションペインで、[ポリシー] を選択します。その後、[ポリシーを作成] を選択します。

  3. [JSON] タブを選択します。次に、次のポリシーを入力して必要な IAM アクセス権限を付与します。

{
    "Version": "2012-10-17",
    "Statement":
    [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "rds:DescribeDBInstances",
                "rds:StopDBInstance",
                "rds:StartDBInstance"
            ],
            "Resource": "*"
        }
    ]
}

4.    [次へ: タグ] を選択します。

  1. (オプション) タグを追加するには、「タグを追加」を選択し、「キー」フィールドと「値」フィールドに適切なを入力します。

6.    [次へ: レビュー] を選択します。

  1. ポリシーの名前を入力します。たとえば、step-functions-start-stop-rds-policyと入力します。ポリシーに付与されている権限を確認するには、「概要」 セクションを参照してください。

8.    [ポリシーを作成] を選択します。

詳細については、「JSON エディターを使用したポリシーの作成」を参照してください。

IAM ロールを作成し、必要なポリシーをアタッチします

1.    IAM コンソールを開きます。

2.    ナビゲーションペインで、[ロール] を選択します。そして、[ロールを作成] を選択します。

  1. 信頼できるエンティティのタイプを選択」から、「AWS サービス」を選択します。

  2. 他の AWS サービスのユースケース」ドロップダウンリストから、「ステップ機能」を選択します。次に、「ステップ機能」 オプションを選択します。

5.    [次へ] を選択します。
**注:****[権限の追加]**ページでは何も実行しないでください。最初にロールを作成してから、デフォルトの権限を編集します。

6.    [次へ] を選択します。

  1. [ロール名] に、ロールの名前を入力します。たとえば、「step-functions-start-stop-rds-role」と入力します。
    (オプション) ロールの説明を更新します。
    (オプション) タグを追加するには、「キー」 フィールドと、「**値 **」 フィールドに適切な値を入力します。

8.    [ロールを作成] を選択します。これにより、ロールリストに戻ります。

  1. 検索ボックスに、作成したロールの名前を入力します。次に、そのロールを選択して詳細を確認します。

  2. 権限」タブで、「権限の追加」ドロップダウンリストを選択します。次に、[ポリシーをアタッチ] を選択します。

  3. IAM権限の設定」 セクションに作成したポリシーの名前を入力します。たとえば、step-functions-start-stop-rds-policyと入力します。このポリシーがオプションとして表示されたら、選択してください。

  4. [権限] タブで AWSLambdaRole AWS 管理ポリシーを選択し、[削除] を選択します。

詳細については、「AWSサービスロールの作成 (コンソール)」を参照してください。

DB インスタンスにタグを追加

1.    Amazon RDS コンソールを開きます。

2 ナビゲーションペインで [データベース] を選択します。

  1. 自動的に起動および停止する DB インスタンスを選択します。

  2. タグ」タブを選択します。

5. [追加] を選択します。タグキーには、autostart と入力します。[値] に 「yes」と入力します。

  1. [別のタグを追加] を選択します。[タグキー]autostopと入力します。[値] に 「yes」と入力します。

  2. これらのタグを保存するには、[追加] を選択します。

詳細については、「タグの追加、一覧表示、削除」を参照してください。

タグ付けされた DB インスタンスを起動および停止するステートマシンを作成します。

1.    ステップ機能コンソール を開きます。

  1. ナビゲーションペインで、[ステートマネージャー] を選択します。次に、[ステートマシンの作成] を選択します。

  2. ワークフローをコードで書く」を選択します。

  3. デフォルトの [タイプ][標準] のままにします。

5. 定義エディタで、サンプル 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.    [次へ] を選択します。

  1. ステートマシン名を入力します。たとえば、step-functions-start-stop-rds-state-machineと入力します。

  2. [権限][既存のロールを選択] を選択します。次に、作成した IAM ロールを選択します。たとえば、step-functions-start-stop-rds-roleを選択します。

  3. (オプション) タグを追加するには、「キー」 フィールドと**「値」** フィールドに適切な値を入力します。

  4. ステートマシンを作成」を選択します。

ワークフローテストを実行

停止状態のタグ付き DB インスタンスの機能テストを実行するには、次の手順を実行します。

1.    ステップ機能コンソール を開きます。

  1. ナビゲーションペインで、[ステートマネージャー] を選択します。

  2. DB インスタンスを起動するために作成したステートマシンを選択します。

  3. [実行開始] を選択します。
    **注:**この解像度にはイベントペイロードは必要ありません。実行開始ダイアログでは、イベントペイロードを削除することも、デフォルトイベントのままにすることもできます。

  4. [実行開始] を選択します。

スケジュールの作成

タグ付けされた DB インスタンスの毎週のメンテナンス期間をスケジュールするには、EventBridge ルールを作成します。このルールは、メンテナンス時間の 30 分前に自動的に DB インスタンスを起動します。

次の使用例では、メンテナンスウィンドウは日曜日の 22:00 ~ 22:30 の間に発生します。このルール例では、毎週日曜日の 21:30 に DB インスタンスを起動します。

  1. EventBridge コンソールを開きます。

  2. ステートマシンを作成」セクションで以前に作成したステートマシンを選択して、タグ付けされた DB インスタンスを起動および停止します。

  3. バス」から「ルール」を選択します。

  4. ドロップダウンリストからデフォルトのイベントバスを選択します。

  5. [ルールを作成] を選択します。

  6. [ルール名] に、作成するルールの名前を入力します。たとえば、step-functions-start-stop-rds-ruleと入力します。

  7. [ルールタイプ]]で [スケジュール] を選択します。このページの他の値については、デフォルト設定のままにしてください。

  8. EventBridge スケジューラーで続行」を選択します。

  9. 定期スケジュール」では、「オカレンス」を選択します。次に、[スケジュールの種類][CRON ベースのスケジュール] を選択します。

  10. 自動スケジュールに cron 式を追加します。たとえば、cron(30 21 ? * SUN *) と入力します。

  11. フレキシブルタイムウィンドウ」では、「オフ」を選択します。

12.    [次へ] を選択します。

  1. [よく使う API] を選択し、次に [実行の開始] を選択します。

  2. 実行開始」で、作成したステートマシンを選択します。たとえば、step-functions-start-stop-rds-state-machineを選択します。入力のデフォルト値は ** {} **のままにしてください。

15.    [次へ] を選択します。

  1. 再試行ポリシーとデッドレターキュー (DLQ)」で、「再試行ポリシー」をクリアして無効にします。

  2. 権限」では、デフォルトのオプションをそのまま使用します。 このスケジュールの新しいロールを作成してください

**注:**EventBridgeは引き継ぐ新しいロールを作成し、特定のワークフロー用の StartExecution APIを起動します。

  1. [次へ] を選択します。

  2. [スケジュールの詳細] で、次の 10 件の呼び出し日が予定されているスケジュールの日付と一致していることを確認します。

  3. [スケジュールの作成] を選択します。

EventBridge がルールを呼び出すと、ステップファンクションワークフローが開始されます。これにより、メンテナンス時間の 30 分前に DB インスタンスが起動します。その後、ワークフローは、メンテナンスウィンドウが完了してから 30 分後に DB インスタンスを停止します。 たとえば、このワークフローは DB インスタンスを 21:30 に起動します。メンテナンスの時間帯は 22:00 ~ 22:30 です。その後、ワークフローはインスタンスを 23:00 に停止します。

コメントはありません

関連するコンテンツ