Skip to content

EC2 (Elastic Compute Cloud) — Drift Coverage

Overview

TFDrift-Falco monitors Amazon EC2 for configuration drift by tracking CloudTrail events related to instances, AMIs, EBS volumes, snapshots, and network interfaces. This enables real-time detection of manual changes made outside of Terraform workflows.

Supported CloudTrail Events

Instance Management (5 events)

Event Description Priority Status
RunInstances EC2 instance created CRITICAL
TerminateInstances EC2 instance terminated CRITICAL
StartInstances EC2 instance started WARNING
StopInstances EC2 instance stopped WARNING
ModifyInstanceAttribute Instance attribute modified WARNING

AMI Management (2 events)

Event Description Priority Status
CreateImage AMI created from instance WARNING
DeregisterImage AMI deregistered WARNING

EBS Volume Management (5 events)

Event Description Priority Status
CreateVolume EBS volume created WARNING
DeleteVolume EBS volume deleted WARNING
AttachVolume Volume attached to instance WARNING
DetachVolume Volume detached from instance WARNING
ModifyVolume Volume configuration modified WARNING

Snapshot Management (2 events)

Event Description Priority Status
CreateSnapshot EBS snapshot created WARNING
DeleteSnapshot EBS snapshot deleted WARNING

Network Interface Management (3 events)

Event Description Priority Status
CreateNetworkInterface Network interface (ENI) created WARNING
DeleteNetworkInterface Network interface deleted WARNING
AttachNetworkInterface Network interface attached WARNING

Total: 17 CloudTrail events

Supported Terraform Resources

  • aws_instance — EC2 instance configuration
  • aws_ami — Amazon Machine Images
  • aws_ebs_volume — EBS volume configuration
  • aws_volume_attachment — EBS volume attachments
  • aws_ebs_snapshot — EBS snapshots
  • aws_network_interface — Elastic Network Interfaces (ENI)
  • aws_network_interface_attachment — ENI attachments

Monitored Drift Attributes

EC2 Instances

  • instance_type — Instance size (t3.micro, m5.large, etc.)
  • ami — Amazon Machine Image ID
  • availability_zone — AZ placement
  • subnet_id — VPC subnet
  • vpc_security_group_ids — Security groups
  • iam_instance_profile — IAM role
  • user_data — Initialization script
  • monitoring — Detailed CloudWatch monitoring
  • ebs_optimized — EBS optimization flag
  • root_block_device — Root volume configuration
  • ebs_block_device — Additional EBS volumes
  • network_interface — Network interface configuration
  • tags — Resource tags

AMIs

  • name — AMI name
  • description — AMI description
  • virtualization_type — HVM or paravirtual
  • root_device_name — Root device identifier
  • ebs_block_device — EBS snapshot mappings
  • tags — Resource tags

EBS Volumes

  • availability_zone — AZ placement
  • size — Volume size (GB)
  • type — Volume type (gp3, io2, st1, sc1)
  • iops — Provisioned IOPS
  • throughput — Throughput (MB/s) for gp3
  • encrypted — Encryption status
  • kms_key_id — KMS key for encryption
  • snapshot_id — Source snapshot
  • tags — Resource tags

Volume Attachments

  • device_name — Device name (/dev/sdf, /dev/sdg, etc.)
  • instance_id — Attached instance
  • volume_id — EBS volume ID
  • force_detach — Force detachment flag
  • skip_destroy — Skip on destroy

EBS Snapshots

  • volume_id — Source volume
  • description — Snapshot description
  • storage_tier — Standard or archive
  • tags — Resource tags

Network Interfaces

  • subnet_id — VPC subnet
  • private_ips — Private IP addresses
  • security_groups — Security group IDs
  • source_dest_check — Source/destination check
  • attachment — Attachment configuration
  • tags — Resource tags

Falco Rule Examples

# Instance Lifecycle
- rule: EC2 Instance Created
  desc: Detect when an EC2 instance is launched
  condition: >
    ct.name="RunInstances"
  output: >
    EC2 instance created
    (user=%ct.user ami=%ct.request.imageId instance_type=%ct.request.instanceType
     region=%ct.region account=%ct.account)
  priority: CRITICAL
  source: aws_cloudtrail
  tags: [terraform, drift, ec2, compute]

- rule: EC2 Instance Terminated
  desc: Detect when an EC2 instance is terminated
  condition: >
    ct.name="TerminateInstances"
  output: >
    EC2 instance terminated
    (user=%ct.user instance=%ct.request.instancesSet.items.instanceId
     region=%ct.region account=%ct.account)
  priority: CRITICAL
  source: aws_cloudtrail
  tags: [terraform, drift, ec2, compute, security]

# Volume Management
- rule: EBS Volume Created
  desc: Detect when an EBS volume is created
  condition: >
    ct.name="CreateVolume"
  output: >
    EBS volume created
    (user=%ct.user size=%ct.request.size type=%ct.request.volumeType az=%ct.request.availabilityZone
     region=%ct.region account=%ct.account)
  priority: WARNING
  source: aws_cloudtrail
  tags: [terraform, drift, ec2, ebs, storage]

Configuration Example

# config.yaml
drift_rules:
  - name: "EC2 Instance Configuration"
    resource_types:
      - "aws_instance"
    watched_attributes:
      - "instance_type"
      - "ami"
      - "vpc_security_group_ids"
      - "iam_instance_profile"
    severity: "critical"

  - name: "EBS Volume Management"
    resource_types:
      - "aws_ebs_volume"
      - "aws_volume_attachment"
    watched_attributes:
      - "size"
      - "type"
      - "encrypted"
    severity: "high"

Best Practices

1. Instance Configuration Management

# Terraform - Immutable infrastructure pattern
resource "aws_instance" "app" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type

  subnet_id                   = aws_subnet.private.id
  vpc_security_group_ids      = [aws_security_group.app.id]
  iam_instance_profile        = aws_iam_instance_profile.app.name

  monitoring = true

  root_block_device {
    volume_type           = "gp3"
    volume_size           = 20
    encrypted             = true
    delete_on_termination = true
  }

  lifecycle {
    create_before_destroy = true
  }

  tags = {
    Name        = "app-server"
    Environment = "production"
  }
}

2. EBS Volume Management

resource "aws_ebs_volume" "data" {
  availability_zone = aws_instance.app.availability_zone
  size              = 100
  type              = "gp3"
  encrypted         = true
  kms_key_id        = aws_kms_key.ebs.arn

  tags = {
    Name   = "app-data"
    Backup = "daily"
  }
}

resource "aws_volume_attachment" "data" {
  device_name = "/dev/sdf"
  volume_id   = aws_ebs_volume.data.id
  instance_id = aws_instance.app.id
}

Known Limitations

1. Instance State vs Configuration

  • StartInstances/StopInstances track state changes, not configuration
  • Use lifecycle.ignore_changes for instance state with auto-scaling

2. AMI Snapshot References

  • CreateImage creates implicit EBS snapshots
  • AMI deregistration doesn't auto-delete underlying snapshots

3. Network Interface Secondary IPs

  • Secondary private IP assignments not tracked via CloudTrail management events

Version History

  • v0.2.0-beta — Initial EC2 coverage (2 events)
  • v0.3.0 (2025 Q1) — EC2 Enhanced support with 17 CloudTrail events
  • Instance management (run, terminate, start, stop, modify)
  • AMI management (create, deregister)
  • EBS volume management (create, delete, attach, detach, modify)
  • Snapshot management (create, delete)
  • Network interface management (create, delete, attach)