Comment arrêter et démarrer des instances Amazon EC2 à des intervalles réguliers avec Lambda ?

Dernière mise à jour : 13/01/2022

Je souhaite réduire mon utilisation d'Amazon Elastic Compute Cloud (Amazon EC2) en arrêtant et en démarrant mes instances EC2 automatiquement. Comment utiliser AWS Lambda et Amazon EventBridge à cet effet ?

Brève description

Remarque : cet exemple de configuration est une solution simple. Pour une solution plus robuste, utilisez AWS Instance Scheduler. Pour plus d'informations, consultez la section Comment arrêter et démarrer mes instances à l'aide d'AWS Instance Scheduler ?

Pour arrêter et démarrer des instances Amazon EC2 à des intervalles réguliers avec Lambda, procédez comme suit :

1.    Créez un rôle d'exécution et une stratégie AWS Identity and Access Management (IAM) personnalisés pour votre fonction Lambda.

2.    Créez des fonctions Lambda pour démarrer et arrêter vos instances EC2.

3.    Testez votre fonction Lambda.

4.    Créez des règles EventBridge qui déclenchent votre fonction selon une planification.
Remarque : vous pouvez également créer des règles qui se déclenchent lors d'un événement qui se produit dans votre compte AWS.

Vous pouvez également utiliser le modèle AWS CloudFormation fourni à la fin de cet article pour automatiser la procédure.

Solution

Remarque : si vous recevez une erreur Client error on launch (erreur du client lors du lancement) après avoir effectué la procédure suivante, consultez Lorsque je démarre mon instance avec des volumes chiffrés attachés, celle-ci s'arrête immédiatement avec l'erreur « client error on launch » (erreur du client lors du lancement).

Obtenez les ID des instances EC2 que vous souhaitez arrêter et démarrer. Puis, procédez comme suit.

Créez une stratégie IAM et un rôle d'exécution pour votre fonction Lambda

1.    Créez une stratégie IAM à l'aide d'un éditeur de stratégie JSON. Copiez et collez le document de stratégie JSON suivant dans l'éditeur de stratégie :

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:Start*",
        "ec2:Stop*"
      ],
      "Resource": "*"
    }
  ]
}

2.    Créez un rôle IAM pour Lambda.

Important : Lorsque vous associez une stratégie d'autorisations à Lambda, assurez-vous de choisir la stratégie IAM que vous venez de créer.

Créez des fonctions Lambda pour démarrer et arrêter vos instances EC2

1.    Dans la console AWS Lambda, choisissez Créer une fonction.

2.    Choisissez Créer à partir de zéro.

3.    Sous Informations de base, procédez comme suit :
Pour Nom de la fonction, saisissez un nom l'identifiant comme la fonction utilisée pour arrêter vos instances EC2. Par exemple, « StopEC2Instances ».
Dans le champ Runtime (Exécution), choisissez Python 3.9.
Sous Permissions (Autorisations), développez Change default execution role (Modifier le rôle d'exécution par défaut).
Sous Execution role (Rôle d'exécution), choisissez Use an existing role (Utiliser un rôle existant).
Sous Rôle existant, choisissez le rôle IAM que vous avez créé plut tôt.

4.    Sélectionnez Créer une fonction.

5.    Sous Code, Code source, copiez et collez le code suivant dans le panneau de l'éditeur dans l'éditeur de code (lambda_function). Ce code arrête les instances EC2 que vous identifiez.

Exemple de code de fonction : arrêt des instances EC2

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.stop_instances(InstanceIds=instances)
    print('stopped your instances: ' + str(instances))

Important : pour région, remplacez « us-west-1 » avec la région AWS dans laquelle se trouve vos instances. Pour instances, remplacez les ID d'instance EC2 d'exemple avec les ID des instances spécifiques que vous souhaitez arrêter et démarrer.

6.    Choisissez Deploy (Déployer).

7.    Dans l'onglet Configuration, choisissez General configuration (Configuration générale), puis Edit (Modifier). Définissez Timeout (Délai d'attente) sur 10 secondes, puis sélectionnez Save (Enregistrer).

Remarque : configurez les paramètres de la fonction Lambda comme requis pour votre cas d'utilisation. Par exemple, si vous souhaitez arrêter et démarrer plusieurs instances, une valeur différente peut être nécessaire pour Timeout (Délai d'attente) et Memory (Mémoire).

8.    Répétez les étapes 1-7 pour créer une autre fonction. Procédez différemment pour que cette fonction démarre vos instances EC2 :

À l'étape 3, entrez un Nom de la fonction différent de celui que vous avez utilisé précédemment. Par exemple, « StartEC2Instances ».
À l'étape 5, copiez et collez le code suivant dans le panneau de modification dans l'éditeur de code ( lambda_function) :

Exemple de code de fonction : démarrage d'instances EC2

import boto3
region = 'us-west-1'
instances = ['i-12345cb6de4f78g9h', 'i-08ce9b2d7eccf6d26']
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    ec2.start_instances(InstanceIds=instances)
    print('started your instances: ' + str(instances))

Important : Pour region (région) et instances, utilisez les mêmes valeurs que celles utilisées pour le code d'arrêt de vos instances EC2.

Testez vos fonctions Lambda

1.    Dans la console AWS Lambda, choisissez Fonctions.

2.    Choisissez l'une des fonctions que vous avez créées.

3.    Sélectionnez l'onglet Code.

4.    Dans la section Code source (Source du code), sélectionnez Test.

5.    Dans la boîte de dialogue Configure test event (Configurer un événement de test), choisissez Create new test event (Créer un nouvel événement de test).

6.    Saisissez un Event name (Nom d'événement). Ensuite, choisissez Create (Créer).

Remarque : vous n'avez pas à changer le code JSON pour l'événement de test ; la fonction ne l'utilise pas.

7.    Choisissez Test pour exécuter la fonction.

8.    Répétez les étapes 1 à 6 pour l'autre fonction créée.

Astuce : vous pouvez vérifier l'état de vos instances EC2 avant et après avoir effectué le test pour confirmer que vos fonctions fonctionnent comme prévu.

Créez des règles EventBridge qui déclenchent vos fonctions Lambda

1.    Ouvrez la console EventBridge.

2.    Sélectionnez Create rule (Créer une règle).

3.    Saisissez un Name (Nom) pour votre règle, comme « StopEC2Instances ». Vous pouvez éventuellement saisir une Description.

4.    Dans Define pattern (Définir le modèle), sélectionnez Schedule (Planifier).

5.    Effectuez l'une ou l'autre des opérations suivantes :

Pour le champ Taux fixe de, saisissez un intervalle de temps en minutes, heures ou jours.
Pour Cron expression (Expression Cron), saisissez une expression qui indique à Lambda quand arrêter vos instances. Pour plus d'informations sur la syntaxe des expressions, consultez Expressions de planification des règles.
Remarque
 : Les expressions Cron sont évaluées selon l'heure UTC. Assurez-vous d'ajuster l'expression pour le fuseau horaire de votre choix.

6.    Dans Select targets (Sélectionner des cibles), choisissez Lambda function (Fonction Lambda) dans le menu déroulant Target (Cible).

7.    Pour Function (Fonction), choisissez la fonction qui arrête vos instances EC2.

8.    Faites défiler vers le bas, puis sélectionnez Create (Créer).

9.    Répétez les étapes 1 à 8 pour créer une règle pour démarrer vos instances EC2. Effectuez la procédure suivante différemment :

Saisissez un nom pour votre règle, comme « StartEC2Instances ».
(Facultatif) Saisissez une Description, comme « Démarrez les instances EC2 tous les matins à 7 heures. »
Dans l'étape 5, pour le champ Cron expression (Expression Cron), saisissez une expression qui indique à Lambda quand démarrer vos instances.
Dans l'étape 7, pour le champ Function (Fonction), choisissez la fonction qui démarre vos instances EC2.

(Facultatif) Utilisez AWS Instance Scheduler pour automatiser la procédure

Pour plus d'informations, consultez Automatiser le démarrage et l'arrêt des instances AWS.