AWS SNS
Le service de messagerie et notifications entièrement géré qui permet la coordination et la communication entre les applications distribuées, avec prise en charge de plusieurs protocoles et modèles de livraison.
Qu'est-ce qu'AWS SNS ?
Imaginez un système de messagerie instantanée, mais pour vos applications et services informatiques. AWS SNS (Simple Notification Service) est exactement cela : un service de notification qui permet à différentes parties de votre infrastructure de communiquer entre elles, et même avec les utilisateurs.
Concrètement, SNS fonctionne comme un diffuseur de messages : une application peut envoyer un message important à SNS, qui se charge ensuite de le transmettre instantanément à tous les destinataires intéressés, qu'il s'agisse d'autres applications, d'emails, de SMS, ou de notifications mobiles.
Comment ça fonctionne ?
Topics
Un "topic" dans SNS est comme un canal de diffusion. Les applications peuvent publier des messages sur ce topic, et tous ceux qui y sont abonnés recevront ces messages.
Abonnements
Les abonnements déterminent qui reçoit les messages : d'autres services AWS, des applications web, des adresses email, des numéros de téléphone, ou même des applications mobiles.
Pourquoi est-ce si utile ?
Communication instantanée
SNS permet de réagir immédiatement aux événements importants, comme un nouvel achat, une alerte de sécurité ou un changement de statut.
Diffusion large
Un message envoyé une seule fois peut être distribué à des milliers, voire des millions de destinataires, sans effort supplémentaire.
Fiabilité garantie
AWS s'assure que vos messages seront délivrés, avec des mécanismes de réessai automatique et une architecture hautement disponible.
Découplage des systèmes
Les applications peuvent communiquer sans dépendre directement les unes des autres, ce qui rend l'architecture plus souple et plus robuste.
En résumé, AWS SNS est comme un assistant efficace qui se charge de transmettre instantanément les messages importants à tous ceux qui doivent les recevoir, qu'il s'agisse d'autres services, d'applications ou directement d'utilisateurs humains.
Fonctionnement technique
AWS SNS est un service de messagerie pub/sub entièrement géré qui utilise le modèle de publication-abonnement (publish-subscribe). Il permet de découpler les composants d'une application distribuée en permettant la transmission de messages entre éditeurs et abonnés.
Les concepts fondamentaux
Publication simple
La base de SNS est la publication de messages vers un topic. Ce code montre comment envoyer un message à tous les abonnés d'un topic SNS.
// Exemple d'utilisation de l'SDK AWS avec Node.js pour AWS SNS
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";
// Initialiser le client SNS
const client = new SNSClient({ region: "eu-west-3" });
// Fonction pour envoyer un message simple vers un topic SNS
async function publishMessageToTopic(topicArn, message, subject) {
const params = {
TopicArn: topicArn,
Message: message,
Subject: subject // Optionnel, utile pour les emails
};
try {
const command = new PublishCommand(params);
const data = await client.send(command);
console.log("Message publié avec succès:", data.MessageId);
return data.MessageId;
} catch (error) {
console.error("Erreur lors de la publication du message:", error);
throw error;
}
}
// Exemple d'utilisation
publishMessageToTopic(
"arn:aws:sns:eu-west-3:123456789012:mon-topic",
"Voici un message important pour tous les abonnés",
"Notification importante"
);
Création de Topics
Les topics sont les canaux de communication dans SNS. Ils peuvent être standards (ordre non garanti) ou FIFO (First-In-First-Out) pour garantir l'ordre des messages.
// Créer un topic SNS
import { SNSClient, CreateTopicCommand } from "@aws-sdk/client-sns";
async function createSNSTopic(topicName, attributes = {}) {
const client = new SNSClient({ region: "eu-west-3" });
const params = {
Name: topicName,
Attributes: attributes
};
try {
const command = new CreateTopicCommand(params);
const response = await client.send(command);
console.log("Topic créé avec succès:", response.TopicArn);
return response.TopicArn;
} catch (error) {
console.error("Erreur lors de la création du topic:", error);
throw error;
}
}
// Créer un topic standard
createSNSTopic("mon-topic-standard");
// Créer un topic FIFO (First-In-First-Out)
createSNSTopic("mon-topic-fifo.fifo", {
"FifoTopic": "true",
"ContentBasedDeduplication": "true"
});
Gestion des abonnements
SNS peut diffuser des messages vers de nombreux types de points de terminaison, y compris SQS, Lambda, HTTP/S, email, SMS et notifications mobiles.
// Gérer les abonnements à un topic SNS
import {
SNSClient,
SubscribeCommand,
ListSubscriptionsByTopicCommand,
UnsubscribeCommand
} from "@aws-sdk/client-sns";
const client = new SNSClient({ region: "eu-west-3" });
// Créer un abonnement à un topic
async function subscribeToTopic(topicArn, protocol, endpoint) {
const params = {
TopicArn: topicArn,
Protocol: protocol, // sqs, lambda, email, sms, http, https, application
Endpoint: endpoint
};
try {
const command = new SubscribeCommand(params);
const response = await client.send(command);
console.log("Abonnement créé avec succès:", response.SubscriptionArn);
return response.SubscriptionArn;
} catch (error) {
console.error("Erreur lors de la création de l'abonnement:", error);
throw error;
}
}
// Lister les abonnements d'un topic
async function listSubscriptions(topicArn) {
const params = {
TopicArn: topicArn
};
try {
const command = new ListSubscriptionsByTopicCommand(params);
const response = await client.send(command);
console.log("Abonnements:", response.Subscriptions);
return response.Subscriptions;
} catch (error) {
console.error("Erreur lors de la récupération des abonnements:", error);
throw error;
}
}
// Se désabonner
async function unsubscribe(subscriptionArn) {
const params = {
SubscriptionArn: subscriptionArn
};
try {
const command = new UnsubscribeCommand(params);
await client.send(command);
console.log("Désabonnement réussi");
return true;
} catch (error) {
console.error("Erreur lors du désabonnement:", error);
throw error;
}
}
// Exemples d'utilisation
const topicArn = "arn:aws:sns:eu-west-3:123456789012:mon-topic";
// Abonnement d'une fonction Lambda
subscribeToTopic(
topicArn,
"lambda",
"arn:aws:lambda:eu-west-3:123456789012:function:ma-fonction"
);
// Abonnement d'une file SQS
subscribeToTopic(
topicArn,
"sqs",
"arn:aws:sqs:eu-west-3:123456789012:ma-file"
);
// Abonnement par email
subscribeToTopic(
topicArn,
"email",
"exemple@domaine.com"
);
Formats JSON et filtrage
SNS permet d'envoyer des messages au format JSON avec différents formats pour différents types d'abonnements, et de filtrer les messages avec des attributs.
// Publication de messages au format JSON et avec filtrage
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";
const client = new SNSClient({ region: "eu-west-3" });
// Fonction pour publier un message structuré en JSON
async function publishJSONMessage(topicArn, messageData, messageAttributes = {}) {
// Structurer le message en JSON
const message = JSON.stringify(messageData);
// Préparer les attributs de message pour le filtrage
const formattedAttributes = {};
Object.entries(messageAttributes).forEach(([key, value]) => {
formattedAttributes[key] = {
DataType: typeof value === 'number' ? 'Number' : 'String',
StringValue: value.toString()
};
});
const params = {
TopicArn: topicArn,
Message: message,
MessageStructure: "json", // Indique à SNS que le message est au format JSON
MessageAttributes: formattedAttributes
};
try {
const command = new PublishCommand(params);
const data = await client.send(command);
console.log("Message JSON publié avec succès:", data.MessageId);
return data.MessageId;
} catch (error) {
console.error("Erreur lors de la publication du message JSON:", error);
throw error;
}
}
// Exemple d'utilisation avec différents formats pour différents protocoles
publishJSONMessage(
"arn:aws:sns:eu-west-3:123456789012:mon-topic",
{
default: "Message par défaut pour les protocoles sans format spécifique",
email: "Ce message sera envoyé par email",
sqs: JSON.stringify({
id: 12345,
event: "nouveau_client",
timestamp: new Date().toISOString(),
data: {
nom: "Dupont",
email: "dupont@exemple.fr"
}
})
},
{
// Attributs pour le filtrage par les abonnés
event_type: "user_registration",
priority: 1,
region: "europe"
}
);
Envoi de SMS
SNS peut être utilisé pour envoyer des SMS directement aux utilisateurs, ce qui est idéal pour les notifications, les alertes et l'authentification à deux facteurs.
// Envoi de SMS via AWS SNS
import { SNSClient, PublishCommand, SetSMSAttributesCommand } from "@aws-sdk/client-sns";
const client = new SNSClient({ region: "eu-west-3" });
// Configurer les attributs SMS globaux (à faire une seule fois)
async function configureSMSAttributes() {
const params = {
attributes: {
DefaultSenderID: "MaSociete", // ID de l'expéditeur qui apparaîtra sur les appareils des destinataires
DefaultSMSType: "Transactional" // Transactional ou Promotional
}
};
try {
const command = new SetSMSAttributesCommand(params);
await client.send(command);
console.log("Attributs SMS configurés avec succès");
} catch (error) {
console.error("Erreur lors de la configuration des attributs SMS:", error);
throw error;
}
}
// Envoyer un SMS directement (sans passer par un topic)
async function sendSMS(phoneNumber, message) {
const params = {
PhoneNumber: phoneNumber, // Format international: +33612345678
Message: message,
MessageAttributes: {
'AWS.SNS.SMS.SenderID': {
DataType: 'String',
StringValue: 'MaSociete'
},
'AWS.SNS.SMS.SMSType': {
DataType: 'String',
StringValue: 'Transactional' // Pour les messages critiques
}
}
};
try {
const command = new PublishCommand(params);
const data = await client.send(command);
console.log("SMS envoyé avec succès:", data.MessageId);
return data.MessageId;
} catch (error) {
console.error("Erreur lors de l'envoi du SMS:", error);
throw error;
}
}
// Configurer les attributs SMS
configureSMSAttributes();
// Exemple d'envoi de SMS
sendSMS(
"+33612345678",
"Votre code de vérification est 123456. Il expire dans 10 minutes."
);
Architecture de Fan-out
Un des modèles d'utilisation les plus puissants de SNS est le fan-out, où un message est distribué à plusieurs destinations simultanément.
// Architecture de diffusion (fan-out) avec AWS SNS et plusieurs services
import {
SNSClient,
CreateTopicCommand,
SubscribeCommand,
PublishCommand
} from "@aws-sdk/client-sns";
const client = new SNSClient({ region: "eu-west-3" });
// Configuration initiale du système de notifications
async function setupNotificationSystem() {
try {
// 1. Créer un topic central pour les événements
const createTopicCommand = new CreateTopicCommand({
Name: "system-events"
});
const topicResult = await client.send(createTopicCommand);
const topicArn = topicResult.TopicArn;
console.log("Topic créé:", topicArn);
// 2. Créer des abonnements pour différents services
// Abonnement pour une fonction Lambda qui traite les événements
const lambdaSubscribeCommand = new SubscribeCommand({
TopicArn: topicArn,
Protocol: "lambda",
Endpoint: "arn:aws:lambda:eu-west-3:123456789012:function:process-events",
FilterPolicy: JSON.stringify({
event_type: ["user_action", "system_alert"]
})
});
await client.send(lambdaSubscribeCommand);
// Abonnement pour une file SQS qui stocke les événements pour traitement ultérieur
const sqsSubscribeCommand = new SubscribeCommand({
TopicArn: topicArn,
Protocol: "sqs",
Endpoint: "arn:aws:sqs:eu-west-3:123456789012:events-queue",
FilterPolicy: JSON.stringify({
priority: ["1", "2"]
})
});
await client.send(sqsSubscribeCommand);
// Abonnement pour les notifications par email (pour les administrateurs)
const emailSubscribeCommand = new SubscribeCommand({
TopicArn: topicArn,
Protocol: "email",
Endpoint: "admin@exemple.fr",
FilterPolicy: JSON.stringify({
priority: ["1"] // Seulement les événements de haute priorité
})
});
await client.send(emailSubscribeCommand);
// Abonnement pour les notifications par SMS (pour les alertes critiques)
const smsSubscribeCommand = new SubscribeCommand({
TopicArn: topicArn,
Protocol: "sms",
Endpoint: "+33612345678",
FilterPolicy: JSON.stringify({
event_type: ["critical_alert"],
priority: ["1"]
})
});
await client.send(smsSubscribeCommand);
return topicArn;
} catch (error) {
console.error("Erreur lors de la configuration du système de notification:", error);
throw error;
}
}
// Fonction pour publier un événement
async function publishEvent(topicArn, eventType, priority, data) {
try {
const payload = {
event_type: eventType,
timestamp: new Date().toISOString(),
data: data
};
const publishCommand = new PublishCommand({
TopicArn: topicArn,
Message: JSON.stringify(payload),
MessageAttributes: {
event_type: {
DataType: "String",
StringValue: eventType
},
priority: {
DataType: "Number",
StringValue: priority.toString()
}
}
});
const result = await client.send(publishCommand);
console.log("Événement publié:", result.MessageId);
return result.MessageId;
} catch (error) {
console.error("Erreur lors de la publication de l'événement:", error);
throw error;
}
}
// Exemple d'utilisation
async function runExample() {
const topicArn = await setupNotificationSystem();
// Publier différents types d'événements
// Alerte critique - sera envoyée à tous les abonnés
await publishEvent(
topicArn,
"critical_alert",
1,
{
message: "Panne du serveur principal détectée",
affected_services: ["api", "database"],
details: "Haute latence et timeouts constatés"
}
);
// Action utilisateur - seulement Lambda et SQS
await publishEvent(
topicArn,
"user_action",
2,
{
user_id: "user123",
action: "checkout",
cart_value: 159.99
}
);
}
Caractéristiques principales
- Topics Standard et FIFO - Les topics standard offrent un débit élevé tandis que les topics FIFO garantissent l'ordre des messages et la déduplication
- Filtrage des messages - Les abonnés peuvent filtrer les messages qu'ils reçoivent en fonction des attributs de message
- Cryptage des données - Cryptage au repos et en transit avec AWS KMS
- Large éventail de protocoles - Support pour SQS, Lambda, HTTP/S, email, SMS et notifications push mobiles
- Acheminement basé sur le contenu - Distribution des messages selon le contenu à différents points de terminaison
- Politique d'accès - Contrôle précis de qui peut publier et s'abonner aux topics
- Traçabilité - Intégration avec CloudWatch, CloudTrail et X-Ray pour le monitoring et le débogage
- Archivage et rejeu - Possibilité d'archiver les messages et de les rejouer en cas de besoin
Comparaison avec AWS SQS
Caractéristique | AWS SNS | |
---|---|---|
Modèle de messagerie | Publication/abonnement (pub/sub) | File d'attente (queue) |
Distribution | 1:N (un message, plusieurs destinataires) | 1:1 (un message, un destinataire) |
Cas d'usage | Diffuser des notifications à plusieurs systèmes | Traitement asynchrone, découplage |
Conservation des messages | Non, délivré une fois (sauf échec) | Oui, jusqu'à ce qu'il soit traité |
Intégration client | Push (SNS publie vers abonnés) | Pull (les clients interrogent SQS) |
Astuce : SNS et SQS sont souvent utilisés ensemble dans une architecture "fan-out" où SNS publie des messages vers plusieurs files SQS pour un traitement parallèle par différents services.
Cas d'usage
Authentification à deux facteurs (2FA)
Utilisation de SNS pour envoyer des codes de vérification par SMS ou email, renforçant la sécurité des applications en ajoutant une couche d'authentification supplémentaire.
Notifications utilisateurs
Envoi de notifications aux utilisateurs via SMS, email ou push mobile pour des événements comme des confirmations de commande, des rappels de rendez-vous ou des alertes de statut.
Traitement parallèle avec fan-out
Distribution d'un même message à plusieurs files SQS ou fonctions
Lambda pour un traitement parallèle, idéal pour les architectures microservices et le traitement des événements.
Alertes et monitoring
Envoi d'alertes aux équipes techniques en cas de problèmes détectés par les systèmes de monitoring, permettant une réaction rapide aux incidents.
Déclenchement de workflows
Utilisation de SNS pour déclencher des workflows Step Functions ou des pipelines de traitement de données en réponse à des événements spécifiques.
Mises à jour en temps réel
Notification des clients web et mobiles en temps réel via une combinaison de SNS et de services comme AWS AppSync ou des API WebSocket.