web-dev-qa-db-fra.com

Comment démarrer et arrêter une instance AWS EC2 en fonction d'un calendrier basé sur le temps

Existe-t-il un moyen simple de démarrer et d'arrêter des instances AWS EC2 à une heure donnée chaque jour? Cela pourrait me faire économiser beaucoup d'argent pour mes serveurs de développement et de test.

17
Tim

Mise à jour

AWS a publié un outil appelé " Instance Scheduler ", comprenant un guide de configuration complet qui est lié à partir de cette page. Cela semble être une amélioration du planificateur EC2 que je décris ci-dessous, avec quelques fonctionnalités supplémentaires, mais c'est essentiellement la même chose.

Le guide ci-dessous fonctionnera toujours, mais il est probablement préférable de regarder le planificateur d'instance pour les nouvelles installations.

Message d'origine

AWS dispose d'un outil appelé EC2 Scheduler qui vous donne un contrôle très flexible sur le démarrage et l'arrêt des instances EC2.

L'outil vous permet de définir les heures de démarrage et d'arrêt par défaut lorsque vous configurez l'outil, que vous pouvez modifier ultérieurement. Vous pouvez choisir les instances à contrôler, vous et vous pouvez spécifier des heures de début et de fin différentes pour chaque instance à l'aide de balises.

Bien que ce soit un excellent outil, la documentation est quelque peu vague et déroutante. C'est comme si la documentation avait été écrite par un ingénieur qui a écrit l'outil et qui sait tout à son sujet, plutôt qu'un rédacteur technique.

Remarque : si vous avez des commentaires ou des corrections, les commentaires sont appréciés. Si vous avez une question basée sur celle-ci, veuillez commencer votre propre question.

Qu'est-ce que EC2 Scheduler

Cet outil est une fonction Lambda qui fonctionne avec Cloudwatch Events et DynamoDB. Il est déployé à l'aide d'un modèle Cloudformation, qui définit également les rôles et politiques IAM nécessaires. Vous pouvez lire sur l'architecture ici .

AWS EC2 Scheduler Architecture

Déploiement

Commencez par aller à cette page et cliquez sur "Lancer la solution". En ce moment, le lien direct est ici , mais cela pourrait changer.

Sélectionnez la région dans laquelle vous souhaitez déployer les ressources en haut de la console. Le script contrôle les instances EC2 dans n'importe quelle région, mais il s'exécute dans une seule région.

Balisage des instances EC2

Ceci est couvert dans la documentation ici , mais ce n'est pas aussi simple que cela pourrait l'être.

Vous contrôlez quelles instances sont démarrées et arrêtées en marquant vos instances.

Le cas le plus simple vous oblige à baliser chaque instance EC2 que vous souhaitez démarrer et arrêter conformément à la planification. Pour ce faire, recherchez votre instance EC2 dans la console, cliquez sur les balises et créez cette balise

EC2 Instance Tagging for Scheduler

Pour activer le copier-coller:

  • Clé: ordonnanceur: ec2-startstop
  • Valeur: vrai

Si vous souhaitez démarrer et arrêter une instance spécifique selon un calendrier différent, vous ajoutez des informations supplémentaires à la clé et à la valeur de la balise. Par exemple, si vous souhaitez qu'une instance démarre à 1500 UTC et s'arrête à 2400 UTC les mardi, jeudi et vendredi, vous saisissez les informations suivantes.

Clé: ordonnanceur: ec2-startstop: tard Valeur: 1500; 2400; utc; mar, jeu, ven

Notez que le mot "tard" peut être n'importe quelle chaîne, "tard" n'a pas de signification particulière.

Vous pouvez convertir UTC à votre heure locale en utilisant cet outil .

Vous pouvez utiliser éditeur de balises pour regrouper des instances de balises. Cela pourrait vous permettre de configurer plus facilement le balisage en bloc, ce qui pourrait être utile pour avoir différents paramètres pour le développement, le test et la production. Je doute que vous l'utilisiez en production cependant.

Paramètres CloudFormation

Lorsque vous exécutez le modèle CloudFormation, vous devez entrer de nombreux paramètres. La plupart que vous pouvez laisser par défaut. Voici certains des paramètres les plus importants

  • Nom de la pile: appelez-le comme vous voulez. C'est exactement ce qu'on appelle dans CloudFormation.
  • Nom de balise personnalisé: il s'agit de la "clé" de la balise que vous placez contre l'instance EC2. Laissez-le à la valeur par défaut, sauf si vous avez une bonne raison ou si vous avez besoin de plusieurs installations.
  • Heure de démarrage/arrêt par défaut: heure UTC par défaut pour démarrer et arrêter les instances
  • DynamoDB: les paramètres sont stockés dans DynamoDB. Vous pouvez changer le nom de la table et autres. Parce que le niveau gratuit de DynamoDB n'expire pas, la plupart des gens ne seront probablement pas facturés.
  • (deuxième écran) Autorisations - il s'agit d'un hareng rouge, voir la section ci-dessous. Laissez-le par défaut et exécutez-vous en tant qu'administrateur lorsque vous essayez de configurer EC2 Scheduler.
  • Options de notification: J'ai trouvé utile de configurer des notifications SNS afin de pouvoir valider que cela fonctionnait. Je n'ai pas passé le temps de trouver comment les désactiver, je viens de le supprimer et j'ai réexécuté le modèle Cloudformation pour le réinstaller.

Autorisations, stratégies et rôles

La section Autorisations/Rôle IAM du modèle CloudFormation est un redingue - c'est-à-dire qu'elle est largement hors de propos. Il spécifie uniquement le rôle utilisé pour exécuter le script CloudFormation, il ne fait aucune différence pour les ressources créées ou le rôle utilisé lors de l'exécution de la fonction lambda. Rétrospectivement, c'est évident, mais ce n'était pas évident pour moi quand j'ai commencé.

Quel que soit le rôle que vous exécutez ce script comme le même rôle et les autorisations en ligne sont créées dans IAM. La fonction Lambda s'exécute à l'aide d'un "rôle de planificateur ec2" créé par le script.

J'ai inclus mes politiques ci-dessous au cas où elles seraient utiles à quiconque.

Événements et mesures CloudWatch

Si vous souhaitez voir les journaux de votre fonction Lambda, accédez aux événements Cloudwatch. La journalisation est assez bonne. Il existe également des métriques, vous pouvez donc voir quand il s'exécute, l'heure à laquelle il s'exécute, etc.

Supplémentaire

Le code de la fonction lambda est disponible sur Github .

Politiques

Ceux-ci ne sont généralement pas nécessaires, mais pourraient être pour quelqu'un, donc je vais les inclure.

Stratégie pour le rôle IAM

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeTags",
                "iam:CreateRole",
                "iam:GetRole",
                "iam:PassRole",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:DeleteRole",
                "dynamodb:*",
                "lambda:*",
                "SNS:Publish",
                "events:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "S3:GetObject",
            "Resource": [
                "arn:aws:s3:::solutions-us-west-2",
                "arn:aws:s3:::solutions-us-west-2/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:StartInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:123456789012:instance/i-0d112345Ab6789012"
            ]
        }
    ]
}

Stratégie de confiance pour le rôle IAM

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com",
          "cloudformation.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
16
Tim

Si vous souhaitez simplement démarrer et arrêter des instances, voici une autre approche à ce sujet qui utilise également le service Lambda. Il suppose que vous souhaitez contrôler un ID d'instance spécifique. Vous pouvez contrôler plusieurs instances en ajoutant plus d'ID séparés par une virgule. (ex: "i-3453453", "i-45656745"). Vous pouvez trouver l'ID de votre instance dans la section Instances de la console AWS.

Dans la console Lambda

  1. Ouvrez la console AWS Lambda et choisissez Créer une fonction.
  2. Choisissez l'auteur à partir de zéro.
  3. Entrez un nom pour votre fonction, tel que "StopEC2Instances".
  4. Pour Runtime, sélectionnez Python 2.7
  5. Développez le menu déroulant Rôle et choisissez Créer un rôle personnalisé. Cela ouvre un nouvel onglet ou une nouvelle fenêtre dans votre navigateur.
  6. Dans le menu déroulant Rôle IAM, sélectionnez Créer un nouveau rôle IAM et entrez un nom de rôle, tel que "lambda_start_stop_ec2".
  7. Choisissez Afficher le document de stratégie, Modifier, puis choisissez Ok lorsque vous êtes invité à lire la documentation. Remplacez tout le texte de la stratégie par ceci:

Code ci-dessous

{
  "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": "*"
    }
  ]
}
  1. Choisissez Autoriser pour terminer la création du rôle et revenir à la console AWS Lambda.
  2. Pour arrêter vos instances, remplacez tout le texte de l'éditeur de code de fonction par ce qui suit:

Code ci-dessous

import boto3
region = ' eu-west-1'
instances = ['i-0dd344443184503fa']

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

N'oubliez pas de remplacer les valeurs de région et d'instance par les vôtres.

  1. Dans le menu déroulant Runtime, choisissez Python2.7.
  2. Dans les paramètres de base, entrez 10 secondes pour la fonction Timeout.
  3. Choisissez Enregistrer.
  4. Répétez toutes les étapes pour créer une autre fonction qui démarrera vos instances, mais utilisez ensuite ce script python pour tout démarrer:

Code ci-dessous

import boto3
region = 'eu-west-1'
instances = [' i-0dd344443184503fa']

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

Planifier les fonctions

Ici, vous allez créer un événement CloudWatch qui déclenchera votre fonction Lambda la nuit

  1. Ouvrez la console Amazon CloudWatch.
  2. Choisissez Événements, puis choisissez Créer une règle.
  3. Choisissez Planification sous Source d'événement.
  4. Entrez un intervalle de temps ou une expression cron qui indique à Lambda quand arrêter vos instances. Pour plus d'informations sur la syntaxe correcte, voir Planifier la syntaxe des expressions pour les règles.

Remarque: les expressions Cron sont évaluées en UTC. Assurez-vous d'ajuster l'expression pour votre fuseau horaire préféré. Voici un exemple qui exécutera la fonction tous les jours à 08h00 GMT/UTC):

0 08 * * ? *
  1. Choisissez Ajouter une cible, puis choisissez la fonction Lambda.
  2. Pour Function, choisissez la fonction Lambda qui arrête vos instances.
  3. Choisissez Configurer les détails.
  4. Entrez les informations suivantes dans les champs fournis: Pour Nom, entrez un nom significatif, tel que "StopEC2Instances". Pour Description, ajoutez une description significative, telle que "arrête les instances EC2 tous les jours la nuit". Pour État, sélectionnez Activé.
  5. Choisissez Créer une règle.

Pour redémarrer vos instances le matin, répétez ces étapes et utilisez votre heure de début préférée. Si vous souhaitez envoyer un message électronique chaque fois que les fonctions échouent, vous pouvez configurer une rubrique SNS et configurer l'envoi de ce message sous Débogage dans la fenêtre de création de fonction Lmbda.

La source de tout cela peut être trouvée ici: documentation AWS

10
netfed