Comment puis-je utiliser Step Functions pour arrêter une instance Amazon RDS pendant plus de 7 jours ?
Je souhaite utiliser AWS Step Functions pour arrêter une instance Amazon Relational Database Service (Amazon RDS) pendant une durée supérieure à 7 jours.
Brève description
Par défaut, vous pouvez arrêter une instance de base de données Amazon RDS pendant 7 jours consécutifs maximum. Au bout de 7 jours, l’instance redémarre de sorte qu’elle ne manque aucune mise à jour de maintenance.
Pour arrêter votre instance pendant plus de 7 jours, vous pouvez utiliser Step Functions pour automatiser le flux de travail de sorte que vous ne manquez pas les fenêtre de maintenance.
Remarque : pour une autre solution, consultez la section Comment utiliser une fonction AWS Lambda pour arrêter une instance Amazon RDS pendant plus de sept jours ?
Résolution
Configurer les autorisations IAM
Pour créer une politique Gestion des identités et des accès AWS (AWS IAM) qui permet à Step Functions de démarrer et d'arrêter une instance RDS, procédez comme suit :
-
Dans le volet de navigation, choisissez Politiques, puis Créer une politique.
-
Sélectionnez l'onglet JSON, puis saisissez l’instruction suivante :
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "rds:DescribeDBInstances", "rds:StopDBInstance", "rds:StartDBInstance" ], "Resource": "*" } ] } -
Sélectionnez Suivant.
-
Dans Nom de la politique, saisissez le nom de votre politique. Par exemple, saisissez step-functions-start-stop-rds-policy.
-
(Facultatif) Pour ajouter une identification, choisissez Ajouter une nouvelle identification, puis saisissez les valeurs appropriées dans les champs Clé et Valeur.
-
Sélectionnez Créer une politique.
Pour en savoir plus, consultez la page Création de stratégies à l’aide de l’éditeur JSON.
Créer un rôle IAM et associer les politiques requises
Procédez comme suit :
- Ouvrez la console IAM.
- Dans le volet de navigation, choisissez Rôles, puis Créer un rôle.
- Pour Sélectionner l’entité de confiance, choisissez Service AWS.
- Dans la liste déroulanteCas d'utilisation pour d'autres services AWS, choisissez Step Functions.
- Sélectionnez Suivant.
Remarque : n'effectuez aucune action sur la page Ajouter des autorisations . Créez d'abord le rôle, puis modifiez les autorisations par défaut. - Sélectionnez Suivant.
- Pour Nom du rôle, saisissez le nom du rôle. Par exemple, saisissez step-functions-start-stop-rds-role.
(Facultatif) Saisissez la description du rôle.
(Facultatif) Pour ajouter une identification, choisissez Ajouter une nouvelle identification et saisissez les valeurs dans les champs Clé et Valeur. - Sélectionnez Créer un rôle. Vous êtes renvoyé vers la page Rôles.
- Dans la zone de recherche, saisissez le nom du rôle que vous avez créé, puis sélectionnez ce rôle pour en afficher les détails.
- Dans l'onglet Autorisations, choisissez la liste déroulante Ajouter des autorisations, puis sélectionnez Associer des politiques.
- Saisissez le nom de la politique que vous avez créée dans la section Configurer les autorisations IAM. Par exemple, saisissez step-functions-start-stop-rds-policy, puis sélectionnez la politique.
- Dans l'onglet Autorisations, sélectionnez la politique gérée par AWS AWSLambdaRole, puis choisissez Supprimer.
Pour en savoir plus, consultez la section Création d'un rôle pour un service AWS (console).
Ajouter des identifications pour les instances de base de données
Procédez comme suit :
- Ouvrez la console Amazon RDS.
- Dans le volet de navigation, sélectionnez Bases de données.
- Sélectionnez l'instance de base de données que vous souhaitez démarrer et arrêter automatiquement.
- Choisissez l'onglet Identifications.
- Sélectionnez Ajouter. Pour Clé d’identification, saisissez démarrage automatique. Pour Valeur, saisissez oui.
- Choisissez Ajouter une autre identification. Pour Clé d’identification, saisissez arrêt automatique. Pour Valeur, saisissez oui.
- Sélectionnez Ajouter.
Pour plus d'informations, consultez la section Ajouter et supprimer des identifications dans Amazon RDS.
Créer une machine à états pour démarrer et arrêter les instances de base de données identifiées
Procédez comme suit :
-
Ouvrez la console Step Functions, puis sélectionnez Commencer.
-
Dans Créer votre machine à états, choisissez Créer la vôtre.
-
Saisissez un nom de machine à états. Par exemple, saisissez step-functions-start-stop-rds-state-machine.
-
Pour Type de machine à états, sélectionnez Standard, puis cliquez sur Continuer.
-
Choisissez l'onglet Code, puis saisissez la définition de machine à états suivante :
{ "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" } } }Remarque : dans le paramètre Attendre 1 heure et 30 minutes, vous pouvez modifier la valeur du champ Secondes à des fins de test. Par exemple, vous pouvez modifier la valeur du champ Secondes pour une fenêtre de maintenance plus ou moins longue.
-
Sélectionnez Config, puis Créer.
-
Pour Confirmer la création du rôle, sélectionnez Confirmer.
-
Choisissez Lancer l'exécution.
Exécuter un test de fonction pour les instances de base de données identifiées à l'état Arrêté
Procédez comme suit :
- Ouvrez la console Step Functions.
- Dans le volet de navigation, sélectionnez Machines à états.
- Sélectionnez la machine à états que vous avez créée pour démarrer vos instances de base de données. Par exemple, sélectionnez step-functions-start-stop-rds-state-machine.
- Choisissez Lancer l'exécution.
Remarque : cette résolution ne requiert pas de données utiles d'événement. Dans la boîte de dialogue Démarrer l'exécution, vous pouvez supprimer les données utiles de l'événement ou conserver l'événement par défaut. - Choisissez Lancer l'exécution.
Créer la planification
Pour planifier une fenêtre de maintenance hebdomadaire pour les instances de base de données identifiées, créez une règle Amazon EventBridge. Cette règle démarre automatiquement l'instance de base de données 30 minutes avant la fenêtre de maintenance.
Dans l'exemple d'utilisation suivant, la fenêtre de maintenance se déroule entre 22h00 et 22h30 le dimanche. L'exemple de règle démarre l'instance de base de données à 21h30 tous les dimanches.
Pour créer la planification, procédez comme suit :
- Ouvrez la console EventBridge.
- Sélectionnez Planification EventBridge, puis Créer une planification.
- Saisissez un nom de planification. Par exemple, step-function-start-stop-schedule. Laissez le groupe de planification comme valeur par défaut.
- Pour Modèle de planification, sélectionnez Planification récurrente.
- Pour Type de planification, choisissez Planification basée sur cron.
- Ajoutez une expression cron pour la planification automatique. Par exemple, saisissez cron(30 21 ? * SUN *).
- Pour Fenêtre horaire flexible, choisissez Désactivé.
- Sélectionnez Suivant.
- Pour Détails de la cible, sélectionnez Cibles modélisées, puis StartExecution.
- Sous StartExecution, sélectionnez la machine à états que vous avez créée dans la section Créer une machine à états pour démarrer et arrêter les instances de base de données identifiées. Par exemple, sélectionnez step-functions-start-stop-rds-state-machine. Conservez la valeur par défaut de l'entrée, {}.
- Sélectionnez Suivant.
- Dans Stratégie de nouvelles tentatives et file d’attente de lettres mortes (DLQ), définissez le commutateur Stratégie de nouvelles tentatives sur Désactivé.
- Pour File d'attente de lettres mortes (DLQ), sélectionnez Aucune.
- Dans Autorisations, choisissez : Créer un nouveau rôle pour cette planification, puis choisissez ** Suivant**.
Remarque : EventBridge crée un nouveau rôle à assumer et lance l'API StartExecution pour votre flux de travail. - Sous Détails de la planification, vérifiez que les 10 dates d'invocation suivantes correspondent aux dates de la planification prévue, puis sélectionnez Créer une planification.
Le flux de travail Step Function commence lorsque EventBridge invoque la règle. Les instances de base de données 30 minutes sont alors démarrées avant la fenêtre de maintenance. Le flux de travail arrête ensuite l'instance de base de données 30 minutes après la fin de la fenêtre de maintenance. Par exemple, le flux de travail démarre votre instance de base de données à 21h30. La fenêtre de maintenance se déroule entre 22h00 et 22h30. Le flux de travail arrête ensuite votre instance à 23h00.
- Langue
- Français

Attention, là! Dès que l'on vérifie l'état d'un sytème sans la possibilité de poser un verrou avant d'agir, on introduit une concurrence critique. Tôt ou tard, la solution officielle de AWS manquera d'arrêter une base de données, ce qui risque d'entraîner des coûts.
Après plusieurs études, j'ai publié une solution fiable sous forme source ouverte. Je n'ai pas déjà traduit le fichier «ReadMe» vers le français, mais si cela vous aiderait, je pourrais le faire.
Ma solution est disponible en deux formes:
-
Step Functions (ce que je commence à préférer pour ce genre de travail): github.com/sqlxpert/step-stay-stopped-aws-rds-aurora
-
SQS + Lambda: github.com/sqlxpert/step-stay-stopped-aws-rds-aurora
Dans ma rédaction 5 AWS Services, 5 Different Approaches to Idempotence sur community.aws, j'explique les inconvénients de StopDBInstance pour RDS et StopDBCluster pour Aurora.
Merci pour votre commentaire. Nous vérifierons et mettrons à jour l'article du Centre de connaissances si nécessaire.
Contenus pertinents
- demandé il y a 10 mois
- demandé il y a 2 ans
- demandé il y a 2 ans
AWS OFFICIELA mis à jour il y a 8 mois