Comment supprimer une ressource personnalisée basée sur Lambda qui est bloquée avec le statut « DELETE_FAILED » ou « DELETE_IN_PROGRESS » dans CloudFormation ?

Date de la dernière mise à jour : 23/08/2021

Ma ressource personnalisée basée sur AWS Lambda est bloquée avec le statut « DELETE_FAILED » ou « DELETE_IN_PROGRESS » dans AWS CloudFormation. Je souhaite supprimer ma ressource personnalisée.

Brève description

Choisissez l'une des solutions suivantes :

  • Supprimer une ressource personnalisée bloquée avec le statut « DELETE_FAILED »
  • Supprimer une ressource personnalisée bloquée avec le statut « DELETE_IN_PROGRESS »

Résolution

Supprimer une ressource personnalisée bloquée avec le statut « DELETE_FAILED »

Une erreur survient si vous supprimez une pile lorsque votre ressource personnalisée basée sur Lambda ne dispose pas de la logique nécessaire pour gérer les demandes de suppression. Vous pouvez également obtenir une erreur si votre ressource personnalisée présente une logique de suppression incorrecte. Le message d'erreur suivant apparaît : « Une ressource personnalisée n'a pas pu être stabilisée pendant le délai prévu. » La pile affiche le statut « DELETE_FAILED ».

Pour supprimer votre pile, procédez comme suit :

1.    Ouvrez la console CloudFormation.

2.    Choisissez la pile contenant votre ressource personnalisée bloquée avec le statut « DELETE_FAILED ».

3.    Choisissez Actions, puis Supprimer la pile.

4.    Dans la fenêtre contextuelle contenant une liste de ressources à conserver, choisissez la ressource personnalisée bloquée avec le statut « DELETE_FAILED ». Cliquez sur « Supprimer ».

5.    Choisissez Actions, puis Supprimer la pile.

Votre pile affiche l'état DELETE_COMPLETE.

Remarque : votre ressource personnalisée n'est pas une ressource physique, vous n'avez donc pas à la nettoyer après la suppression de la pile.

Supprimer une ressource personnalisée bloquée avec le statut « DELETE_IN_PROGRESS »

Si votre pile est bloquée avec le statut « DELETE_IN_PROGRESS » lors de la suppression d'une ressource personnalisée, il se peut qu'elle ne dispose pas de la logique nécessaire pour gérer les demandes de suppression. Il est également possible que la logique de suppression de votre pile soit erronée.

Pour forcer la pile à effectuer la suppression, vous devez envoyer le signal « SUCCESS » manuellement. Le signal nécessite les valeurs ResponseURL et RequestId, toutes deux incluses dans l'événement envoyé depuis CloudFormation vers Lambda.

1.    Vérifiez que votre fonction Lambda journalise les détails de l'événement.

Si votre fonction Lambda n'inclut pas la logique d'impression de l'événement dans les journaux, il vous sera impossible de récupérer les valeurs ResponseURL et RequestId. Ces valeurs sont nécessaires pour envoyer un signal manuel. Dans ce cas, vous devez attendre l'expiration de la pile CloudFormation, soit environ une heure, et passer au statut DELETE_FAILED. Suivez ensuite les étapes de la section Supprimer une ressource personnalisée bloquée avec le statut « DELETE_FAILED » pour supprimer votre pile.

Remarque : si votre fonction Lambda dispose déjà de la logique suivante, passez à l'étape 2.

Exemple de logique :

exports.handler = function(event, context) {
    console.log("REQUEST RECEIVED:\n" + JSON.stringify(event));
...
}

2.    Dans votre modèle CloudFormation, identifiez le nom de la fonction Lambda à laquelle votre ressource personnalisée envoie des demandes. Vous pouvez rechercher le nom de la fonction dans la propriété ServiceToken de la ressource AWS::CloudFormation::CustomResource ou Custom::String. Par exemple :

MyCustomResource: 
  Type: "Custom::PingTester"
  Properties: 
    ServiceToken:
      !Sub |
        arn:aws:lambda:us-east-1:111122223333:function:awsexamplelambdafunction

3.    Ouvrez la console Lambda.

4.    Dans le volet de navigation, choisissez Fonctions, puis sélectionnez la fonction que vous avez identifiée à l'étape 1. Par exemple, awsexamplelambdafunction est le nom de la fonction dans l'exemple de code ci-dessus.

5.    Choisissez l'onglet Surveillance, puis cliquez sur Afficher les journaux dans CloudWatch.

6.    Dans la console Amazon CloudWatch, choisissez le dernier journal.

Remarque : vous pouvez voir les journaux CloudWatch uniquement si votre fonction a accès à Amazon CloudWatch Logs pour la transmission en continu des journaux.

7.    Dans le dernier journal, identifiez l'événement où RequestType a pour valeur Supprimer, puis copiez les valeurs pour RequestId, ResponseURL, StackId, LogicalResourceId et PhysicalResourceId. Par exemple :

Received event: {
  "RequestType": "Delete",
  "ServiceToken": "arn:aws:lambda:us-east-1:111122223333:function:awsexamplelambdafunction",
  "ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.us-east-1.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A111122223333%3Astack/awsexamplecloudformation/33ad60e0-5f25-11e9-a734-0aa6b80efab2%7CMyCustomResource%7Ce2fc8f5c-0391-4a65-a645-7c695646739?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170313T0212304Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=QWERTYUIOLASDFGBHNZCV%2F20190415%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=dgvg36bh23mk44nj454bjb54689bg43r8v011uerehiubrjrug5689ghg94hb",
  "StackId": "arn:aws:cloudformation:us-east-1:111122223333:stack/awsexamplecloudformation/33ad60e0-5f25-11e9-a734-0aa6b80efab2",
  "RequestId": "e2fc8f5c-0391-4a65-a645-7c695646739",
  "LogicalResourceId": "MyCustomResource",
  "PhysicalResourceId": "test-MyCustomResource-1URTEVUHSKSKDFF",
  "ResourceType": "Custom::PingTester"

8.    Pour envoyer le signal « SUCCESS » dans l'objet de réponse à la demande de suppression, exécutez la commande suivante. Veillez à inclure les valeurs copiées à l'étape 7.

$ curl -H 'Content-Type: ''' -X PUT -d '{
    "Status": "SUCCESS",
    "PhysicalResourceId": "test-CloudWatchtrigger-1URTEVUHSKSKDFF",
    "StackId": "arn:aws:cloudformation:us-east-1:111122223333:stack/awsexamplecloudformation/33ad60e0-5f25-11e9-a734-0aa6b80efab2
  ",
    "RequestId": "e2fc8f5c-0391-4a65-a645-7c695646739",
    "LogicalResourceId": "CloudWatchtrigger"
  }' 'https://cloudformation-custom-resource-response-useast1.s3.us-east-1.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A111122223333%3Astack/awsexamplecloudformation/33ad60e0-5f25-11e9-a734-0aa6b80efab2%7CMyCustomResource%7Ce2fc8f5c-0391-4a65-a645-7c695646739?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170313T0212304Z&X-Amz-SignedHeaders=host&X-Amz-Expires=7200&X-Amz-Credential=QWERTYUIOLASDFGBHNZCV%2F20190415%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=dgvg36bh23mk44nj454bjb54689bg43r8v011uerehiubrjrug5689ghg94hb
  '

Vos ressources personnalisées passent au statut « DELETE_COMPLETE » dans les événements de pile CloudFormation.