---
title: Drift Setup — AWS
description: Enable event-driven compliance drift monitoring for AWS using EventBridge.
---

import { Aside } from '@astrojs/starlight/components';

## Architecture

```
AWS Config Configuration Item Change
  → EventBridge rule
    → API Destination
      → api.complyform.dev/v1/drift/event
```

AWS Config records resource configuration changes and emits them as EventBridge events. An EventBridge rule filters for compliance-relevant resource types and forwards matching events to the ComplyForm drift webhook via an API Destination.

## Prerequisites

- **ComplyForm Team+ tier** with an active project
- AWS account with an active <a href="https://docs.aws.amazon.com/config/latest/developerguide/stop-start-recorder.html" target="_blank" rel="noopener noreferrer">Config recorder</a>
- Terraform installed (v1.0+)

## Step 1: Enable Event-Driven Mode

```bash
complyform dashboard project drift enable \
  --mode=event-driven \
  --project-label=prod-aws
```

This command returns a webhook secret. Copy it — you will pass it to the Terraform module as `webhook_secret`.

## Step 2: Deploy the Event Pipeline

Save the following Terraform module and apply it to your AWS account.

```hcl title="complyform-drift-aws/main.tf"
variable "region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

variable "webhook_url" {
  description = "ComplyForm drift webhook endpoint"
  type        = string
  default     = "https://api.complyform.dev/v1/drift/event"
}

variable "webhook_secret" {
  description = "HMAC signing secret from ComplyForm setup"
  type        = string
  sensitive   = true
}

resource "aws_cloudwatch_event_rule" "complyform_drift" {
  name        = "complyform-drift-events"
  description = "Forward compliance-relevant Config changes to ComplyForm"

  event_pattern = jsonencode({
    source      = ["aws.config"]
    detail-type = ["Config Configuration Item Change"]
    detail = {
      messageType = ["ConfigurationItemChangeNotification"]
      configurationItem = {
        resourceType = [
          "AWS::EC2::Instance",
          "AWS::EC2::SecurityGroup",
          "AWS::EC2::VPC",
          "AWS::EC2::Subnet",
          "AWS::S3::Bucket",
          "AWS::RDS::DBInstance",
          "AWS::IAM::Role",
          "AWS::IAM::Policy",
          "AWS::KMS::Key",
          "AWS::EKS::Cluster",
          "AWS::CloudTrail::Trail",
        ]
      }
    }
  })
}

resource "aws_cloudwatch_event_api_destination" "complyform" {
  name                             = "complyform-drift"
  invocation_endpoint              = var.webhook_url
  http_method                      = "POST"
  invocation_rate_limit_per_second = 10
  connection_arn                   = aws_cloudwatch_event_connection.complyform.arn
}

resource "aws_cloudwatch_event_connection" "complyform" {
  name               = "complyform-drift"
  authorization_type = "API_KEY"

  auth_parameters {
    api_key {
      key   = "X-Drift-Secret"
      value = var.webhook_secret
    }
  }
}

resource "aws_cloudwatch_event_target" "complyform" {
  rule      = aws_cloudwatch_event_rule.complyform_drift.name
  target_id = "complyform-drift"
  arn       = aws_cloudwatch_event_api_destination.complyform.arn
  role_arn  = aws_iam_role.complyform_eventbridge.arn
}

resource "aws_iam_role" "complyform_eventbridge" {
  name = "complyform-drift-eventbridge"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "events.amazonaws.com"
      }
    }]
  })
}

resource "aws_iam_role_policy" "complyform_eventbridge" {
  name = "complyform-drift-invoke"
  role = aws_iam_role.complyform_eventbridge.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action   = "events:InvokeApiDestination"
      Effect   = "Allow"
      Resource = aws_cloudwatch_event_api_destination.complyform.arn
    }]
  })
}
```

## Step 3: Apply

```bash
cd complyform-drift-aws
terraform init
terraform apply -var="webhook_secret=YOUR_SECRET"
```

After `apply` completes, verify the pipeline is active:

```bash
complyform dashboard project drift status --project-label=prod-aws
```

<Aside type="note">
AWS Config must have an active recorder in the target region. If Config is not enabled, EventBridge will not receive configuration change events. You can verify recorder status with `aws configservice describe-configuration-recorders`.
</Aside>

<Aside type="tip">
EventBridge event propagation is typically seconds to minutes after the resource change.
</Aside>

## Next Steps

- [Drift Setup Overview](../) — monitoring modes and alert configuration
- [Drift Monitoring Guide](../../guides/drift-monitoring/) — dashboards, alert tuning, and triage workflows
