Lors de l'abonnement d'une rubrique Amazon SNS (Amazon Simple Notification Service) ou d'une fonction AWS Lambda à des notifications d'événement Amazon S3 (Simple Storage Service), je reçois le message d'erreur « Unable to validate the following destination configurations » (Impossible de valider les configurations de destination suivantes). Lorsque j'essaie de définir une dépendance sur la stratégie de rubrique SNS à partir du compartiment S3 dans mon modèle, je reçois une erreur de validation de dépendance circulaire.

Dans la mesure où AWS CloudFormation gère l'ordre des dépendances, les notifications d'événement Amazon S3 sont définies en tant qu'attribut du compartiment S3 et elles sont établies lors de la création de la ressource de compartiment S3.

Vous devez donc créer les ressources dans l'ordre suivant :​
Remarque : Cette résolution utilise une rubrique Amazon SNS comme exemple. La résolution est similaire si vous recevez les erreurs lorsque vous utilisez une fonction AWS Lambda.

  1. Créez la rubrique SNS car le compartiment S3 y fait référence.
  2. Créez le compartiment S3 car la stratégie de rubrique SNS fait référence au compartiment S3 et à la rubrique SNS.

Avant d'abonner une rubrique SNS aux notifications d'événement S3, vous devez spécifier une stratégie de rubrique (AWS::SNS::TopicPolicy) avec les autorisations appropriées. Cette stratégie doit être créée avant l'abonnement.

Essayez une des stratégies suivantes pour éviter l'erreur « Unable to validate the following destination configurations » lors de l'utilisation des notifications d'événement S3.

Spécifier une valeur pour BucketName dans le modèle CloudFormation

Utilisez un nom statique pour votre compartiment S3 en spécifiant une valeur pour la propriété BucketName dans la ressource de compartiment S3 du modèle CloudFormation. Cela élimine la nécessité d'inclure { "Ref": "paramBucketName" } dans la stratégie de rubrique SNS et supprime la dépendance intrinsèque entre la stratégie de rubrique SNS et Amazon S3.

Par exemple, le modèle CloudFormation suivant spécifie une valeur codée en dur ("-Bucket-Name-") pour la propriété BucketName. Si vous utilisez un modèle similaire, n'oubliez pas de remplacer toutes les instances de "-Bucket-Name-" par le nom de compartiment de votre cas d'utilisation.

{
  "Resources": {
    "SNSTopic": {
        "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
        "Type": "AWS::SNS::TopicPolicy",
        "Properties": {
            "PolicyDocument": {
                "Id": "MyTopicPolicy",
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Sid": "Statement-id",
                        "Effect": "Allow",
                        "Principal": { "AWS": "*" },
                        "Action": "sns:Publish",
                        "Resource": { "Ref": "SNSTopic" },
                        "Condition": {
                            "ArnLike": {
                                "aws:SourceArn": { "Fn::Join": [ "", [ "arn:aws:s3:::", "-Bucket-Name-" ]]} }
                        }
                    }
                ]
            },
            "Topics": [ { "Ref": "SNSTopic" } ]
        }
    },
    "S3Bucket": {
        "Type": "AWS::S3::Bucket",
        "DependsOn": ["SNSTopicPolicy"],
        "Properties": {
            "AccessControl": "BucketOwnerFullControl",
            "BucketName": "-Bucket-Name-",
            "NotificationConfiguration": {
                "TopicConfigurations": [
                    {
                        "Topic": { "Ref": "SNSTopic" },
                        "Event": "s3:ObjectCreated:Put"
                    }
                ]
            }
        }
    }
  }
}

Remarque : La ressource S3Bucket a une valeur explicite DependsOn définie sur SNSTopicPolicy. Cet attribut spécifie que le modèle créera la ressource SNSTopicPolicy avant la ressource S3Bucket.

Pour utiliser le même modèle CloudFormation pour des compartiments S3 avec des noms différents, vous pouvez définir un paramètre pour le nom de compartiment. Ce paramètre vous permet d'utiliser le même modèle pour plusieurs noms de compartiment en transmettant le nom en tant que paramètre au cours de la création de la pile.

Par exemple, pour utiliser le modèle suivant, vous devez transmettre le nom de compartiment en tant que paramètre "paramBucketName" au cours de la création de la pile.

{
  "Parameters": {
    "paramBucketName": {
      "Type": "String",
      "Description": "Bucket Name"
    }
  },
  "Resources": {
    "SNSTopic": {
        "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
        "Type": "AWS::SNS::TopicPolicy",
        "Properties": {
            "PolicyDocument": {
                "Id": "MyTopicPolicy",
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Sid": "Statement-id",
                        "Effect": "Allow",
                        "Principal": { "AWS": "*" },
                        "Action": "sns:Publish",
                        "Resource": { "Ref": "SNSTopic" },
                        "Condition": {
                            "ArnLike": {
                                "aws:SourceArn": { "Fn::Join": [ "", [ "arn:aws:s3:::", {"Ref": "paramBucketName"} ]]} }
                        }
                    }
                ]
            },
            "Topics": [ { "Ref": "SNSTopic" } ]
        }
    },
    "S3Bucket": {
        "Type": "AWS::S3::Bucket",
        "DependsOn": ["SNSTopicPolicy"],
        "Properties": {
            "AccessControl": "BucketOwnerFullControl",
            "BucketName": {"Ref": "paramBucketName"},
            "NotificationConfiguration": {
                "TopicConfigurations": [
                    {
                        "Topic": { "Ref": "SNSTopic" },
                        "Event": "s3:ObjectCreated:Put"
                    }
                ]
            }
        }
    }
  }
}

Créer une pile, puis procéder à sa mise à jour

Divisez la création de pile en deux étapes. Commencez par créer la pile, mais ne spécifiez pas la propriété NotificationConfiguration dans la ressource de compartiment S3. Ensuite, effectuez une mise à jour de la pile afin d'ajouter la notification d'événement S3. Cela vous évite de définir la notification d'événement S3 avant la création de la stratégie de rubrique SNS.

Lors de la première étape, créez toutes les ressources, dont la stratégie de la rubrique SNS, comme illustré dans cet exemple :

{
    "Resources": {
        "SNSTopic": {
            "Type": "AWS::SNS::Topic"
        },
        "SNSTopicPolicy": {
            "Type": "AWS::SNS::TopicPolicy",
            "Properties": {
                "PolicyDocument": {
                    "Id": "MyTopicPolicy",
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Sid": "Statement-id",
                            "Effect": "Allow",
                            "Principal": { "AWS": "*" },
                            "Action": "sns:Publish",
                            "Resource": { "Ref": "SNSTopic" },
                            "Condition": {
                                "ArnLike": {
                                    "aws:SourceArn": { "Fn::Join": [ "", [ "arn:aws:s3:::", { "Ref": "S3Bucket" } ] ]
                                    }
                                }
                            }
                        }
                    ]
                },
                "Topics": [ { "Ref": "SNSTopic" } ]
            }
        },
        "S3Bucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "AccessControl": "BucketOwnerFullControl"
            }
        }
    }
}

Ensuite, mettez à jour la pile de façon à ajouter la notification d'événement S3, comme illustré dans cet exemple : 

{
  "Resources": {
        "SNSTopic": {
        "Type": "AWS::SNS::Topic"
    },
    "SNSTopicPolicy": {
        "Type": "AWS::SNS::TopicPolicy",
        "Properties": {
            "PolicyDocument": {
                "Id": "MyTopicPolicy",
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Sid": "Statement-id",
                        "Effect": "Allow",
                        "Principal": { "AWS": "*" },
                        "Action": "sns:Publish",
                        "Resource": { "Ref": "SNSTopic" },
                        "Condition": {
                            "ArnLike": {
                                "aws:SourceArn": { "Fn::Join": [ "", [ "arn:aws:s3:::", { "Ref": "S3Bucket" } ] ]
                                }
                            }
                        }
                    }
                ]
            },
            "Topics": [ { "Ref": "SNSTopic" } ]
        }
    },
    "S3Bucket": {
        "Type": "AWS::S3::Bucket",
        "Properties": {
            "AccessControl": "BucketOwnerFullControl",
            "NotificationConfiguration": {
                "TopicConfigurations": [
                    {
                        "Topic": { "Ref": "SNSTopic" },
                        "Event": "s3:ObjectCreated:Put"
                    }
                ]
            }
        }
    }
  }
}

Pour plus d'informations, consultez Utilisation des piles.

Remarque : Pour utiliser un modèle CloudFormation YAML, consultez Tool for converting AWS CloudFormation templates between JSON and YAML formats.


Cette page vous a-t-elle été utile ? Oui | Non

Retour au Centre de connaissances AWS Support

Vous avez besoin d'aide ? Consultez le site du Centre AWS Support

Date de publication : 15/09/2016

Date de mise à jour : 02/11/2018