Direkt zum Inhalt

Wie kann ich Step Functions verwenden, um eine Amazon-RDS-Instance für mehr als 7 Tage anzuhalten?

Lesedauer: 9 Minute
0

Ich möchte AWS Step Functions verwenden, um einen Amazon Relational Database Service (Amazon RDS) für mehr als 7 Tage zu beenden.

Kurzbeschreibung

Standardmäßig kannst du eine Amazon-RDS-Datenbank-Instance für bis zu 7 Tage am Stück anhalten. Nach 7 Tagen wird die Instance neu gestartet, damit sie keine Wartungs-Updates verpasst.

Um die Instance für mehr als 7 Tage anzuhalten, kannst du Step Functions verwenden, um den Workflow zu automatisieren, sodass du keine Wartungsfenster verpasst.

Hinweis: Du findest eine alternative Lösung unter Wie kann ich eine AWS-Lambda-Funktion verwenden, um eine Amazon-RDS-Instance für mehr als sieben Tage anzuhalten?

Lösung

IAM-Berechtigungen konfigurieren

Gehe wie folgt vor, um eine AWS Identity and Access Management (IAM)-Richtlinie zu erstellen, die es Step Functions ermöglicht, eine RDS-Instance zu starten und anzuhalten:

  1. Öffne die IAM-Konsole.

  2. Wähle im Navigationsbereich Richtlinien und dann Richtlinie erstellen aus.

  3. Wähle die Registerkarte JSON und gib dann die folgende Anweisung ein:

    {    "Version": "2012-10-17",
        "Statement":
        [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "rds:DescribeDBInstances",
                    "rds:StopDBInstance",
                    "rds:StartDBInstance"
                ],
                "Resource": "*"
            }
        ]
    }
    
  4. Wähle Weiter aus.

  5. Gib unter Richtlinienname den Namen für deine Richtlinie ein. Gib beispielsweise step-functions-start-stop-rds-policy ein.

  6. (Optional) Um ein Tag hinzuzufügen, wähle Add new tag (Neues Tag hinzufügen) aus und gib dann die Werte für die Felder Schlüssel und Wert ein.

  7. Wähle Richtlinie erstellen aus.

Weitere Informationen findest du unter Richtlinien mithilfe des JSON-Editors erstellen.

Eine IAM-Rolle erstellen und die erforderlichen Richtlinien anfügen

Gehe wie folgt vor:

  1. Öffne die IAM-Konsole.
  2. Wähle im Navigationsbereich Rollen und dann Rolle erstellen.
  3. Wähle für Vertrauenswürdige Entitäten auswählen die Option AWS-Service aus.
  4. Wähle in der Dropdown-Liste Use cases for other AWS service (Anwendungsfälle für einen anderen AWS-Service) die Option Step Functions aus.
  5. Wähle Weiter aus.
    Hinweis: Ergreife auf der Seite Berechtigungen hinzufügen keine Maßnahmen. Erstelle zuerst die Rolle und bearbeite dann die Standardberechtigungen.
  6. Wähle Weiter aus.
  7. Gib unter Rollenname den Namen für die Rolle ein. Gib beispielsweise step-functions-start-stop-rds-role ein.
    (Optional) Gib die Rollenbeschreibung ein.
    (Optional) Um ein Tag hinzuzufügen, wähle Add new tag (Neues Tag hinzufügen) aus und gib die Werte für die Felder Schlüssel und Wert ein.
  8. Wähle Rolle erstellen aus. Dadurch kehrst du zur Seite Rollen zurück.
  9. Gib in das Suchfeld den Namen der Rolle ein, die du erstellt hast, und wähle dann diese Rolle aus, um die Details anzuzeigen.
  10. Wähle auf der Registerkarte Berechtigungen die Dropdown-Liste Berechtigungen hinzufügen aus, und wähle dann Richtlinien anfügen aus.
  11. Gib in das Suchfeld den Namen der Richtlinie ein, die du im Abschnitt Configure IAM permissions (IAM-Berechtigungen konfigurieren) erstellt hast. Gib beispielsweise step-functions-start-stop-rds-policy ein und wähle dann die Richtlinie aus.
  12. Wähle auf der Registerkarte Berechtigungen die von AWS verwaltete Richtlinie AWSLambdaRole und dann Entfernen aus.

Weitere Informationen findest du unter Erstellen einer Rolle für einen AWS-Service (Konsole).

Tags für Datenbank-Instances hinzufügen

Gehe wie folgt vor:

  1. Öffne die Amazon-RDS-Konsole.
  2. Wähle im Navigationsbereich Datenbanken aus.
  3. Wähle die Datenbank-Instance aus, die du automatisch starten und anhalten möchtest.
  4. Wähle die Registerkarte Tags aus.
  5. Wähle Hinzufügen aus. Gib für Tag-Schlüssel autostart ein. Gib für Wert yes ein.
  6. Wähle Ein weiteres Tag hinzufügen. Gib für Tag-Schlüssel autostop ein. Gib für „Wert“ yes ein.
  7. Wähle Hinzufügen aus.

Weitere Informationen findest du unter Hinzufügen und Löschen von Tags in Amazon RDS.

Eine Zustandsmaschine zum Starten und Anhalten von markierten Datenbank-Instances erstellen

Gehe wie folgt vor:

  1. Öffne die Step-Functions-Konsole und wähle dann Erste Schritte aus.

  2. Wähle aus Zustandsmaschine erstellen die Option Erstellen Sie Ihr eigenes aus.

  3. Gib einen Zustandsmaschinen-Namen ein. Gib beispielsweise step-functions-start-stop-rds-state-machine ein.

  4. Wähle für Zustandsmaschinentyp die Option Standard und dann Weiter aus.

  5. Wähle die Registerkarte Code und gib dann die folgende Zustandsmaschinen-Definition ein:

    {  "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"
        }
      }
    }

    Hinweis: Im Parameter Wait for 1 hour and 30 minutes (1 Stunde und 30 Minuten warten) kannst du den Wert im Feld Sekunden zu Testzwecken ändern. Du kannst beispielsweise den Wert des Felds Sekunden in ein längeres oder kürzeres Wartungsfenster ändern.

  6. Wähle Konfigund dann Erstellen aus.

  7. Wähle für Bestätigen Sie die Rollenerstellung die Option Bestätigen aus.

  8. Wähle Ausführung starten.

Führe einen Funktionstest für markierte Datenbank-Instances im Status „Angehalten“ durch

Gehe wie folgt vor:

  1. Öffne die Step-Functions-Konsole.
  2. Wähle im linken Navigationsbereich Zustandsmaschinen aus.
  3. Wähle die Zustandsmaschine aus, die du erstellt hast, um die Datenbank-Instances zu starten. Beispielsweise step-functions-start-stop-rds-state-machine.
  4. Wähle Ausführung starten.
    Hinweis: Für diese Lösung sind keine Ereignis-Nutzdaten erforderlich. Im Dialogfeld Ausführung starten kannst du die Ereignis-Nutzdaten entfernen oder das Standardereignis beibehalten.
  5. Wähle Ausführung starten.

Den Zeitplan erstellen

Um ein wöchentliches Wartungsfenster für die markierten Datenbank-Instances zu planen, erstelle eine Amazon-EventBridge-Regel. Diese Regel startet die Datenbank-Instance automatisch 30 Minuten vor dem Wartungsfenster.

Im folgenden Beispiel findet das Wartungsfenster am Sonntag zwischen 22.00 und 22.30 Uhr statt. Die Beispielregel startet die Datenbank-Instance jeden Sonntag um 21.30 Uhr.

Gehe wie folgt vor, um den Zeitplan zu erstellen:

  1. Öffne die EventBridge-Konsole.
  2. Wähle EventBridge-Zeitplan und anschließend Zeitplan erstellen.
  3. Gib einen Namen für den Zeitplan ein. Zum Beispiel step-function-start-stop-schedule. Belasse Gruppe planen als Standard.
  4. Wähle für Zeitplanmuster die Option Wiederkehrender Zeitplan aus.
  5. Wähle für Zeitplantyp die Option Cron-basierter Zeitplan aus.
  6. Füge einen Cron-Ausdruck für den automatisierten Zeitplan hinzu. Gib beispielsweise cron(30 21 ? * SUN *) ein.
  7. Wähle für Flexible Zeitfenster die Option Aus.
  8. Wähle Weiter aus.
  9. Wähle für Zieldetail die Option Vorgeschlagene Ziele aus und wähle dann StartExecution aus.
  10. Wähle unter StartExecution die Zustandsmaschine aus, die du im Abschnitt Zustandsmaschine erstellen, um markierte Datenbank-Instances zu starten und anzuhalten erstellt hast. Wähle beispielsweise step-functions-start-stop-rds-state-machine aus. Behalte den Standardwert der Eingabe von {} bei.
  11. Wähle Weiter aus.
  12. Stelle unter Wiederholungsrichtlinie und Warteschlange für unzustellbare Nachrichten (DLQ) die Option Wiederholungsrichtlinie auf „Aus“.
  13. Wähle für Warteschlange für unzustellbare Nachrichten (DLQ) die Option Keine aus.
  14. Wähle unter Berechtigungen: Neue Rolle für diesen Zeitplan erstellen und wähle dann Nächster Schritt.
    Hinweis: EventBridge erstellt eine neue Rolle, die übernommen werden soll, und initiiert die StartExecution-API für deinen Workflow.
  15. Vergewissere dich unter Details des Zeitplans, dass die nächsten 10 Aufrufdaten mit den Daten deines erwarteten Zeitplans übereinstimmen, und wähle dann Zeitplan erstellen aus.

Der Step-Function-Workflow beginnt, wenn EventBridge die Regel aufruft. Dadurch werden die Datenbank-Instances 30 Minuten vor dem Wartungsfenster gestartet. Der Workflow stoppt die Datenbank-Instance dann 30 Minuten nach Abschluss des Wartungsfensters. Der Workflow startet die Datenbank-Instance beispielsweise um 21.30 Uhr. Das Wartungsfenster findet zwischen 22.00 und 22.30 Uhr statt. Dann stoppt der Workflow die Instance um 23,00 Uhr.