Skip to content

Auto Scaling (Amazon EC2 Auto Scaling) — Drift Coverage

Overview

TFDrift-Falco monitors Amazon EC2 Auto Scaling for configuration drift by tracking CloudTrail events related to Auto Scaling groups, launch configurations, scaling policies, and scheduled actions. This enables real-time detection of manual changes made outside of Terraform workflows.

Supported CloudTrail Events

Auto Scaling Group Management (4 events)

Event Description Priority Status
CreateAutoScalingGroup Auto Scaling group created CRITICAL
DeleteAutoScalingGroup Auto Scaling group deleted CRITICAL
UpdateAutoScalingGroup Auto Scaling group configuration updated WARNING
SetDesiredCapacity Desired capacity manually set WARNING

Launch Configuration Management (2 events)

Event Description Priority Status
CreateLaunchConfiguration Launch configuration created WARNING
DeleteLaunchConfiguration Launch configuration deleted WARNING

Scaling Policy Management (2 events)

Event Description Priority Status
PutScalingPolicy Scaling policy created/updated WARNING
DeletePolicy Scaling policy deleted WARNING

Scheduled Action Management (2 events)

Event Description Priority Status
PutScheduledUpdateGroupAction Scheduled action created/updated WARNING
DeleteScheduledAction Scheduled action deleted WARNING

Total: 10 CloudTrail events

Supported Terraform Resources

  • aws_autoscaling_group — Auto Scaling group configuration
  • aws_launch_configuration — Launch configuration (EC2-Classic or default VPC)
  • aws_autoscaling_policy — Scaling policies (target tracking, step, simple)
  • aws_autoscaling_schedule — Scheduled scaling actions

Monitored Drift Attributes

Auto Scaling Groups

  • name — Auto Scaling group name
  • launch_configuration — Launch configuration name
  • launch_template — Launch template specification
  • min_size — Minimum capacity
  • max_size — Maximum capacity
  • desired_capacity — Desired capacity
  • default_cooldown — Default cooldown period (seconds)
  • health_check_type — Health check type (EC2, ELB)
  • health_check_grace_period — Grace period (seconds)
  • vpc_zone_identifier — VPC subnet IDs
  • availability_zones — Availability zones
  • load_balancers — Classic load balancer names
  • target_group_arns — ALB/NLB target group ARNs
  • termination_policies — Instance termination policies
  • enabled_metrics — CloudWatch metrics collection
  • suspended_processes — Suspended scaling processes
  • tags — Resource tags

Launch Configurations

  • name — Launch configuration name
  • image_id — AMI ID
  • instance_type — EC2 instance type
  • key_name — SSH key pair name
  • security_groups — Security group IDs
  • user_data — User data script
  • iam_instance_profile — IAM instance profile
  • ebs_optimized — EBS optimization flag
  • enable_monitoring — Detailed monitoring
  • spot_price — Spot instance max price
  • root_block_device — Root volume configuration
  • ebs_block_device — Additional EBS volumes

Scaling Policies

  • name — Policy name
  • autoscaling_group_name — Target Auto Scaling group
  • policy_type — Policy type (TargetTrackingScaling, StepScaling, SimpleScaling)
  • adjustment_type — Adjustment type (ChangeInCapacity, PercentChangeInCapacity, ExactCapacity)
  • scaling_adjustment — Scaling adjustment value
  • cooldown — Cooldown period (seconds)
  • target_tracking_configuration — Target tracking settings
  • step_adjustments — Step scaling adjustments
  • estimated_instance_warmup — Instance warmup time

Scheduled Actions

  • scheduled_action_name — Schedule name
  • autoscaling_group_name — Target Auto Scaling group
  • min_size — Scheduled minimum size
  • max_size — Scheduled maximum size
  • desired_capacity — Scheduled desired capacity
  • start_time — Start time (one-time)
  • end_time — End time
  • recurrence — Cron expression (recurring)
  • time_zone — Time zone

Falco Rule Examples

# Auto Scaling Group Lifecycle
- rule: Auto Scaling Group Created
  desc: Detect when an Auto Scaling group is created
  condition: >
    ct.name="CreateAutoScalingGroup"
  output: >
    Auto Scaling group created
    (user=%ct.user asg=%ct.request.autoScalingGroupName min=%ct.request.minSize max=%ct.request.maxSize
     region=%ct.region account=%ct.account)
  priority: CRITICAL
  source: aws_cloudtrail
  tags: [terraform, drift, autoscaling, compute]

- rule: Auto Scaling Group Deleted
  desc: Detect when an Auto Scaling group is deleted
  condition: >
    ct.name="DeleteAutoScalingGroup"
  output: >
    Auto Scaling group deleted
    (user=%ct.user asg=%ct.request.autoScalingGroupName
     region=%ct.region account=%ct.account)
  priority: CRITICAL
  source: aws_cloudtrail
  tags: [terraform, drift, autoscaling, compute, security]

# Configuration Changes
- rule: Auto Scaling Group Updated
  desc: Detect when Auto Scaling group configuration is updated
  condition: >
    ct.name="UpdateAutoScalingGroup"
  output: >
    Auto Scaling group updated
    (user=%ct.user asg=%ct.request.autoScalingGroupName
     region=%ct.region account=%ct.account)
  priority: WARNING
  source: aws_cloudtrail
  tags: [terraform, drift, autoscaling, configuration]

# Manual Scaling
- rule: Auto Scaling Desired Capacity Changed
  desc: Detect when desired capacity is manually set
  condition: >
    ct.name="SetDesiredCapacity"
  output: >
    Auto Scaling desired capacity changed
    (user=%ct.user asg=%ct.request.autoScalingGroupName capacity=%ct.request.desiredCapacity
     region=%ct.region account=%ct.account)
  priority: WARNING
  source: aws_cloudtrail
  tags: [terraform, drift, autoscaling, scaling]

# Scaling Policy Management
- rule: Auto Scaling Policy Created
  desc: Detect when a scaling policy is created or updated
  condition: >
    ct.name="PutScalingPolicy"
  output: >
    Auto Scaling policy created/updated
    (user=%ct.user policy=%ct.request.policyName asg=%ct.request.autoScalingGroupName
     region=%ct.region account=%ct.account)
  priority: WARNING
  source: aws_cloudtrail
  tags: [terraform, drift, autoscaling, policy]

# Scheduled Actions
- rule: Auto Scaling Scheduled Action Created
  desc: Detect when a scheduled action is created or updated
  condition: >
    ct.name="PutScheduledUpdateGroupAction"
  output: >
    Auto Scaling scheduled action created/updated
    (user=%ct.user action=%ct.request.scheduledActionName asg=%ct.request.autoScalingGroupName
     region=%ct.region account=%ct.account)
  priority: WARNING
  source: aws_cloudtrail
  tags: [terraform, drift, autoscaling, schedule]

Example Drift Scenarios

Scenario 1: Desired Capacity Manually Changed

CloudTrail Event:

{
  "eventName": "SetDesiredCapacity",
  "requestParameters": {
    "autoScalingGroupName": "web-asg",
    "desiredCapacity": 10,
    "honorCooldown": false
  },
  "userIdentity": {
    "principalId": "AIDAI23ABCD4EFGH5IJKL",
    "userName": "ops-engineer"
  }
}

TFDrift-Falco Alert:

🚨 Drift Detected: aws_autoscaling_group.web_asg
Changed: desired_capacity = 5 → 10
User: ops-engineer (IAM User)
Region: us-east-1
Severity: MEDIUM

Scenario 2: Auto Scaling Group Deleted

CloudTrail Event:

{
  "eventName": "DeleteAutoScalingGroup",
  "requestParameters": {
    "autoScalingGroupName": "prod-asg",
    "forceDelete": true
  },
  "userIdentity": {
    "type": "AssumedRole",
    "principalId": "AROAI23ABCD4EFGH5IJKL:admin"
  }
}

TFDrift-Falco Alert:

🚨 Drift Detected: aws_autoscaling_group.prod_asg
DELETED: Auto Scaling group removed with force
User: admin (Assumed Role)
Region: us-east-1
Severity: CRITICAL

Scenario 3: Scaling Policy Modified

CloudTrail Event:

{
  "eventName": "PutScalingPolicy",
  "requestParameters": {
    "autoScalingGroupName": "api-asg",
    "policyName": "cpu-scale-out",
    "policyType": "TargetTrackingScaling",
    "targetTrackingConfiguration": {
      "predefinedMetricSpecification": {
        "predefinedMetricType": "ASGAverageCPUUtilization"
      },
      "targetValue": 80.0
    }
  }
}

TFDrift-Falco Alert:

🚨 Drift Detected: aws_autoscaling_policy.cpu_scale_out
Changed: target_tracking_configuration.target_value = 70.0 → 80.0
User: sre-team (Assumed Role)
Region: us-east-1
Severity: MEDIUM

Scenario 4: Scheduled Action Added

CloudTrail Event:

{
  "eventName": "PutScheduledUpdateGroupAction",
  "requestParameters": {
    "autoScalingGroupName": "batch-asg",
    "scheduledActionName": "scale-up-morning",
    "recurrence": "0 8 * * MON-FRI",
    "minSize": 10,
    "maxSize": 20,
    "desiredCapacity": 15
  }
}

TFDrift-Falco Alert:

🚨 Drift Detected: aws_autoscaling_schedule (unmanaged)
NEW: Scheduled action created outside Terraform
name: scale-up-morning
recurrence: 0 8 * * MON-FRI
User: developer@example.com (Console)
Region: us-east-1
Severity: LOW

Configuration Example

# config.yaml
drift_rules:
  - name: "Auto Scaling Group Configuration"
    resource_types:
      - "aws_autoscaling_group"
    watched_attributes:
      - "min_size"
      - "max_size"
      - "desired_capacity"
      - "launch_configuration"
      - "launch_template"
      - "vpc_zone_identifier"
    severity: "critical"

  - name: "Scaling Policies"
    resource_types:
      - "aws_autoscaling_policy"
    watched_attributes:
      - "policy_type"
      - "target_tracking_configuration"
      - "adjustment_type"
      - "scaling_adjustment"
    severity: "high"

  - name: "Scheduled Actions"
    resource_types:
      - "aws_autoscaling_schedule"
    watched_attributes:
      - "min_size"
      - "max_size"
      - "desired_capacity"
      - "recurrence"
    severity: "medium"

Best Practices

1. Auto Scaling Group with Target Tracking

# Terraform - ASG with CPU-based target tracking
resource "aws_autoscaling_group" "web" {
  name                = "web-asg"
  launch_configuration = aws_launch_configuration.web.name
  min_size            = 2
  max_size            = 10
  desired_capacity    = 3
  health_check_type   = "ELB"
  health_check_grace_period = 300
  vpc_zone_identifier = aws_subnet.private[*].id
  target_group_arns   = [aws_lb_target_group.web.arn]

  # Termination policies
  termination_policies = [
    "OldestLaunchConfiguration",
    "Default"
  ]

  # Metrics
  enabled_metrics = [
    "GroupDesiredCapacity",
    "GroupInServiceInstances",
    "GroupMinSize",
    "GroupMaxSize"
  ]

  # Important: Ignore desired_capacity for policy-based scaling
  lifecycle {
    ignore_changes = [desired_capacity]
  }

  tag {
    key                 = "Name"
    value               = "web-server"
    propagate_at_launch = true
  }
}

# Target tracking scaling policy
resource "aws_autoscaling_policy" "cpu_tracking" {
  name                   = "cpu-target-tracking"
  autoscaling_group_name = aws_autoscaling_group.web.name
  policy_type            = "TargetTrackingScaling"

  target_tracking_configuration {
    predefined_metric_specification {
      predefined_metric_type = "ASGAverageCPUUtilization"
    }
    target_value = 70.0
  }
}

2. Launch Configuration

# Terraform - Launch configuration for ASG
resource "aws_launch_configuration" "web" {
  name_prefix          = "web-"
  image_id             = data.aws_ami.ubuntu.id
  instance_type        = "t3.medium"
  key_name             = var.key_name
  security_groups      = [aws_security_group.web.id]
  iam_instance_profile = aws_iam_instance_profile.web.name

  # User data
  user_data = base64encode(templatefile("${path.module}/user_data.sh", {
    environment = "production"
  }))

  # EBS optimization
  ebs_optimized = true

  # Enable detailed monitoring
  enable_monitoring = true

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

  # Create new before destroying old
  lifecycle {
    create_before_destroy = true
  }
}

3. Step Scaling Policy

# Terraform - Step scaling for high traffic
resource "aws_autoscaling_policy" "scale_out" {
  name                   = "scale-out-step"
  autoscaling_group_name = aws_autoscaling_group.api.name
  policy_type            = "StepScaling"
  adjustment_type        = "PercentChangeInCapacity"

  # Warmup time
  estimated_instance_warmup = 300

  step_adjustment {
    metric_interval_lower_bound = 0
    metric_interval_upper_bound = 10
    scaling_adjustment          = 10
  }

  step_adjustment {
    metric_interval_lower_bound = 10
    scaling_adjustment          = 20
  }
}

# CloudWatch alarm to trigger scaling
resource "aws_cloudwatch_metric_alarm" "high_cpu" {
  alarm_name          = "api-high-cpu"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 2
  metric_name         = "CPUUtilization"
  namespace           = "AWS/EC2"
  period              = 60
  statistic           = "Average"
  threshold           = 80

  dimensions = {
    AutoScalingGroupName = aws_autoscaling_group.api.name
  }

  alarm_actions = [aws_autoscaling_policy.scale_out.arn]
}

4. Scheduled Scaling

# Terraform - Scale up for business hours
resource "aws_autoscaling_schedule" "scale_up_morning" {
  scheduled_action_name  = "scale-up-morning"
  autoscaling_group_name = aws_autoscaling_group.batch.name
  min_size               = 5
  max_size               = 20
  desired_capacity       = 10
  recurrence             = "0 8 * * MON-FRI"
  time_zone              = "America/New_York"
}

# Scale down for off-hours
resource "aws_autoscaling_schedule" "scale_down_evening" {
  scheduled_action_name  = "scale-down-evening"
  autoscaling_group_name = aws_autoscaling_group.batch.name
  min_size               = 2
  max_size               = 5
  desired_capacity       = 2
  recurrence             = "0 18 * * MON-FRI"
  time_zone              = "America/New_York"
}

Security Considerations

1. Launch Configuration Security

  • Use encrypted EBS volumes
  • Apply least-privilege IAM instance profiles
  • Avoid embedding secrets in user_data
  • Use AWS Secrets Manager or SSM Parameter Store
  • Monitor image_id changes for AMI drift

2. Network Security

  • Deploy ASG instances in private subnets
  • Use security groups to restrict access
  • Monitor vpc_zone_identifier changes
  • Track security group associations

3. Scaling Policies

  • Set appropriate min/max boundaries
  • Monitor SetDesiredCapacity for manual overrides
  • Use target tracking for predictable workloads
  • Track cooldown period changes

4. Access Control

  • Restrict who can modify ASG configurations
  • Monitor UpdateAutoScalingGroup events
  • Alert on DeleteAutoScalingGroup operations
  • Track suspended_processes changes

Known Limitations

1. Desired Capacity Management

  • SetDesiredCapacity is normal during auto-scaling
  • Use lifecycle.ignore_changes for desired_capacity
  • Distinguish between manual and automatic changes
  • Policy-based scaling triggers frequent updates

2. Launch Template vs Launch Configuration

  • Launch templates not tracked in current implementation
  • Only launch configurations have dedicated events
  • Launch template changes tracked via UpdateAutoScalingGroup
  • Consider separate monitoring for launch templates

3. Mixed Instances Policy

  • Mixed instances policy changes tracked via UpdateAutoScalingGroup
  • Detailed instance type changes not granularly tracked
  • Use Terraform state comparison for detailed drift

4. Lifecycle Hooks

  • Lifecycle hook changes not tracked in current implementation
  • Planned for future enhancement
  • Monitor via UpdateAutoScalingGroup events

Version History

  • v0.3.0 (2025 Q1) - Initial Auto Scaling support with 10 CloudTrail events
  • Auto Scaling group management (create, delete, update, set capacity)
  • Launch configuration management (create, delete)
  • Scaling policy management (put, delete)
  • Scheduled action management (put, delete)
  • Comprehensive drift detection for auto-scaling infrastructure