Est-il possible de forcer la recréation d'EC2 :: Instance ou RDS :: DBInstance dans Amazon Cloudformation?

16

Est-il possible de forcer la recréation d'une instance EC2 ou RDS à l'aide de piles de cloudformation?

Ma pile reste bloquée à un point où la simple destruction et la création de la ressource le corrigeront, au lieu de cela j'ai dû supprimer la pile entière pour continuer le travail.

Éditer:

Ce problème m'a frappé deux fois. J'ai d'abord créé une instance AWS :: RDS :: avec quelques valeurs par défaut, puis j'ai essayé de la rétrograder vers "EngineVersion": "5.5". Changer cela est censé se produire avec une interruption, mais les instances mysql ne peuvent pas être rétrogradées de 5.6 à 5.5, donc la pile a été laissée dans l'état UPDATE_FAILED et je ne peux pas recréer RDS sans une astuce désagréable.

L'autre occurrence était que j'ai plusieurs "AWS :: EC2 :: Instance" qui télécharge et exécute un script à partir de ses "UserData" évidemment si Y change le script téléchargé, je dois recréer l'instance, et il n'y a aucun moyen de le faire. Encore une fois, j'utilise la même astuce pour faire recréer la machine.

L'astuce désagréable:

Au lieu d'utiliser un groupe de mise à l'échelle automatique d'une machine, j'ai résolu les deux problèmes en changeant la zone de disponibilité dans les propriétés ... mais je me suis laissé de mauvais goût

théiste
la source
Besoin de plus d'informations pour répondre. Vos instances se bloquent-elles au démarrage? Un service ne répond plus? Si vous cherchez à recréer manuellement une instance EC2, vous pouvez créer un groupe de mise à l'échelle automatique avec une instance. Lorsque vous mettez fin à l'instance, une autre sera créée.
Edwin
édité pour clarifier. J'ai aussi demandé ici: forums.aws.amazon.com/thread.jspa?threadID=135295&tstart=0
théiste
Cela ne répond pas directement à votre question, mais pour réexécuter les scripts UserData lorsqu'ils sont modifiés, vous pouvez consulter cfn-hup: docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
Reed Kraft-Murphy

Réponses:

10

Pour les instances EC2 sauvegardées par l'instance, une astuce consiste à ajouter un commentaire au script de données utilisateur contenant un numéro de version, une date ou similaire, puis de le modifier chaque fois que vous souhaitez que l'instance soit recréée:

{
    "Resources" : {
        "MyEC2Instance" : {
            "Type" : "AWS::EC2::Instance",
            "Properties" : {
                // ... other properties ...
                "UserData": { 
                    "Fn::Base64" : {
                        "Fn::Join" : [ ":", [
                        "#!/bin/bash\n",
                        "# Version: 1.0\n",
                        // ... rest of user data ...
                    ]]}
            }
        }
    }
}

Toute modification de UserDataentraînera le remplacement de l'instance (c'est-à-dire la régénération). Le comportement du script de données utilisateur doit être le même, car la seule modification est un commentaire. Notez que cela ne fonctionne pas pour les instances soutenues par EBS.

Pour RDS, vous pouvez prendre un instantané DB de l'instance RDS actuelle, puis modifier votre modèle pour utiliser cet instantané avec DBSnapshotIdentifier:

{
    "Resources" : {
        "MyDB" : {
        "Type" : "AWS::RDS::DBInstance",
        "Properties" : {
            // ... other properties ...
            "DBSnapshotIdentifier": "<db snapshot ID>"
        }
    }    
}

À chaque DBSnapshotIdentifiermodification, l'instance de base de données sera remplacée. L'utilisation d'instantanés vous permettra également de conserver les données à partir du moment où l'instantané a été créé. (Si vous souhaitez effacer les données, vous pouvez créer un instantané vide et le transmettre en entrée. Ou supprimer et recréer la pile CloudFormation entière.)

Une approche plus générique consiste à modifier le nom logique de la ressource. Depuis la modification d'un modèle de pile dans les documents CloudFormation:

Pour la plupart des ressources, la modification du nom logique d'une ressource équivaut à supprimer cette ressource et à la remplacer par une nouvelle. Toutes les autres ressources qui dépendent de la ressource renommée doivent également être mises à jour et peuvent entraîner leur remplacement. D'autres ressources nécessitent que vous mettiez à jour une propriété (pas seulement le nom logique) afin de déclencher une mise à jour.

Markusk
la source
Semble que la seule solution est de faire des "trucs sales" J'ai atteint une solution similaire (forçant les changements de zones de disponibilité) quelque temps après avoir demandé :)
theist
4
Je veux juste souligner que l'instance est remplacée et donc les UserData exécutées lorsque l'instance EC2 est sauvegardée par l'instance. S'il est soutenu par EBS, le changement de UserData ne fera que redémarrer l'instance et UserData n'est pas exécuté à nouveau. Vous pouvez utiliser cfn-hup pour exécuter à nouveau les UserData même dans ce cas, mais l'instance reste la même.
Kaitsu
@Kaitsu: Merci, c'est une clarification très précieuse. J'ai mis à jour ma réponse en conséquence.
Markusk
@Kaitsu mais si vous réexécutez manuellement le script (situé dans / var / lib / cloud / instance / scripts / part-001), vous devez vous assurer que le script est défensif pour exécuter les mêmes commandes plusieurs fois :(
c24w
1

Si vous le placez dans un AutoScalingGroup, vous pouvez modifier le AutoScalingGroup min / max / default à 0, puis dès qu'il commence à détruire l'ancienne instance, vous pouvez ensuite mettre le min / max / default au 1/1/1 et presto: nouvelle instance.

Tim Bassett
la source
0

Si vos EC2 sont dans un AutoScalingGroup, vous pouvez définir la AutoScalingGroupNamepropriété avec un numéro de version.

Chaque fois que vous modifiez ce numéro de version, CFN: 1. crée un nouveau groupe de mise à l'échelle automatique et fait tourner les instances souhaitées 2. tue les instances de l'ancien groupe de mise à l'échelle automatique et le supprime

Voici un morceau de code de ma pile où j'utilise cette technique pour forcer un grand nombre de machines EC2 à recréer et à extraire automatiquement de nouveaux logiciels de S3.

AutoScalingGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
        AutoScalingGroupName: !Sub "${StackName}-${ServiceName}-${ServiceVersion}"
marcopeg
la source