web-dev-qa-db-fra.com

Comment forcer une pile CloudFormation à se mettre à jour lorsque le paramètre est mis à jour?

J'exécute une pile AWS CloudFormation qui accepte certains paramètres et lance des instances EC2 avec d'autres ressources AWS. Les paramètres sont introduits dans les données utilisateur de l'instance EC2 et en fonction de cela, des modifications sont apportées dynamiquement à l'application Web résidant sur l'instance EC2.

CFN Parameters

UserData: 
      Fn::Base64: 
        Fn::Join: 
          - ""
          - 
            - "#!/bin/bash \n"
            - "sh website-conf/website_mysql_config.sh "
            - " -c \""
            - 
              Ref: "CompanyName"

Comme le montre l'exemple ci-dessus, CompanyName est l'un des nombreux paramètres transmis au script userdata. Le problème est que, lorsqu'un ou plusieurs paramètres sont mis à jour, CloudFormation ne le détecte pas et renvoie plutôt cette erreur.

CFN Error

Donc, afin de mettre à jour la pile, je dois éditer la pile et apporter des modifications à l'ASG afin que CloudFormation 'voit' les changements et exécute la mise à jour de la pile.

Existe-t-il un moyen de forcer CFN à mettre à jour la pile lorsque les paramètres sont mis à jour?

7
captainblack

Utilisez la commande AWS CLI Update-Stack. Si vous utilisez l'AWS CLI, vous pouvez injecter des paramètres dans votre pile de sorte que toute modification apportée à l'un des paramètres entraîne une nouvelle pile. Je le fais moi-même pour injecter l'ID de validation de Git/version dans UserData, donc la simple validation des modifications du JSON/Yaml de la pile dans Git permettra les mises à jour de la pile. Toute modification du fichier de paramètres permettra des mises à jour de la pile, même juste un commentaire. Je référence mon ID de validation Git dans UserData de la même manière que vous faites référence à Ref: CompanyName, donc lorsque je change l'ID de validation Git, la section userData est mise à jour lors des mises à jour de la pile.

Mettre à jour la commande de pile

aws cloudformation update-stack --stack-name MyStack --template-body file:///Users/Documents/Git/project/cloudformation/stack.json --parameters file:///Users/Documents/Git/project/cloudformation/parameters/stack-parameters.dev.json --capabilities CAPABILITY_IAM

Processus

Avec cette approche, vous modifiez vos paramètres dans le fichier json ou yaml de paramètres, puis vous le vérifiez dans le contrôle de version. Maintenant, si vous utilisez un serveur de build, vous pouvez mettre à jour votre pile en vérifiant master et en exécutant simplement cette ligne ci-dessus. L'utilisation d'AWS CodeBuild vous facilite la tâche, vous n'avez donc pas besoin de Jenkins.

3
Usman Mutawakil

CloudFormation ne mettra pas à jour la pile sauf s'il y a un changement dans les propriétés des ressources déjà créé dans la pile.

Par exemple: Considérez que j'ai un modèle simple pour créer une base de données où je dois passer 2 paramètres:

  1. nom-db
  2. région

Supposons que j'utilise db-name en le passant comme valeur à DBInstanceIdentifier.

Supposons également que je n'utilise le paramètre d'entrée region à aucune fin dans la création de ressources (ou de ses propriétés) de la pile de quelque manière que ce soit. Il s'agit davantage d'un paramètre factice que je conserve à des fins de lisibilité.

J'ai réussi (TEST-DB1, us-east-1) en tant que paramètres d'entrée dans le modèle CloudFormation et créé avec succès les ressources.

Scenario-1: Maintenant, si je mets à jour la pile ( en utilisant toujours le modèle existant ) et que je change simplement les paramètres d'entrée en (TEST-DB2, us-east-1). c'est-à-dire: changer uniquement le nom de la base de données et non la région. Ensuite, CloudFormation détectera que cette mise à jour des paramètres entraîne une modification des propriétés des ressources en cours d'exécution de la pile et calculera et affichera les modifications sous la forme d'un ensemble de modifications.

Scenario-2: Supposons que je fasse une autre mise à jour ( en utilisant toujours la propriété de modèle existante ) et que je change simplement les paramètres d'entrée en (TEST-DB1, us-east-2). c'est-à-dire: changer uniquement la région et non le nom de la base de données. Ensuite, CloudFormation détectera que, cette mise à jour des paramètres, entraînera AUCUN changement dans les propriétés des ressources en cours d'exécution de la pile affichera le Error creating change set.

Conclusion: Votre modification du paramètre d'entrée doit entraîner une mise à jour/remplacement de tout les ressources (ou ses attributs comme les groupes de sécurité, le port, etc.) de la pile. Ensuite, AWS CloudFormation les affichera sous la forme Change Sets pour votre avis. De plus, la méthode (mise à jour ou remplacement) qu'AWS CloudFormation utilise dépend de la propriété que vous mettez à jour pour un type de ressource donné.

Votre paramètre "CompanyName" n'apporte aucune modification aux ressources en cours d'exécution de la pile. Par conséquent, il indique que Error creating change set. Vous devez l'utiliser pour créer toute ressource/propriété de ressource de la pile. Ensuite, CloudFormation détectera les ensembles de modifications lorsque vous le modifierez. Il en va de même pour tous les autres paramètres d'entrée que vous utilisez.

8
Madhukar Mohanraju

La réponse à votre problème est déjà répondue avec cet état, CloudFormation ne mettra pas à jour la pile sauf s'il y a un changement dans les propriétés des ressources déjà créées dans la pile.

Et pour la réponse à votre question, veuillez vérifier l'explication ci-dessous.

Il existe un moyen de forcer Cloudformation à mettre à jour la pile à l'aide de AWS::CloudFormation::Init. En utilisant cfn-init, chaque instance peut se mettre à jour lorsqu'elle détecte la modification apportée par AWS::CloudFormation::Init dans les métadonnées.

Il y a un concept que nous devons d'abord comprendre, c'est la différence entre UserData et les métadonnées, au moins sous le AWS::CloudFormation::Init Cas.

  • Userdata: ne sera appelé qu'une seule fois lors du premier lancement de l'instance (y compris la mise à jour nécessitant le remplacement de l'instance). Donc, si vous mettez à jour la pile (sans en créer une nouvelle), même si vous changez la valeur du paramètre, cela ne changera rien si vous appelez le paramètre sous UserData.
  • Metadata: peut être mis à jour à tout moment. Pour que cela fonctionne, vous devez vous assurer que le démon qui détecte les métadonnées modifiées est en cours d'exécution (le démon est appelé cfn-hup)

Si vous utilisez déjà les Metadata et AWS::CloudFormation::Init, les données ne sont pas immédiatement mises à jour. Pour autant que je sache, voici la condition que les données soient modifiées après avoir changé la valeur Metadata.

  • Redémarrez l'instance
  • Courir cfn-init commande à nouveau avec son paramètre
  • Attendre environ 15 minutes, car le démon pour vérifier la modification dans Metadata vérifie la modification une fois toutes les 15 minutes.
1
sin