Modern QA2026Cost Control Strategies — tiles
Log inJoin
67 / 75 · 08 Infrastructure as Code Testing · Ephemeral Environments← prev⊞ allnext →☰ Read as one page

12.5Cost Control Strategies

Ephemeral environments can be expensive if not managed carefully. A single PR environment with an RDS instance, ECS service, and load balancer costs roughly $5-15/day. With 20 active PRs, that is $100-300/day.

Strategy Implementation Savings
Auto-destroy after N hours GitHub Action cron job + terraform destroy 60-80%
Minimal instance sizes Conditional sizing based on workspace name 70-90%
Shared read-only resources Reference production VPC, DNS zone via data sources 20-30%
Spot instances for compute capacity_type = "SPOT" for EKS nodes 60-70%
Scheduled scale-to-zero Lambda that scales down PR envs outside business hours 50-60%
TTL tags on all resources Automated cleanup of resources older than 48 hours Prevents zombie resources

Auto-Destroy Cron Job

# .github/workflows/cleanup-ephemeral.yml
name: Cleanup Stale Ephemeral Environments
on:
  schedule:
    - cron: '0 2 * * *'  # Daily at 2 AM UTC
  workflow_dispatch:

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Find stale environments
        run: |
          cd terraform/
          terraform workspace list | grep "pr-" | while read ws; do
            WS_NAME=$(echo "$ws" | tr -d ' *')
            PR_NUM=$(echo "$WS_NAME" | grep -oP '\d+')

            # Check if the PR is still open
            PR_STATE=$(gh pr view "$PR_NUM" --json state -q '.state' 2>/dev/null || echo "UNKNOWN")

            if [ "$PR_STATE" != "OPEN" ]; then
              echo "Destroying stale environment: $WS_NAME (PR state: $PR_STATE)"
              terraform workspace select "$WS_NAME"
              terraform destroy -auto-approve
              terraform workspace select default
              terraform workspace delete "$WS_NAME"
            fi
          done

Resource TTL Tags

# Add TTL tags to all ephemeral resources
locals {
  common_tags = merge(
    {
      Team        = "platform"
      Environment = local.env_name
      ManagedBy   = "terraform"
    },
    local.is_ephemeral ? {
      EphemeralTTL = timeadd(timestamp(), "48h")
      PRNumber     = var.pr_number
    } : {}
  )
}