Gestion des notifications d'alarme - AWS IoT Events

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Gestion des notifications d'alarme

AWS IoT Eventsutilise une fonction Lambda pour gérer les notifications d'alarme. Vous pouvez utiliser la fonction Lambda fournie par AWS IoT Events ou en créer une nouvelle.

Création d'une fonction Lambda

AWS IoT Eventsfournit une fonction Lambda qui permet aux alarmes d'envoyer et de recevoir des notifications par e-mail et SMS.

Prérequis

Les exigences suivantes s'appliquent lorsque vous créez une fonction Lambda pour les alarmes :

  • Si votre alarme envoie des notifications par e-mail ou SMS, vous devez disposer d'un rôle IAM qui vous permet AWS Lambda de travailler avec Amazon SES et Amazon SNS.

    Exemple de politique :

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ses:GetIdentityVerificationAttributes", "ses:SendEmail", "ses:VerifyEmailIdentity" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "sns:Publish", "sns:OptInPhoneNumber", "sns:CheckIfPhoneNumberIsOptedOut" ], "Resource": "*" }, { "Effect": "Deny", "Action": [ "sns:Publish" ], "Resource": "arn:aws:sns:*:*:*" } ] }
  • Vous devez choisir la même AWS région pour les deux AWS IoT Events etAWS Lambda. Pour la liste des régions prises en charge, voir AWS IoT Eventspoints de terminaison et quotas et points de AWS Lambdaterminaison et quotas dans le. Référence générale d'Amazon Web Services

Déploiement d'une fonction Lambda

Ce didacticiel utilise un AWS CloudFormation modèle pour déployer une fonction Lambda. Ce modèle crée automatiquement un rôle IAM qui permet à la fonction Lambda de fonctionner avec Amazon SES et Amazon SNS.

Ce qui suit vous montre comment utiliser le AWS Command Line Interface (AWS CLI) pour créer une CloudFormation pile.

  1. Dans le terminal de votre appareil, exécutez aws --version pour vérifier si vous avez installé leAWS CLI. Pour plus d'informations, consultez Installation d'AWS CLI dans le Guide de l'utilisateur AWS Command Line Interface.

  2. Exécutez aws configure list pour vérifier si vous avez configuré le AWS CLI dans la AWS région qui contient toutes vos AWS ressources pour ce didacticiel. Pour plus d'informations, voir Configuration du AWS CLI dans le guide de AWS Command Line Interface l'utilisateur

  3. Téléchargez le CloudFormation modèle, NotificationLambda.Template.Yaml.zip.

    Note

    Si vous rencontrez des difficultés pour télécharger le fichier, le modèle est également disponible dans leCloudFormation modèle.

  4. Décompressez le contenu et enregistrez-le localement en tant que notificationLambda.template.yaml.

  5. Ouvrez un terminal sur votre appareil et accédez au répertoire dans lequel vous avez téléchargé le notificationLambda.template.yaml fichier.

  6. Pour créer une CloudFormation pile, exécutez la commande suivante :

    aws cloudformation create-stack --stack-name notificationLambda-stack --template-body file://notificationLambda.template.yaml --capabilities CAPABILITY_IAM

Vous pouvez modifier ce CloudFormation modèle pour personnaliser la fonction Lambda et son comportement.

Note

AWS Lambdaréessaie deux fois les erreurs de fonction. Si la fonction ne dispose pas de la capacité suffisante pour gérer toutes les demandes entrantes, des événements peuvent attendre dans la file d'attente pendant des heures ou des jours avant d'être envoyés à la fonction. Vous pouvez configurer une file d'attente de messages non remis (DLQ) sur la fonction pour capturer les événements qui n'ont pas été traités correctement. Pour plus d'informations, consultez Appel asynchrone dans le Guide du développeur AWS Lambda.

Vous pouvez également créer ou configurer la pile dans la CloudFormation console. Pour plus d'informations, consultez la section Utilisation des piles dans le Guide de l'AWS CloudFormationutilisateur.

Création d'une fonction Lambda personnalisée

Vous pouvez créer une fonction Lambda ou modifier celle fournie par. AWS IoT Events

Les exigences suivantes s'appliquent lorsque vous créez une fonction Lambda personnalisée.

  • Ajoutez des autorisations qui permettent à votre fonction Lambda d'effectuer des actions spécifiques et d'accéder aux AWS ressources.

  • Si vous utilisez la fonction Lambda fournie parAWS IoT Events, assurez-vous de choisir le runtime Python 3.7.

Exemple de fonction Lambda :

import boto3 import json import logging import datetime logger = logging.getLogger() logger.setLevel(logging.INFO) ses = boto3.client('ses') sns = boto3.client('sns') def check_value(target): if target: return True return False # Check whether email is verified. Only verified emails are allowed to send emails to or from. def check_email(email): if not check_value(email): return False result = ses.get_identity_verification_attributes(Identities=[email]) attr = result['VerificationAttributes'] if (email not in attr or attr[email]['VerificationStatus'] != 'Success'): logging.info('Verification email for {} sent. You must have all the emails verified before sending email.'.format(email)) ses.verify_email_identity(EmailAddress=email) return False return True # Check whether the phone holder has opted out of receiving SMS messages from your account def check_phone_number(phone_number): try: result = sns.check_if_phone_number_is_opted_out(phoneNumber=phone_number) if (result['isOptedOut']): logger.info('phoneNumber {} is not opt in of receiving SMS messages. Phone number must be opt in first.'.format(phone_number)) return False return True except Exception as e: logging.error('Your phone number {} must be in E.164 format in SSO. Exception thrown: {}'.format(phone_number, e)) return False def check_emails(emails): result = True for email in emails: if not check_email(email): result = False return result def lambda_handler(event, context): logging.info('Received event: ' + json.dumps(event)) nep = json.loads(event.get('notificationEventPayload')) alarm_state = nep['alarmState'] default_msg = 'Alarm ' + alarm_state['stateName'] + '\n' timestamp = datetime.datetime.utcfromtimestamp(float(nep['stateUpdateTime'])/1000).strftime('%Y-%m-%d %H:%M:%S') alarm_msg = "{} {} {} at {} UTC ".format(nep['alarmModelName'], nep.get('keyValue', 'Singleton'), alarm_state['stateName'], timestamp) default_msg += 'Sev: ' + str(nep['severity']) + '\n' if (alarm_state['ruleEvaluation']): property = alarm_state['ruleEvaluation']['simpleRule']['inputProperty'] default_msg += 'Current Value: ' + str(property) + '\n' operator = alarm_state['ruleEvaluation']['simpleRule']['operator'] threshold = alarm_state['ruleEvaluation']['simpleRule']['threshold'] alarm_msg += '({} {} {})'.format(str(property), operator, str(threshold)) default_msg += alarm_msg + '\n' emails = event.get('emailConfigurations', []) logger.info('Start Sending Emails') for email in emails: from_adr = email.get('from') to_adrs = email.get('to', []) cc_adrs = email.get('cc', []) bcc_adrs = email.get('bcc', []) msg = default_msg + '\n' + email.get('additionalMessage', '') subject = email.get('subject', alarm_msg) fa_ver = check_email(from_adr) tas_ver = check_emails(to_adrs) ccas_ver = check_emails(cc_adrs) bccas_ver = check_emails(bcc_adrs) if (fa_ver and tas_ver and ccas_ver and bccas_ver): ses.send_email(Source=from_adr, Destination={'ToAddresses': to_adrs, 'CcAddresses': cc_adrs, 'BccAddresses': bcc_adrs}, Message={'Subject': {'Data': subject}, 'Body': {'Text': {'Data': msg}}}) logger.info('Emails have been sent') logger.info('Start Sending SNS message to SMS') sns_configs = event.get('smsConfigurations', []) for sns_config in sns_configs: sns_msg = default_msg + '\n' + sns_config.get('additionalMessage', '') phone_numbers = sns_config.get('phoneNumbers', []) sender_id = sns_config.get('senderId') for phone_number in phone_numbers: if check_phone_number(phone_number): if check_value(sender_id): sns.publish(PhoneNumber=phone_number, Message=sns_msg, MessageAttributes={'AWS.SNS.SMS.SenderID':{'DataType': 'String','StringValue': sender_id}}) else: sns.publish(PhoneNumber=phone_number, Message=sns_msg) logger.info('SNS messages have been sent')

Pour plus d'informations, veuillez consulter Présentation de AWS Lambda dans le Manuel du développeur AWS Lambda.

CloudFormation modèle

Utilisez le CloudFormation modèle suivant pour créer votre fonction Lambda.

AWSTemplateFormatVersion: '2010-09-09' Description: 'Notification Lambda for Alarm Model' Resources: NotificationLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Path: "/" ManagedPolicyArns: - 'arn:aws:iam::aws:policy/AWSLambdaExecute' Policies: - PolicyName: "NotificationLambda" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "ses:GetIdentityVerificationAttributes" - "ses:SendEmail" - "ses:VerifyEmailIdentity" Resource: "*" - Effect: "Allow" Action: - "sns:Publish" - "sns:OptInPhoneNumber" - "sns:CheckIfPhoneNumberIsOptedOut" Resource: "*" - Effect: "Deny" Action: - "sns:Publish" Resource: "arn:aws:sns:*:*:*" NotificationLambdaFunction: Type: AWS::Lambda::Function Properties: Role: !GetAtt NotificationLambdaRole.Arn Runtime: python3.7 Handler: index.lambda_handler Timeout: 300 MemorySize: 3008 Code: ZipFile: | import boto3 import json import logging import datetime logger = logging.getLogger() logger.setLevel(logging.INFO) ses = boto3.client('ses') sns = boto3.client('sns') def check_value(target): if target: return True return False # Check whether email is verified. Only verified emails are allowed to send emails to or from. def check_email(email): if not check_value(email): return False result = ses.get_identity_verification_attributes(Identities=[email]) attr = result['VerificationAttributes'] if (email not in attr or attr[email]['VerificationStatus'] != 'Success'): logging.info('Verification email for {} sent. You must have all the emails verified before sending email.'.format(email)) ses.verify_email_identity(EmailAddress=email) return False return True # Check whether the phone holder has opted out of receiving SMS messages from your account def check_phone_number(phone_number): try: result = sns.check_if_phone_number_is_opted_out(phoneNumber=phone_number) if (result['isOptedOut']): logger.info('phoneNumber {} is not opt in of receiving SMS messages. Phone number must be opt in first.'.format(phone_number)) return False return True except Exception as e: logging.error('Your phone number {} must be in E.164 format in SSO. Exception thrown: {}'.format(phone_number, e)) return False def check_emails(emails): result = True for email in emails: if not check_email(email): result = False return result def lambda_handler(event, context): logging.info('Received event: ' + json.dumps(event)) nep = json.loads(event.get('notificationEventPayload')) alarm_state = nep['alarmState'] default_msg = 'Alarm ' + alarm_state['stateName'] + '\n' timestamp = datetime.datetime.utcfromtimestamp(float(nep['stateUpdateTime'])/1000).strftime('%Y-%m-%d %H:%M:%S') alarm_msg = "{} {} {} at {} UTC ".format(nep['alarmModelName'], nep.get('keyValue', 'Singleton'), alarm_state['stateName'], timestamp) default_msg += 'Sev: ' + str(nep['severity']) + '\n' if (alarm_state['ruleEvaluation']): property = alarm_state['ruleEvaluation']['simpleRule']['inputProperty'] default_msg += 'Current Value: ' + str(property) + '\n' operator = alarm_state['ruleEvaluation']['simpleRule']['operator'] threshold = alarm_state['ruleEvaluation']['simpleRule']['threshold'] alarm_msg += '({} {} {})'.format(str(property), operator, str(threshold)) default_msg += alarm_msg + '\n' emails = event.get('emailConfigurations', []) logger.info('Start Sending Emails') for email in emails: from_adr = email.get('from') to_adrs = email.get('to', []) cc_adrs = email.get('cc', []) bcc_adrs = email.get('bcc', []) msg = default_msg + '\n' + email.get('additionalMessage', '') subject = email.get('subject', alarm_msg) fa_ver = check_email(from_adr) tas_ver = check_emails(to_adrs) ccas_ver = check_emails(cc_adrs) bccas_ver = check_emails(bcc_adrs) if (fa_ver and tas_ver and ccas_ver and bccas_ver): ses.send_email(Source=from_adr, Destination={'ToAddresses': to_adrs, 'CcAddresses': cc_adrs, 'BccAddresses': bcc_adrs}, Message={'Subject': {'Data': subject}, 'Body': {'Text': {'Data': msg}}}) logger.info('Emails have been sent') logger.info('Start Sending SNS message to SMS') sns_configs = event.get('smsConfigurations', []) for sns_config in sns_configs: sns_msg = default_msg + '\n' + sns_config.get('additionalMessage', '') phone_numbers = sns_config.get('phoneNumbers', []) sender_id = sns_config.get('senderId') for phone_number in phone_numbers: if check_phone_number(phone_number): if check_value(sender_id): sns.publish(PhoneNumber=phone_number, Message=sns_msg, MessageAttributes={'AWS.SNS.SMS.SenderID':{'DataType': 'String','StringValue': sender_id}}) else: sns.publish(PhoneNumber=phone_number, Message=sns_msg) logger.info('SNS messages have been sent')