

# Using Amazon EventBridge
<a name="cloudwatch-events"></a>

You can use [Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/) (formerly CloudWatch Events) to automate your AWS services and respond automatically to system events such as application availability issues or resource changes. Events from AWS services, including ACM, are delivered to Amazon EventBridge in near-real time. You can use events to trigger targets including AWS Lambda functions, AWS Batch jobs, Amazon SNS topics, and many others. For more information, see [What Is Amazon EventBridge?](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html)

**Topics**
+ [Amazon EventBridge support for ACM](supported-events.md)
+ [Initiating actions with Amazon EventBridge in ACM](example-actions.md)

# Amazon EventBridge support for ACM
<a name="supported-events"></a>

This topic lists and describes the ACM related events supported by Amazon EventBridge.

## ACM Certificate Approaching Expiration event
<a name="expiration-approaching-event"></a>

ACM sends daily expiration events for all active certificates (public, private and imported) starting 45 days prior to expiration for private/imported certificates and 30 days prior to expiration for public certificates. This timing can be changed using the [PutAccountConfiguration](https://docs.aws.amazon.com/acm/latest/APIReference/API_PutAccountConfiguration.html) action of the ACM API.

ACM automatically initiates renewal of eligible certificates that it issued, but imported certificates need to be reissued and reimported prior to expiration to avoid outages. For more information, see [Reimporting a certificate](https://docs.aws.amazon.com/acm/latest/userguide/import-reimport.html#reimport-certificate-api). You can use expiration events to set up automation to reimport certificates into ACM. For an example of automation using AWS Lambda, see [Initiating actions with Amazon EventBridge in ACM](example-actions.md).

*ACM Certificate Approaching Expiration* events have the following structure.

```
{
  "version": "0",
  "id": "id",
  "detail-type": "ACM Certificate Approaching Expiration",
  "source": "aws.acm",
  "account": "account",
  "time": "2020-09-30T06:51:08Z",
  "region": "region",
  "resources": [
    "arn:aws:acm:region:account:certificate/certificate_ID"
  ],
  "detail": {
    "DaysToExpiry": 31,
    "CommonName": "example.com"
  }
}
```

## ACM Certificate Expired event
<a name="expired-event"></a>

**Note**  
Certificate Expired events aren't available for [imported certificates](import-certificate.md).

Customers can listen on this event to alert them if an ACM issued public or private certificate in their account expires.

*ACM Certificate Expired* events have the following structure.

```
{
    "version": "0",
    "id": "id", 
    "detail-type": "ACM Certificate Expired",
    "source": "aws.acm",
    "account": "account",
    "time": "2019-12-22T18:43:48Z",
    "region": "region",
    "resources": [
        "arn:aws:acm:region:account:certificate/certificate_ID"
     ],
     "detail": {   
        "CertificateType" : "AMAZON_ISSUED" | "PRIVATE",    
        "CommonName": "example.com",     
        "DomainValidationMethod" : "EMAIL" | "DNS",    
        "CertificateCreatedDate" : "2018-12-22T18:43:48Z",
        "CertificateExpirationDate" : "2019-12-22T18:43:48Z",
        "InUse" : TRUE | FALSE,    
        "Exported" : TRUE | FALSE
    }
 }
```

## ACM Certificate Available event
<a name="available-event"></a>

Customers can listen on this event to be notified when a managed public or private certificate is ready for use. The event is published on issuance, renewal, and import. For a private certificate, once it becomes available, customer action is still required to deploy it to hosts. 

*ACM Certificate Available* events have the following structure.

```
{
    "version": "0",
    "id": "id", 
    "detail-type": "ACM Certificate Available",
    "source": "aws.acm",
    "account": "account",
    "time": "2019-12-22T18:43:48Z",
    "region": "region",
    "resources": [
        "arn:aws:acm:region:account:certificate/certificate_ID"
    ],
    "detail": {
       “Action” : "ISSUANCE" | "RENEWAL" | "IMPORT" | "REIMPORT",
       "CertificateType" : "AMAZON_ISSUED" | "PRIVATE" | "IMPORTED",    
       "CommonName": "example.com",     
       "DomainValidationMethod" : "EMAIL" | "DNS",    
       "CertificateCreatedDate" : "2019-12-22T18:43:48Z",
       "CertificateExpirationDate" : "2019-12-22T18:43:48Z",
       "DaysToExpiry" : 198,
       "InUse" : TRUE | FALSE,    
       "Exported" : TRUE | FALSE     
     }
}
```

## ACM Certificate Renewal Action Required event
<a name="renewal-required-event"></a>

**Note**  
Certificate Renewal Action Required events aren't available for [imported certificates](import-certificate.md).

Customers can listen on this event to be alerted when a customer action must be taken before a certificate can be renewed. For instance, if a customer adds CAA records that prevent ACM from renewing a certificate, ACM publishes this event when automatic renewal fails at 45 days before expiration for private certificates and 30 days before expiration for public certificates. If no customer action is taken, ACM makes further renewal attempts at 30 days (for private only), 15 days, 3 days, and 1 day, or until customer action is taken, the certificate expires, or the certificate is no longer eligible for renewal. An event is published for each of these renewal attempts.

*ACM Certificate Renewal Action Required* events have the following structure.

```
{
   "version": "0",
   "id": "id", 
   "detail-type": "ACM Certificate Renewal Action Required",
   "source": "aws.acm",
   "account": "account",
   "time": "2019-12-22T18:43:48Z",
   "region": "region",
   "resources": [
       "arn:aws:acm:region:account:certificate/certificate_ID"
    ],
    "detail": {   
       "CertificateType" : "AMAZON_ISSUED" | "PRIVATE",   
       "CommonName": "example.com",    
       "DomainValidationMethod" : "EMAIL" | "DNS",   
       "RenewalStatusReason" : "CAA_ERROR" | "PENDING_DOMAIN_VALIDATION" | "NO_AVAILABLE_CONTACTS" | "ADDITIONAL_VERIFICATION_REQUIRED" | "DOMAIN_NOT_ALLOWED" | "INVALID_PUBLIC_DOMAIN" | "DOMAIN_VALIDATION_DENIED" | "PCA_LIMIT_EXCEEDED" | "PCA_INVALID_ARN" | "PCA_INVALID_STATE" | "PCA_REQUEST_FAILED" | "PCA_NAME_CONSTRAINTS_VALIDATION" | "PCA_RESOURCE_NOT_FOUND" | "PCA_INVALID_ARGS" | "PCA_INVALID_DURATION" | "PCA_ACCESS_DENIED" | "SLR_NOT_FOUND" | "OTHER",
       "DaysToExpiry": 30, 
       "CertificateExpirationDate" : "2019-12-22T18:43:48Z",
       "InUse" : TRUE | FALSE,        
       "Exported" : TRUE | FALSE
   }
}
```

## ACM Certificate Revoked event
<a name="revoked-event"></a>

Customers can listen on this event to alert them if an ACM issued public or private certificate in their account is revoked.

**Note**  
Only exported certificates can be revoked. Imported certificates cannot be revoked via revoke-certificate. 

*ACM Certificate Revoked* events have the following structure.

```
{
  "version": "0",
  "id": "id",
  "detail-type": "ACM Certificate Revoked",
  "source": "aws.acm",
  "account": "account",
  "time": "2019-12-22T18:43:48Z",
  "region": "region",
 "resources": [
        "arn:aws:acm:region:account:certificate/certificate_ID"
     ],
  "detail": {
    "CertificateType" : "AMAZON_ISSUED" | "PRIVATE", 
    "CommonName": "example.com",
    "CertificateExpirationDate" : "2019-12-22T18:43:48Z",
    "Exportable": TRUE | FALSE
  }
}
```

## AWS health events
<a name="health-event"></a>

AWS health events are generated for ACM certificates that are eligible for renewal. For information about renewal eligibility, see [Managed certificate renewal in AWS Certificate Manager](managed-renewal.md).

Health events are generated in two scenarios:
+ On successful renewal of a public or private certificate.
+ When a customer must take action for a renewal to occur. This may mean choosing a link in an email message (for email-validated certificates), or resolving an error. One of the following event codes is included with each event. The codes are exposed as variables that you can use for filtering.
  + `AWS_ACM_RENEWAL_STATE_CHANGE` (the certificate has been renewed, has expired, or is due to expire)
  + `CAA_CHECK_FAILURE` (CAA check failed)
  + `AWS_ACM_RENEWAL_FAILURE` (for certificates signed by a private CA)

Health events have the following structure. In this example, an `AWS_ACM_RENEWAL_STATE_CHANGE` event has been generated.

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

# Initiating actions with Amazon EventBridge in ACM
<a name="example-actions"></a>

You can create Amazon EventBridge rules based on these events and use the Amazon EventBridge console to configure actions that take place when the events are detected. This section provides sample procedures for configuring Amazon EventBridge rules and resulting actions.

**Topics**
+ [Responding to an event with Amazon SNS](event-sns-response.md)
+ [Responding to an event with a Lambda function](event-lambda-response.md)

# Responding to an event with Amazon SNS
<a name="event-sns-response"></a>

This section shows how to configure Amazon SNS to send a text notification whenever ACM generates a health event.

Complete the following procedure to configure a response.

**To create a Amazon EventBridge rule and trigger an action**

1. Create an Amazon EventBridge rule. For more information, see [Creating Amazon EventBridge rules that react to events](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule.html).

   1. In the Amazon EventBridge console at [https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/), navigate to the **Events** > **Rules** page and choose **Create rule**. 

   1. On the **Create rule** page, select **Event Pattern**.

   1. For **Service Name**, choose **Health** from the menu.

   1. For **Event Type**, choose **Specific Health events**.

   1. Select **Specific service(s)** and choose **ACM** from the menu.

   1. Select **Specific event type category(s)** and choose **accountNotification**.

   1. Choose **Any event type code**.

   1. Choose **Any resource**.

   1. In the **Event pattern preview** editor, paste the JSON pattern emitted by the event. This example uses the pattern from the [AWS health events](supported-events.md#health-event) section.

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

1. Configure an action.

   In the **Targets** section, you can choose from among many services that can immediately consume your event, such as Amazon Simple Notification Service (SNS), or you can choose **Lambda function** to pass the event to customized executable code. For an example of an AWS Lambda implementation, see [Responding to an event with a Lambda function](event-lambda-response.md).

# Responding to an event with a Lambda function
<a name="event-lambda-response"></a>

This procedure demonstrates how to use AWS Lambda to listen on Amazon EventBridge, create notifications with Amazon Simple Notification Service (SNS), and publish findings to AWS Security Hub CSPM, providing visibility to administrators and security teams. <a name="lambda-setup"></a>

**To set up a Lambda function and IAM role**

1. First configure an AWS Identity and Access Management (IAM) role and define the permissions needed by the Lambda function. This security best practice gives you flexibility in designating who has authorization to call the function, and in limiting the permissions granted to that person. It is not recommended to run most AWS operations directly under a user account and especially not under an administrator account.

   Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. Use the JSON policy editor to create the policy defined in the template below. Provide your own Region and AWS account details. For more information, see [Creating policies on the JSON tab](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. Create an IAM role and attach the new policy to it. For information about creating an IAM role and attaching a policy, see [Creating a role for an AWS service (console)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html#roles-creatingrole-service-console). 

1. Open the AWS Lambda console at [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Create the Lambda function. For more information, see [Create a Lambda function with the console](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html). Complete the following steps:

   1. On the **Create function** page, choose the **Author from scratch** option to create the function.

   1. Specify a name such as "handle-expiring-certificates" in the **Function name** field.

   1. Choose Python 3.8 from the **Runtime** list.

   1. Expand **Change default execution role** and choose **Use an existing role**.

   1. Choose the role you previously created from the **Existing role** list.

   1. Choose **Create function**.

   1. Under **Function code**, insert the following code:

      ```
      # 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. Under **Environment variables**, choose **Edit** and optionally add the following variables.
      + (Optional) EXPIRY\$1DAYS

        Specifies how much lead time, in days, before the certificate expiration notice is sent. The function defaults to 45 days, but you can specify custom values.
      + (Optional) SNS\$1TOPIC\$1ARN

        Specifies an ARN for an Amazon SNS. Provide the full ARN in the format of arn:aws:sns:*<region>*:*<account-number>*:*<topic-name>*.
      + (Optional) SECURITY\$1HUB\$1REGION

        Specifies an AWS Security Hub CSPM in a different Region. If this is not specified, the Region of the running Lambda function is used. If the function is run in multiple Regions, it may be desirable to have all certificate messages go to Security Hub CSPM in a single Region. 

   1. Under **Basic settings**, set **Timeout** to 30 seconds.

   1. At the top of the page, choose **Deploy**.

Complete the tasks in the following procedure to begin using this solution.

**To automate an email notice of expiration**

In this example, we provide a single email for each expiring certificate at the moment the event is raised through Amazon EventBridge. By default, ACM raises an event each day for a certificate that is 45 days or less from expiration. (This period can be customized using the [PutAccountConfiguration](https://docs.aws.amazon.com/acm/latest/APIReference/API_PutAccountConfiguration.html) operation of the ACM API.) Each of these events triggers the following cascade of automated actions:

```
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. Create the Lambda function and configure permissions. (Already completed – see [To set up a Lambda function and IAM role](#lambda-setup)).

1. Create a *standard* SNS topic for the Lambda function to use to send out notifications. For more information, see [Creating an Amazon SNS topic](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html).

1. Subscribe any interested parties to the new SNS topic. For more information, see [Subscribing to an Amazon SNS topic](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html).

1. Create an Amazon EventBridge rule to trigger the Lambda function. For more information, see [Creating Amazon EventBridge rules that react to events](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule.html).

   In the Amazon EventBridge console at [https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/), navigate to the **Events** > **Rules** page and choose **Create rule**. Specify **Service Name**, **Event Type**, and **Lambda function**. In the **Event Pattern preview** editor, paste the following code:

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

   An event such as Lambda receives is displayed under **Show sample event(s)**:

   ```
   {
     "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"
     }
   }
   ```

**To clean up**

Once you no longer need the example configuration, or any configuration, it is a best practice to remove all traces of it to avoid security problems and unexpected future charges:
+ IAM policy and role
+ Lambda function
+ CloudWatch Events rule
+ CloudWatch Logs associated with Lambda
+ SNS Topic