

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.

# Initiation d'actions avec Amazon EventBridge dans ACM
<a name="example-actions"></a>

Vous pouvez créer des EventBridge règles Amazon basées sur ces événements et utiliser la EventBridge console Amazon pour configurer les actions qui ont lieu lorsque les événements sont détectés. Cette section fournit des exemples de procédures pour configurer les EventBridge règles Amazon et les actions qui en résultent.

**Topics**
+ [Répondre à un événement avec Amazon SNS](event-sns-response.md)
+ [Répondre à un événement avec une fonction Lambda](event-lambda-response.md)

# Répondre à un événement avec Amazon SNS
<a name="event-sns-response"></a>

Cette section explique comment configurer Amazon SNS pour envoyer une notification écrite lorsqu'ACM génère un événement d'état.

Suivez la procédure ci-dessous pour configurer une réponse.

**Pour créer une EventBridge règle Amazon et déclencher une action**

1. Créez une EventBridge règle Amazon. Pour plus d'informations, consultez [la section Création de EventBridge règles Amazon qui réagissent aux événements](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule.html).

   1. Dans la EventBridge console Amazon à l'[https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/)adresse, accédez à la page **Événements** > **Règles** et choisissez **Create rule**. 

   1. Sur la page **Créer une règle**, sélectionnez **Modèle d'événement**.

   1. Dans le champ **Nom du service**, choisissez **État** à partir du menu.

   1. Dans le champ **Type d'événement**, choisissez **Événements d'état spécifiques**.

   1. Sélectionnez **Service(s) spécifique(s)** et choisissez **ACM** à partir du menu.

   1. Sélectionnez **Catégorie(s) de type d'événement spécifique(s)** et choisissez**accountNotification**.

   1. Choisissez **N'importe quel code de type d'événement**.

   1. Choisissez **N'importe quel type de ressource**.

   1. Dans l'éditeur **Aperçu du modèle d'événement**, collez le modèle JSON émis par l'événement. Cet exemple utilise le modèle de la section [AWS événements liés à la santé](supported-events.md#health-event).

   ```
   {
      "source":[
         "aws.health"
      ],
      "detail-type":[
         "AWS Health Event"
      ],
      "detail":{
         "service":[
            "ACM"
         ],
         "eventTypeCategory":[
            "scheduledChange"
         ],
         "eventTypeCode":[
            "AWS_ACM_RENEWAL_STATE_CHANGE"
         ]
      }
   }
   ```

1. Configurez une action.

   Dans la section **Cibles**, vous pouvez effectuer un choix parmi de nombreux services susceptibles d'utiliser immédiatement votre événement, comme Amazon Simple Notification Service (SNS), ou vous pouvez choisir **Fonction Lambda** pour transmettre l'événement à un code exécutable personnalisé. Pour obtenir un exemple d'implémentation de AWS Lambda , consultez [Répondre à un événement avec une fonction Lambda](event-lambda-response.md).

# Répondre à un événement avec une fonction Lambda
<a name="event-lambda-response"></a>

Cette procédure explique comment AWS Lambda écouter sur Amazon EventBridge, créer des notifications avec Amazon Simple Notification Service (SNS) et publier des résultats sur Amazon AWS Security Hub CSPM, offrant ainsi une visibilité aux administrateurs et aux équipes de sécurité. <a name="lambda-setup"></a>

**Pour configurer une fonction Lambda et un rôle IAM**

1. Configurez d'abord un rôle Gestion des identités et des accès AWS (IAM) et définissez les autorisations requises par la fonction Lambda. Cette bonne pratique en matière de sécurité vous offre une certaine souplesse pour désigner la personne autorisée à appeler la fonction, et pour limiter les autorisations accordées à cette personne. Il n'est pas recommandé d'exécuter la plupart AWS des opérations directement sous un compte utilisateur et surtout pas sous un compte administrateur.

   Ouvrez la console IAM à l’adresse [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. Utilisez l'éditeur de stratégie JSON pour créer la stratégie définie dans le modèle ci-dessous. Indiquez votre région et les détails de votre AWS compte. Pour plus d'informations, consultez [Création de stratégies sous l'onglet JSON](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html#access_policies_create-json-editor).

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "LambdaCertificateExpiryPolicy1",
               "Effect": "Allow",
               "Action": "logs:CreateLogGroup",
               "Resource": "arn:aws:logs:us-east-1:123456789012:*"
           },
           {
               "Sid": "LambdaCertificateExpiryPolicy2",
               "Effect": "Allow",
               "Action": [
                   "logs:CreateLogStream",
                   "logs:PutLogEvents"
               ],
               "Resource": [
                   "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/handle-expiring-certificates:*"
               ]
           },
           {
               "Sid": "LambdaCertificateExpiryPolicy3",
               "Effect": "Allow",
               "Action": [
                   "acm:DescribeCertificate",
                   "acm:GetCertificate",
                   "acm:ListCertificates",
                   "acm:ListTagsForCertificate"
               ],
               "Resource": "*"
           },
           {
               "Sid": "LambdaCertificateExpiryPolicy4",
               "Effect": "Allow",
               "Action": "SNS:Publish",
               "Resource": "*"
           },
           {
               "Sid": "LambdaCertificateExpiryPolicy5",
               "Effect": "Allow",
               "Action": [
                   "SecurityHub:BatchImportFindings",
                   "SecurityHub:BatchUpdateFindings",
                   "SecurityHub:DescribeHub"
               ],
               "Resource": "*"
           },
           {
               "Sid": "LambdaCertificateExpiryPolicy6",
               "Effect": "Allow",
               "Action": "cloudwatch:ListMetrics",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. Créez un rôle IAM et attachez la nouvelle stratégie à celui-ci. Pour plus d'informations sur la création d'un rôle IAM et l'attachement d'une politique, consultez la section [Création d'un rôle pour un AWS service (console)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html#roles-creatingrole-service-console). 

1. Ouvrez la AWS Lambda console à l'adresse [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Créez la fonction Lambda. Pour plus d'informations, consultez [Créer une fonction Lambda à l'aide de la console](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html). Procédez comme suit :

   1. Sur la page **Créer une fonction**, choisissez l'option **Créer de bout en bout** afin de créer la fonction.

   1. Spécifiez un nom tel que « handle-expiring-certificates » dans le champ **Nom de la fonction**.

   1. Dans la liste **Environnement d'exécution**, choisissez Python 3.8.

   1. Développez **Modifier le rôle d'exécution par défaut** et choisissez **Utiliser un rôle existant**.

   1. Dans la liste **Rôle existant**, choisissez le rôle que vous avez précédemment créé.

   1. Choisissez **Créer une fonction**.

   1. Sous **Code de fonction**, insérez le code suivant :

      ```
      # Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
      # SPDX-License-Identifier: MIT-0
      #
      # Permission is hereby granted, free of charge, to any person obtaining a copy of this
      # software and associated documentation files (the "Software"), to deal in the Software
      # without restriction, including without limitation the rights to use, copy, modify,
      # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
      # permit persons to whom the Software is furnished to do so.
      #
      # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
      # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
      # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
      # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      
      import json
      import boto3
      import os
      from datetime import datetime, timedelta, timezone
      # -------------------------------------------
      # setup global data
      # -------------------------------------------
      utc = timezone.utc
      # make today timezone aware
      today = datetime.now().replace(tzinfo=utc)
      # set up time window for alert - default to 45 if its missing
      if os.environ.get('EXPIRY_DAYS') is None:
          expiry_days = 45
      else:
          expiry_days = int(os.environ['EXPIRY_DAYS'])
      expiry_window = today + timedelta(days = expiry_days)
      def lambda_handler(event, context):
          # if this is coming from the ACM event, its for a single certificate
          if (event['detail-type'] == "ACM Certificate Approaching Expiration"):
              response = handle_single_cert(event, context.invoked_function_arn)
          return {
              'statusCode': 200,
              'body': response 
          }
      def handle_single_cert(event, context_arn):
          cert_client = boto3.client('acm')
          cert_details = cert_client.describe_certificate(CertificateArn=event['resources'][0])
          result = 'The following certificate is expiring within ' + str(expiry_days) + ' days: ' + cert_details['Certificate']['DomainName']
          # check the expiry window before logging to Security Hub and sending an SNS
          if cert_details['Certificate']['NotAfter'] < expiry_window:
              # This call is the text going into the SNS notification
              result = result + ' (' + cert_details['Certificate']['CertificateArn'] + ') '
              # this call is publishing to SH
              result = result + ' - ' + log_finding_to_sh(event, cert_details, context_arn)
              # if there's an SNS topic, publish a notification to it
              if os.environ.get('SNS_TOPIC_ARN') is None:
                  response = result
              else:
                  sns_client = boto3.client('sns')
                  response = sns_client.publish(TopicArn=os.environ['SNS_TOPIC_ARN'], Message=result, Subject='Certificate Expiration Notification')
          return result
      def log_finding_to_sh(event, cert_details, context_arn):
          # setup for security hub
          sh_region = get_sh_region(event['region'])
          sh_hub_arn = "arn:aws:securityhub:{0}:{1}:hub/default".format(sh_region, event['account'])
          sh_product_arn = "arn:aws:securityhub:{0}:{1}:product/{1}/default".format(sh_region, event['account'])
          # check if security hub is enabled, and if the hub arn exists
          sh_client = boto3.client('securityhub', region_name = sh_region)
          try:
              sh_enabled = sh_client.describe_hub(HubArn = sh_hub_arn)
          # the previous command throws an error indicating the hub doesn't exist or lambda doesn't have rights to it so we'll stop attempting to use it
          except Exception as error:
              sh_enabled = None
              print ('Default Security Hub product doesn\'t exist')
              response = 'Security Hub disabled'
          # This is used to generate the URL to the cert in the Security Hub Findings to link directly to it
          cert_id = right(cert_details['Certificate']['CertificateArn'], 36)
          if sh_enabled:
              # set up a new findings list
              new_findings = []
                  # add expiring certificate to the new findings list
              new_findings.append({
                  "SchemaVersion": "2018-10-08",
                  "Id": cert_id,
                  "ProductArn": sh_product_arn,
                  "GeneratorId": context_arn,
                  "AwsAccountId": event['account'],
                  "Types": [
                      "Software and Configuration Checks/AWS Config Analysis"
                  ],
                  "CreatedAt": event['time'],
                  "UpdatedAt": event['time'],
                  "Severity": {
                      "Original": '89.0',
                      "Label": 'HIGH'
                  },
                  "Title": 'Certificate expiration',
                  "Description": 'cert expiry',
                  'Remediation': {
                      'Recommendation': {
                          'Text': 'A new certificate for ' + cert_details['Certificate']['DomainName'] + ' should be imported to replace the existing imported certificate before expiration',
                          'Url': "https://console.aws.amazon.com/acm/home?region=" + event['region'] + "#/?id=" + cert_id
                      }
                  },
                  'Resources': [
                      {
                          'Id': event['id'],
                          'Type': 'ACM Certificate',
                          'Partition': 'aws',
                          'Region': event['region']
                      }
                  ],
                  'Compliance': {'Status': 'WARNING'}
              })
              # push any new findings to security hub
              if new_findings:
                  try:
                      response = sh_client.batch_import_findings(Findings=new_findings)
                      if response['FailedCount'] > 0:
                          print("Failed to import {} findings".format(response['FailedCount']))
                  except Exception as error:
                      print("Error: ", error)
                      raise
          return json.dumps(response)
      # function to setup the sh region    
      def get_sh_region(event_region):
          # security hub findings may need to go to a different region so set that here
          if os.environ.get('SECURITY_HUB_REGION') is None:
              sh_region_local = event_region
          else:
              sh_region_local = os.environ['SECURITY_HUB_REGION']
          return sh_region_local
      # quick function to trim off right side of a string
      def right(value, count):
          # To get right part of string, use negative first index in slice.
          return value[-count:]
      ```

   1. Sous **Variables d'environnement**, choisissez **Modifier** et ajoutez éventuellement les variables suivantes.
      + (Facultatif) EXPIRY\$1DAYS

        Indique le délai, en jours, avant l'envoi de l'avis d'expiration du certificat. La fonction est définie par défaut sur 45 jours, mais vous pouvez spécifier des valeurs personnalisées.
      + (Facultatif) SNS\$1TOPIC\$1ARN

        Indique un ARN pour un service Amazon SNS. Fournissez l'ARN complet au format arn:aws:sns : : :. *<region>* *<account-number>* *<topic-name>*
      + (Facultatif) SECURITY\$1HUB\$1REGION

        Spécifie un AWS Security Hub CSPM dans une autre région. Si cela n'est pas indiqué, la région de la fonction Lambda en cours d'exécution est utilisée. Si la fonction est exécutée dans plusieurs régions, il peut être souhaitable que tous les messages de certificat soient envoyés au Security Hub CSPM d'une seule région. 

   1. Sous **Paramètres de base**, définissez **Expiration** sur 30 secondes.

   1. En haut de la page, choisissez **Déployer**.

Effectuez les tâches de la procédure suivante pour commencer à utiliser cette solution.

**Pour automatiser l'envoi d'un avis d'expiration par e-mail**

Dans cet exemple, nous fournissons un e-mail unique pour chaque certificat expirant au moment où l'événement est déclenché via Amazon EventBridge. Par défaut, ACM déclenche un événement par jour au cours des 45 jours qui précèdent l'expiration d'un certificat. (Cette période peut être personnalisée à l'aide de l'opération [PutAccountConfiguration](https://docs.aws.amazon.com/acm/latest/APIReference/API_PutAccountConfiguration.html) de l'API ACM). Chacun de ces événements déclenche la cascade d'actions automatisées suivante :

```
ACM raises Amazon EventBridge event → 
>>>>>>> events

          Event matches Amazon EventBridge rule → 

                    Rule calls Lambda function → 

                              Function sends SNS email and logs a Finding in Security Hub CSPM
```

1. Créez la fonction Lambda et configurez les autorisations. (Déjà terminé – voir [Pour configurer une fonction Lambda et un rôle IAM](#lambda-setup)).

1. Créez une rubrique SNS *standard* à utiliser par la fonction Lambda pour envoyer des notifications. Pour plus d'informations, consultez [Création d'une rubrique Amazon SNS](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html).

1. Abonnez toutes les parties intéressées à la nouvelle rubrique SNS. Pour plus d'informations, consultez [Abonnement à une rubrique Amazon SNS](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html).

1. Créez une EventBridge règle Amazon pour déclencher la fonction Lambda. Pour plus d'informations, consultez [la section Création de EventBridge règles Amazon qui réagissent aux événements](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule.html).

   Dans la EventBridge console Amazon à l'[https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/)adresse, accédez à la page **Événements** > **Règles** et choisissez **Create rule**. Complétez les champs **Nom du service**, **Type d'événement** et **Fonction Lambda**. Dans l'éditeur **Aperçu du modèle d'événement**, collez le code suivant :

   ```
   {
     "source": [
       "aws.acm"
     ],
     "detail-type": [
       "ACM Certificate Approaching Expiration"
     ]
   }
   ```

   Un événement tel que Lambda reçoit apparaît sous **Afficher les exemples d'événements** :

   ```
   {
     "version": "0",
     "id": "9c95e8e4-96a4-ef3f-b739-b6aa5b193afb",
     "detail-type": "ACM Certificate Approaching Expiration",
     "source": "aws.acm",
     "account": "123456789012",
     "time": "2020-09-30T06:51:08Z",
     "region": "us-east-1",
     "resources": [
       "arn:aws:acm:us-east-1:123456789012:certificate/61f50cd4-45b9-4259-b049-d0a53682fa4b"
     ],
     "detail": {
       "DaysToExpiry": 31,
       "CommonName": "My Awesome Service"
     }
   }
   ```

**Pour nettoyer**

Une fois que vous n'avez plus besoin de l'exemple de configuration, ou de toute autre configuration, il est préférable d'en supprimer toute trace pour éviter les problèmes de sécurité et les frais imprévus :
+ Politique IAM et rôle
+ Fonction Lambda
+ CloudWatch Règle des événements
+ CloudWatch Logs associés à Lambda
+ Rubrique SNS