Sweepers
This document describes the test sweeper infrastructure for cleaning up leaked test resources.
Overview
Section titled “Overview”Sweepers clean up resources that were created during acceptance tests but failed to be destroyed. This can happen when:
- Tests fail before cleanup
- API errors prevent deletion
- Developer interrupts tests
- Partial test runs leave resources behind
Running Sweepers
Section titled “Running Sweepers”Clean up all test resources
Section titled “Clean up all test resources”make sweepAllow failures and continue
Section titled “Allow failures and continue”make sweeperRun specific sweeper
Section titled “Run specific sweeper”TF_ACC=1 go test ./internal/sweep -v -sweep=default -sweep-run=crowdstrike_host_groupControl Log Verbosity
Section titled “Control Log Verbosity”Sweepers use structured logging with configurable log levels. Set the SWEEP_LOG_LEVEL environment variable to control output verbosity:
# Show only warnings and errors (default: INFO)SWEEP_LOG_LEVEL=WARN make sweep
# Show all logs including trace messages (useful for debugging)SWEEP_LOG_LEVEL=TRACE make sweep
# Available levels: TRACE, DEBUG, INFO, WARN, ERRORLog levels:
- TRACE - Detailed debug information including all skipped resources
- DEBUG - Debug information
- INFO - General operational information (default)
- WARN - Warning messages for non-critical issues
- ERROR - Error messages
Example with trace logging:
SWEEP_LOG_LEVEL=TRACE make sweep# Output includes: [TRACE] Skipping Prevention Policy production-policy (not a test resource)Prerequisites
Section titled “Prerequisites”Sweepers require the same environment variables as acceptance tests:
FALCON_CLIENT_ID- CrowdStrike API client IDFALCON_CLIENT_SECRET- CrowdStrike API client secretFALCON_CLOUD- (optional) Cloud region
WARNING: Sweepers will delete infrastructure. Only run in development/test accounts.
Test Resource Naming
Section titled “Test Resource Naming”All test resources MUST use the sweep.ResourcePrefix constant (defined as "tf-acc-test-" in internal/sweep/sweep.go) to be identified by sweepers.
Example:
name := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) // "tf-acc-test-abc123"Registered Sweepers
Section titled “Registered Sweepers”The following sweepers are currently registered:
crowdstrike_host_group- Host groupscrowdstrike_prevention_policy- Prevention policies (Windows, Linux, Mac)crowdstrike_sensor_update_policy- Sensor update policiescrowdstrike_content_update_policy- Content update policies (RT Response)crowdstrike_cloud_aws_account- AWS cloud account registrationscrowdstrike_cloud_gcp_account- GCP cloud account registrationscrowdstrike_ioa_rule_group- Custom IOA rule groupscrowdstrike_firewall_rule_group- Firewall rule groupscrowdstrike_sensor_visibility_exclusion- Sensor visibility exclusionscrowdstrike_ml_file_path_exclusion- Machine learning file path exclusionscrowdstrike_data_protection_content_pattern- Data protection content patternscrowdstrike_data_protection_sensitivity_label- Data protection sensitivity labelscrowdstrike_cloud_compliance_custom_framework- Cloud compliance custom frameworkscrowdstrike_cloud_group- Cloud groupscrowdstrike_cloud_security_custom_rule- Cloud security custom rulescrowdstrike_cloud_security_kac_policy- Cloud security KAC policiescrowdstrike_it_automation_task- IT automation taskscrowdstrike_it_automation_task_group- IT automation task groupscrowdstrike_it_automation_policy- IT automation policies
Adding New Sweepers
Section titled “Adding New Sweepers”- Create
sweep.goin the service package (e.g.,internal/host_groups/sweep.go) - Implement
RegisterSweepers()function - Add sweeper registration to
internal/sweep/sweep_test.go
Example:
package myservice
import ( "github.com/hashicorp/terraform-provider-crowdstrike/internal/sweep")
func RegisterSweepers() { sweep.Register("crowdstrike_my_resource", sweepMyResources, "crowdstrike_dependency", // Optional dependencies )}
func sweepMyResources(ctx context.Context, client *client.CrowdStrikeAPISpecification) ([]sweep.Sweepable, error) { // Implementation}Sweeper Dependencies
Section titled “Sweeper Dependencies”Sweepers can declare dependencies to ensure cleanup order:
sweep.Register("crowdstrike_policy_attachment", sweepAttachments)sweep.Register("crowdstrike_policy", sweepPolicies, "crowdstrike_policy_attachment", // Delete attachments first)Architecture
Section titled “Architecture”Core Components
Section titled “Core Components”internal/sweep/sweep.go- Core interfaces (Sweepable), shared client, and orchestrationinternal/sweep/register.go- Registration helper that wraps sweepers with error handlinginternal/sweep/resource.go- Resource wrapper for creating sweepable resourcesinternal/sweep/skip.go- Error handling logic for skipping transient failuresinternal/sweep/sweep_test.go- TestMain entry point and sweeper registration
Service Sweepers
Section titled “Service Sweepers”Each service package can implement a sweep.go file that:
- Defines a
RegisterSweepers()function - Implements sweep functions that list and filter test resources
- Returns a list of
Sweepableresources to delete
Parallel Deletion
Section titled “Parallel Deletion”The SweepOrchestrator uses hashicorp/go-multierror to delete resources in parallel while collecting errors. All resources within a sweeper are deleted concurrently unless errors occur.
Error Handling
Section titled “Error Handling”Sweepers skip transient errors that shouldn’t fail the entire sweep:
- Rate limiting (429)
- Service unavailable (503)
- Timeouts
- Network errors
- Resource not found (404)
Implementation Details
Section titled “Implementation Details”Resource Identification
Section titled “Resource Identification”Test resources are identified by the sweep.ResourcePrefix constant in their name field:
if !strings.HasPrefix(name, sweep.ResourcePrefix) { log.Printf("[INFO] Skipping resource %s (not a test resource)", name) continue}Delete Function Pattern
Section titled “Delete Function Pattern”Each service implements a delete function:
func deleteResource(ctx context.Context, client *client.CrowdStrikeAPISpecification, id string) error { params := service.NewDeleteResourceParams() params.WithContext(ctx) params.Ids = []string{id}
_, err := client.Service.DeleteResource(params) if err != nil { if sweep.ShouldIgnoreError(err) { sweep.Debug("Ignoring error for resource %s: %s", id, err) return nil } return err }
return nil}Troubleshooting
Section titled “Troubleshooting”Sweeper Fails with Rate Limit Error
Section titled “Sweeper Fails with Rate Limit Error”Rate limit errors are automatically skipped. If you see consistent rate limiting, you can:
- Wait and re-run the sweeper
- Run sweepers for specific resources instead of all at once
Resources Not Being Swept
Section titled “Resources Not Being Swept”Verify that:
- Resources use the
sweep.ResourcePrefixconstant (accessed viaacctest.ResourcePrefixin tests) - The sweeper is registered in
internal/sweep/sweep_test.go - The list API call is returning the resources
Sweeper Times Out
Section titled “Sweeper Times Out”Increase the timeout:
make sweep SWEEP_TIMEOUT=120mDevelopment
Section titled “Development”Running Tests
Section titled “Running Tests”The sweep infrastructure can be tested by:
- Creating test resources manually
- Running the sweeper
- Verifying resources are deleted
Example:
# Create a test host group via Terraformcd examples/resources/crowdstrike_host_groupterraform apply
# Run the sweepermake sweep
# Verify the resource was deletedterraform plan # Should show resource needs to be createdAdding Dependencies
Section titled “Adding Dependencies”When adding a new sweeper, consider if other resources must be deleted first:
- Attachments before policies
- Policies before the resources they protect
- Child resources before parent resources
Declare dependencies in the Register() call:
sweep.Register("crowdstrike_child", sweepChildren)sweep.Register("crowdstrike_parent", sweepParents, "crowdstrike_child", // Delete children first)