# Testing Events Archive and Replay with LocalStack & EventBridge

[EventBridge](https://aws.amazon.com/eventbridge/) allows you to manage events across different AWS services and applications. Event sources for EventBridge can include a vast array of AWS services that are natively integrated, third-party applications through integrations, or custom applications. Similarly, events can be directed to numerous AWS services or custom applications via API endpoints.

EventBridge buses, as per design, are transient carriers for events, making them a black box which event-driven systems often are. This makes it difficult to track what event came through and where it went. This can be partially mitigated by using archives, wherein you can configure a rule on your event bus to automatically save all incoming events to an archive. The replay feature then lets you replay all stored events on the event bus.

[LocalStack](https://localstack.cloud/) allows you to emulate and test this archive and replay workflow on your local machine. In this tutorial, you'll create a [Lambda function locally](https://docs.localstack.cloud/user-guide/aws/lambda/) using LocalStack & [AWS CLI](https://aws.amazon.com/cli/) to serve as the target for an EventBridge rule. You will then create an [archive](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-archive-event.html), and once events are stored in the archive, you will [replay](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-replay-archived-event.html) them.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722924693907/9622cf55-e0b6-40fc-9d72-c67c6435b748.png align="center")

## Prerequisites

* [LocalStack CLI](https://docs.localstack.cloud/getting-started/installation/#localstack-cli)
    
* [Docker](https://docs.docker.com/get-docker/)
    
* [AWS CLI](https://docs.aws.amazon.com/cli/v1/userguide/cli-chap-install.html) with [`awslocal` wrapper](https://docs.localstack.cloud/user-guide/integrations/aws-cli/#localstack-aws-cli-awslocal)
    
* [Node.js](https://nodejs.org/en/download/package-manager) & [`zip`](https://infozip.sourceforge.net/)
    
* [LocalStack Web Application](https://app.localstack.cloud/dashboard) account (optional)
    

## Start your LocalStack container

Launch the LocalStack container on your local machine using the specified command:

```bash
PROVIDER_OVERRIDE_EVENTS=v2 localstack start
```

The configuration variable `PROVIDER_OVERRIDE_EVENTS=v2` enables you to set the [EventBridge v2 provider](https://discuss.localstack.cloud/t/introducing-eventbridge-v2-in-localstack/946), which enhances emulation for EventBridge features like buses, rules, patterns, and targets, and supports archive & replay.

Once initiated, you'll receive a confirmation output indicating that the LocalStack container is up and running.

```bash

     __                     _______ __             __
    / /   ____  _________ _/ / ___// /_____ ______/ /__
   / /   / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
  / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
 /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|

 💻 LocalStack CLI 3.6.0
 👤 Profile: default

[20:19:34] starting LocalStack in    localstack.py:503
           Docker mode 🐳
...
LocalStack version: 3.6.1.dev20240725091954
LocalStack build date: 2024-07-26
LocalStack build git hash: d536652
```

## Create a Lambda Function

Since the event bus is transient, you need a target to verify what events pass through your system. You can create a Lambda function to log the events.

To begin, create a new file named `index.js`. Add the following code to log events:

```javascript
'use strict';

exports.handler = (event, context, callback) => {
    console.log('LogScheduledEvent');
    console.log('Received event:', JSON.stringify(event, null, 2));
    callback(null, 'Finished');
};
```

This code logs details of incoming events and concludes by sending a `Finished` message via the callback.

Next, package this file into a ZIP archive with the command:

```bash
zip function.zip index.js
```

Deploy the Lambda function using the following command:

```bash
awslocal lambda create-function \
    --function-name LogScheduledEvent \
    --runtime nodejs18.x \
    --role arn:aws:iam::000000000000:role/lambda-ex \
    --handler index.handler \
    --zip-file fileb://function.zip
```

The command outputs details about the function, including its name, pending state, and other configuration data:

```bash
{
    "FunctionName": "LogScheduledEvent",
    ...
    "State": "Pending",
    "StateReason": "The function is being created.",
    "StateReasonCode": "Creating",
    ...
    "EphemeralStorage": {
        "Size": 512
    },
    ...
    "RuntimeVersionConfig": {
        "RuntimeVersionArn": "arn:aws:lambda:us-east-1::runtime:8eeff65f6809a3ce81507fe733fe09b835899b99481ba22fd7
5b5a7338290ec1"
    }
}
```

## Create an EventBridge Archive

You can set up an EventBridge archive to store past events. This archive can hold events indefinitely or for a specified number of days. When configuring the archive, you can either capture all events from an event bus or selectively store only targeted events. Additionally, you can apply filters or rules to store events that meet specific criteria.

To start, create a custom event bus named `test-event-bus` to receive events, using this command:

```bash
awslocal events create-event-bus --name test-event-bus
```

The output would confirm the creation of the event bus:

```bash
{
    "EventBusArn": "arn:aws:events:us-east-1:000000000000:event-bus/test-event-bus"
}
```

## Create an EventBridge Rule

You can create a rule named `ARTestRule` to archive events that are sent to the event bus. EventBridge rules allow you to route specific events according to your needs. This rule filters events based on defined patterns and sends matching events to attached target services.

To create the rule, execute the following command:

```bash
awslocal events put-rule \
    --name ARTestRule \
    --event-bus-name test-event-bus \
    --event-pattern '{
      "detail-type": ["customerCreated"]
    }'
```

You should see the following output:

```bash
{
    "RuleArn": "arn:aws:events:us-east-1:000000000000:rule/test-event-bus/ARTestRule"
}
```

## Create an EventBridge Target

You can then choose a target. Targets are entities that consume your events. When an event triggers a rule, all targets linked to that rule are activated.

In this case, you can use the Lambda function as the target by retrieving the ARN of the Lambda function:

```bash
awslocal lambda get-function \
    --function-name LogScheduledEvent \
    --query 'Configuration.FunctionArn' \
    --output text
```

The Lambda ARN output will be:

```bash
arn:aws:lambda:us-east-1:000000000000:function:LogScheduledEvent
```

Finally, you can associate the Lambda function as a target to the `ARTestRule` using this command:

```bash
awslocal events put-targets \
    --rule ARTestRule \
    --event-bus-name test-event-bus \
    --targets '[
      {
        "Id": "1",
        "Arn": "arn:aws:lambda:us-east-1:000000000000:function:LogScheduledEvent"
      }
    ]'
```

You should see the following output:

```bash
{
    "FailedEntryCount": 0,
    "FailedEntries": []
}
```

## Create an EventBridge Archive

Next, establish an archive named `ArchiveTest` using the ARN from your event bus:

```bash
awslocal events create-archive \
    --archive-name ArchiveTest \
    --event-source-arn arn:aws:events:us-east-1:000000000000:event-bus/test-event-bus
```

The output would show the archive's ARN, its enabled state, and creation time:

```bash
{
    "ArchiveArn": "arn:aws:events:us-east-1:000000000000:archive/ArchiveTest",
    "State": "ENABLED",
    "CreationTime": "2024-08-03T19:03:00.917596+05:30"
}
```

## Send a test event

With the archive and rule configured, you can send a test event to verify that the system is functioning as expected. Execute the following command to send a test event:

```bash
awslocal events put-events --entries '[
  {
    "Source": "TestEvent",
    "DetailType": "customerCreated",
    "Detail": "{}",
    "EventBusName": "test-event-bus"
  }
]'
```

In this command:

* The event source is identified as `TestEvent`.
    
* The event is sent to the `test-event-bus`.
    
* The event detail is empty (`{}`) and the type is `customerCreated`.
    

The output should confirm successful event submission:

```bash
{
    "FailedEntryCount": 0,
    "Entries": [
        {
            "EventId": "ee947775-0dcd-405c-8ba9-e100dcf244fa"
        }
    ]
}
```

## Replay the event

Once test events are stored in the archive, you can replay them. To replay events, you need to specify both the source and the event bus they should be replayed into. Events must be replayed into the same event bus from which they were collected. You can also define a specific time window during which you want the events to be replayed into the bus.

Run the following command to start the replay:

```bash
awslocal events start-replay \
    --replay-name ReplayTest \
    --event-source-arn arn:aws:events:us-east-1:000000000000:archive/ArchiveTest \
    --event-start-time 2024-08-01 --event-end-time 2024-08-06 \
    --destination '{"Arn":"arn:aws:events:us-east-1:000000000000:event-bus/test-event-bus"}'
```

In the above command:

* The replay name is specified as `ReplayTest`.
    
* The event source ARN is the archive's ARN.
    
* The event start and end times are chosen based on the article's date but can be customized.
    
* The destination is the ARN for the `test-event-bus`.
    

The output should look like this:

```bash
{
    "ReplayArn": "arn:aws:events:us-east-1:000000000000:replay/ReplayTest",
    "State": "COMPLETED",
    "ReplayStartTime": "2024-08-06T12:58:01.405559+05:30"
}
```

To further inspect the replay details, use the command:

```bash
awslocal events describe-replay --replay-name ReplayTest
```

The description output will provide detailed information about the replay:

```bash
{
    "ReplayName": "ReplayTest",
    "ReplayArn": "arn:aws:events:us-east-1:000000000000:replay/ReplayTest",
    "State": "COMPLETED",
    "EventSourceArn": "arn:aws:events:us-east-1:000000000000:archive/ArchiveTest",
    "Destination": {
        "Arn": "arn:aws:events:us-east-1:000000000000:event-bus/test-event-bus"
    },
    ...
}
```

Replayed events will contain metadata to distinguish them from original events. You can check LocalStack logs for Lambda invocation details:

```bash
2024-08-06T07:29:24.039  INFO --- [et.reactor-1] localstack.request.aws     : AWS events.StartReplay => 200
2024-08-06T07:29:24.681  INFO --- [et.reactor-0] localstack.request.http    : POST /_localstack_lambda/58324d0bbf2060f95e80830df11f08a8/status/58324d0bbf2060f95e80830df11f08a8/ready => 202
2024-08-06T07:29:24.720  INFO --- [et.reactor-1] localstack.request.http    : POST /_localstack_lambda/58324d0bbf2060f95e80830df11f08a8/invocations/091a672b-a832-4824-a4cc-d56c75ed9893/logs => 202
2024-08-06T07:29:24.721  INFO --- [et.reactor-0] localstack.request.http    : POST /_localstack_lambda/58324d0bbf2060f95e80830df11f08a8/invocations/091a672b-a832-4824-a4cc-d56c75ed9893/response => 202
```

On the [CloudWatch Logs Resource Browser](https://app.localstack.cloud/inst/default/resources/cloudwatch/groups), you can inspect the `/aws/lambda/LogScheduledEvent` log to view the received event:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722929441259/612dadd0-9e8a-4567-a796-16e32575ac75.png align="center")

## Conclusion

With EventBridge Archive & Replay, you can capture and replay past events to troubleshoot issues or reprocess events through newly added functionalities without manually storing your events or setting up an additional infrastructure layer like [Dead Letter Queues (DLQ)](https://aws.amazon.com/what-is/dead-letter-queue/), which can be time-consuming depending on the event consumer. LocalStack lets you test these event-driven workflows locally, simplifying the development loop and reducing development costs.

LocalStack’s EventBridge emulation supports testing event transmission across different AWS regions and accounts, integration with various targets (such as [SNS](https://docs.localstack.cloud/user-guide/aws/sns/), [SQS](https://docs.localstack.cloud/user-guide/aws/sqs/), [Step Functions](https://docs.localstack.cloud/user-guide/aws/stepfunctions/)), and [Cloud Pods](https://docs.localstack.cloud/user-guide/state-management/cloud-pods/) for state sharing & collaboration. In upcoming blog posts, we will delve into some of these use cases, showcasing how LocalStack can make the black box of event-driven systems transparent for developers.
