โ†
AI for IT Certification
Aware ยท M45 ยท lesson 45 of 120 ยท queued
Preview โ€” browse every lesson free. Enroll to mark lessons complete, open partner links and save your progress. Login & enroll โ†’
Config Management And Drift Detection
๐Ÿ“–
now learning

Config Management And Drift Detection

15 min

Hook

Your infrastructure-as-code declares a database with max_connections = 500. The actual database has max_connections = 300. Somewhere between the code review and production, someone made a manual tweak. That drift has been running for 6 months. No one noticed because the limit hasn't been hit. Until today: application scales up, hits 295 concurrent connections, and starts rejecting new requests. Post-incident analysis: the drift has been there all along. Now multiply this by thousands of configuration parameters across hundreds of servers, databases, load balancers, and networks. You can't manually audit all of them. An AI-powered drift detection system learns your baseline configuration, continuously compares actual state to declared state, flags meaningful drift (the 300-connection limit) separately from harmless variance (temporary file timestamps), and recommends remediation before misconfigurations cause outages.

Purpose

Configuration drift happens when the actual state of your infrastructure diverges from the declared state. In IaC (Terraform, CloudFormation, Ansible), you declare what resources should look like. But manual changes, emergency hotfixes, patches applied by vendors, and failed automation can cause drift.

Most drift is harmless. A log file's timestamp differs. A package version updates automatically. A cache is cleared. But some drift is dangerous: a security group rule is deleted, a database backup is disabled, a firewall rule is changed, a permission is modified.

Traditional drift detection is manual and expensive: ops teams periodically run Terraform plan, inspect the output, and manually decide "is this drift OK or a problem?" As infrastructure scales, this becomes infeasible.

AI-driven drift detection automates this:

  • Continuous monitoring: Compare actual state to baseline every hour, not quarterly.
  • Classification: Distinguish harmless drift (timestamps, generated IDs) from meaningful drift (configuration parameters, security settings).
  • Remediation recommendations: Suggest fixes (revert drift, update IaC, acknowledge as new baseline).
  • Compliance reporting: Flag drift that violates compliance frameworks (CIS benchmarks, PCI-DSS, HIPAA).

This lesson teaches you to design drift detection workflows: capturing baselines โ†’ continuous comparison โ†’ classifying drift โ†’ recommending remediation โ†’ integrating with IaC and compliance systems.

Why This Matters

Configuration drift is a hidden killer. It causes:

Operational issues: Misconfigured parameters degrade performance or cause failures. The database connection limit drift cited above. A load balancer timeout changed from 60s to 30s (manually, to "fix" a specific issue), now timing out legitimate long-running requests.

Security issues: A security group rule deleted (unauthorized, or by accident). An IAM permission modified (over-permissioned). A encryption setting disabled (compliance violation).

Compliance failures: PCI-DSS requires logging to be enabled on all databases. Manual audit finds logging disabled on one database, drift from baseline. Compliance audit finds this, generates a finding, and you scramble to explain how it happened.

Troubleshooting delays: Application is slow. Ops investigates the code, the database, the network. Turns out a kernel parameter was changed three months ago, degrading I/O performance. No one knew about the change; it's not in any ticketing system.

Expensive to fix at scale: Manually reverting drift across thousands of servers is error-prone. Bulk changes risk breaking systems. Safe, gradual remediation requires careful orchestration.

AI-driven drift detection catches these issues early, prevents compliance failures, and reduces troubleshooting time.

Core Concepts

Key insight: Configuration State Has Multiple Dimensions

Configuration is not a single thing; it's a multi-dimensional state space:

  • Declarative state: What you declared in IaC (Terraform vars, Ansible playbooks, CloudFormation templates).
    - Deployed state: What the deployment pipeline actually applied (which Terraform vars were used, which playbook tasks ran).
    - Actual state: What the infrastructure is actually running (what the OS reports, what the API returns, what a network scan shows).
    - Desired state: What you want (might differ from declared state if policies change; e.g., "all servers must run Ubuntu 22.04", and you're on 20.04).

A complete drift detection system monitors all four dimensions.

Example: Security group rule

  • Declared: "Allow SSH from office IP 10.1.0.0/16."
  • Deployed: Same.
  • Actual: "Allow SSH from 0.0.0.0/0" (someone manually added a rule to debug an issue).
  • Desired: "Allow SSH from office IP only, and only during business hours."
  • Drift: Actual differs from declared (open SSH). Also, actual doesn't meet desired (no time restriction).

Key insight: Not All Drift is Bad; Distinguishing Signal from Noise

A server boots. Its /tmp directory has new timestamps (files created during boot). Is this drift? Technically yes, the actual timestamps differ from yesterday. Is it meaningful? No.

Real drift:

  • Configuration parameter changed (max_connections, timeout, thread pool size).
  • Permission or security setting changed (encryption enabled/disabled, firewall rule added/removed).
  • Software version differs from declared version.
  • File permissions changed (owner, group, mode).
  • Installed packages differ from declared.

Harmless drift:

  • Log file timestamps.
  • Temporary file contents (cache, temporary directories).
  • Dynamically generated values (UUIDs, auto-generated IDs).
  • System-managed metadata (access times, inode counts).

AI classification uses features like:

  • Type of change: Configuration parameter changes are meaningful. Timestamp changes are harmless.
  • Frequency of change: Parameters that change rarely are meaningful if they drift. Metrics that change constantly (file modification times) are noise.
  • Business impact: Does this drift affect the application? Does it affect security, compliance, or performance?
  • Historical patterns: If this drift happens regularly (e.g., temp files get cleaned up daily), it's expected noise.

Key insight: Baseline Capture Requires Care

Your baseline is the source of truth for comparison. If your baseline is corrupted, all subsequent drift detection is garbage.

Capture baseline correctly:

  • Capture from a known-good state. Don't capture configuration from a system that's partially broken or mid-deployment.
  • Capture at a specific point in time (tag the git commit, record the deployment ID, note the timestamp).
  • Capture all relevant dimensions: filesystem, registry, APIs, databases, cloud resources.
  • Document assumptions: "Baseline assumes Ubuntu 20.04, kernel 5.10, no custom patches."
  • Validate baseline: Check that it matches your IaC. If IaC says port 443 should be open, verify baseline shows it open.

Maintain baseline over time:

  • As infrastructure changes (security patches, package updates), update baseline intentionally. Don't let baseline drift unconsciously.
  • Use a change control process: "Need to update baseline to Ubuntu 22.04. Approval required, tracked in change ticket."
  • Version your baseline (baseline v1.0, v1.1, v2.0). Changes are diffs, not black boxes.

Key insight: Continuous Comparison at the Right Granularity

How often should you compare actual state to baseline?

  • Real-time: Security-critical configs (firewall rules, IAM policies, encryption settings). Detect changes immediately.
    - Hourly: Performance-critical configs (database parameters, kernel tuning). Catch changes quickly.
    - Daily: Routine configs (package versions, file permissions). Drift detection with lower overhead.
    - Weekly or on-demand: Low-risk configs (documentation files, metadata). Manual checks sufficient.

Granularity matters. Comparing every field of a 1 MB config file every minute is wasteful. Comparing every byte is over-detailed; you only care about changes to meaningful parameters.

Smart comparison strategy:

  • Identify changeable fields (versions, timestamps, generated IDs). Ignore in comparison.
  • Identify critical fields (security settings, performance parameters). Compare frequently.
  • Ignore machine-generated diffs (reformatting, comments). Focus on semantic changes.
  • Use hash-based comparison for large configs: compare hashes first (fast), then diff details (slow) only if hash changed.

Key insight: Remediation Requires Human Decision-Making

When drift is detected, you don't automatically fix it. Drift detection should recommend remediation, not execute it.

Options for remediation:

  1. Revert to baseline: Restore the declared configuration (safest for most drifts).
  2. Update IaC: The new configuration is actually better than declared. Update IaC to match actual state (formalize the change).
  3. Investigate: Drift is unexpected. Investigate why it happened (unplanned maintenance? Vendor patch? Security incident?).
  4. Acknowledge as acceptable: Drift is expected and harmless. Update baseline to include it (prevent false alarms).

Different organizations have different policies:

  • Strict: All drift is unacceptable. Revert automatically, ask questions later.
  • Moderate: Meaningful drift is problematic. Investigate, then decide remediation. Harmless drift is acknowledged.
  • Permissive: Drift is tolerated unless it's a compliance violation or security risk.

AI assists by classifying drift and recommending remediation. Humans make the final decision, especially for security and compliance drift.

Key insight: Compliance Integration

Many compliance frameworks require configuration baselines:

  • CIS Benchmarks: Define secure configurations for operating systems, databases, cloud platforms. Drift from CIS baseline is a finding.
    - PCI-DSS: Requires encryption to be enabled, logging to be turned on, firewalls to be configured in a specific way.
    - HIPAA: Requires encryption, audit logging, access controls.
    - SOC 2: Requires configuration management and change control.

An AI-driven drift detection system should integrate with compliance frameworks:

  • Know which configuration changes require approval under SOC 2.
  • Flag changes that violate PCI-DSS (e.g., encryption disabled).
  • Highlight CIS benchmark deviations.
  • Generate compliance reports (e.g., "100% of servers match CIS Level 1 baseline").

Practical Use Cases

Before/After: Detecting Security Drift (IAM Permissions)

Before AI (Manual Quarterly Audits):

  • March: Security team manually checks IAM policies. All policies match the approval matrix. Check passes.
  • May: Someone creates a temporary IAM role to debug an issue. Attaches it to a production database user account.
  • July (two months later): Quarterly security audit. Team discovers the overpermissioned role. Investigation reveals it's been there 2 months. Who created it? When? Why? Logs are fuzzy. Possible compliance violation. Incident report generated.
  • September: Compliance audit finds this drift. Becomes a Finding in the annual SOC 2 audit.
  • Cost: Security team labor, compliance violation remediation, audit findings.

With AI:

  • May: Role is created. Drift detection service queries IAM policies hourly.
  • May, next hour: New role is detected. Doesn't match any approved role template. Flagged as "unauthorized IAM role." Alert to security team: "New IAM role 'debug-role' created on May 5. Not in approval matrix. Recommend review."
  • May, same day: Security team reviews. Sees it was created for debugging. Requires temporary role to have an expiration date and explicit approval. Role is either deleted or moved to temporary status with 30-day expiration.
  • No July surprise. No compliance finding.

Before/After: Detecting Performance Configuration Drift (Database Parameters)

Before AI:

  • Database max_connections is declared as 500 in Terraform.
  • During an outage on March 15, DBA manually reduces it to 300 to prevent cascading connection storms.
  • Fix is supposed to be temporary. DBA forgets to change it back.
  • April-September: Application scales up gradually. Begins hitting 300-connection limit during peak. New connections are rejected. 3% of requests fail.
  • User complaints: "Your service is flaky during peak hours."
  • September: Performance analysis reveals connection limit is the bottleneck. IaC is checked; Terraform says 500. Database says 300. Drift is found. Investigated: manual change from March, never reverted. Changed back to 500. Problem solved.
  • Cost: 6 months of customer complaints, investigation time, reputation damage.

With AI:

  • March 15: DBA manually reduces max_connections to 300.
  • March 16: Drift detection compares actual (300) to baseline (500). Flags it: "Database max_connections differs from baseline. Current: 300, Baseline: 500. Change magnitude: -40%. Estimated impact: connection rejections possible at high load."
  • March 16, morning: Alert to DBA: "Config drift detected in production database. Review and confirm intent."
  • March 16, 2 PM: DBA confirms: "This is a temporary emergency change from yesterday. Will revert when load stabilizes. Expect revert by March 20."
  • March 20: Monitoring shows load has stabilized. DBA reverts max_connections to 500. Drift resolved.
  • No April-September problem. No customer complaints.

Before/After: Detecting Compliance Drift (Encryption)

Before AI:

  • Security policy: "All databases must have encryption at rest enabled."
  • A new database is created manually (not via IaC) for a quick analytics project. Encryption is omitted (more performance, less compliance thinking).
  • Database runs for 8 months with no encryption.
  • Annual compliance audit: All databases scanned. Compliance tool finds unencrypted database. Becomes a critical finding. Encryption must be enabled retroactively (requires rebuilding the database).
  • Post-incident: Why wasn't this caught? Database was not in the CMDB. It was created outside the standard process. Cost: compliance finding, rebuild effort, potential audit failure.

With AI:

  • New database is created manually.
  • Drift detection service scans cloud account (AWS, GCP, Azure). Discovers new database resource.
  • Compares configuration to compliance baseline: "Encryption at rest: required by CIS benchmark and company policy."
  • Actual database: encryption disabled.
  • Drift flagged as critical: "Database 'analytics-db' does not meet compliance baseline. Encryption at rest is disabled. Recommend enabling encryption immediately."
  • Alert to ops and compliance team: "Non-compliant database detected. Requires immediate remediation per SOC 2 policy."
  • Encryption is enabled the same day. No compliance finding.

Examples

Example 1: Drift Detection Workflow for Kubernetes ConfigMaps

Scenario: ConfigMap declared in IaC defines database connection string. Someone manually edits the ConfigMap in the cluster (without updating IaC).

Step 1: Capture Baseline
โ””โ”€ IaC declares ConfigMap:
{
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DB_CONNECTION: "postgres://prod-db:5432"
LOG_LEVEL: "INFO"
CACHE_TTL: "3600"
}
โ””โ”€ Baseline captured from IaC at git commit: abc123def456

Step 2: Deploy to Cluster
โ””โ”€ Kubernetes controller applies ConfigMap to cluster
โ””โ”€ Actual state in cluster matches baseline (initially)

Step 3: Someone Manually Edits ConfigMap (without IaC change)
โ””โ”€ kubectl edit configmap app-config
โ””โ”€ Change: LOG_LEVEL: "INFO" โ†’ "DEBUG" (troubleshooting)
โ””โ”€ Change applied directly to cluster (not via IaC)

Step 4: Drift Detection Runs (hourly)
โ””โ”€ Queries cluster: kubectl get configmap app-config -o yaml
โ””โ”€ Compares actual state (DEBUG) to baseline (INFO)
โ””โ”€ Identifies drift:
{
field: data.LOG_LEVEL
baseline: "INFO"
actual: "DEBUG"
type: configuration parameter
significance: high (affects logging behavior)
impact: moderate (debug logging uses more disk/bandwidth)
}

Step 5: Classify Drift
โ””โ”€ Is LOG_LEVEL meaningful? Yes. It affects application behavior.
โ””โ”€ Is this expected? No. Not in IaC, not tracked in any change ticket.
โ””โ”€ Harmless? Probably. Debug logging doesn't break anything.
โ””โ”€ But it's undeclared. Should be tracked.
โ””โ”€ Classification: ANOMALOUS (untracked change, not critical)

Step 6: Alert & Remediation Options
โ””โ”€ Alert to ops: "ConfigMap drift detected. data.LOG_LEVEL is DEBUG (actual) vs INFO (baseline)."
โ””โ”€ Options presented:
โ”œโ”€ Option 1: Revert to baseline (set LOG_LEVEL back to INFO)
โ”œโ”€ Option 2: Update IaC to match actual (make DEBUG the new baseline)
โ”œโ”€ Option 3: Investigate (who changed it? why? when?)
โ”œโ”€ Option 4: Acknowledge (this is acceptable; suppress future alerts)

Step 7: Remediation
โ””โ”€ Ops chooses Option 2: Update IaC to DEBUG
โ””โ”€ Kubernetes ConfigMap is now declared as DEBUG in git
โ””โ”€ IaC is committed and tracked
โ””โ”€ Drift resolves; future state is consistent

Example 2: Detecting Drift in Database Configuration Parameters

Three servers: Postgres database replicas. Declared configuration: identical in IaC.

Server 1: Primary database
โ”œโ”€ max_connections: 500 (declared, actual)
โ”œโ”€ shared_buffers: 4GB (declared, actual)
โ”œโ”€ effective_cache_size: 12GB (declared, actual)

Server 2: Replica 1
โ”œโ”€ max_connections: 500 (declared, actual)
โ”œโ”€ shared_buffers: 4GB (declared, actual)
โ”œโ”€ effective_cache_size: 12GB (declared, actual)

Server 3: Replica 2
โ”œโ”€ max_connections: 500 (declared)
โ”œโ”€ shared_buffers: 4GB (declared)
โ”œโ”€ effective_cache_size: 12GB (declared)
โ””โ”€ ACTUAL: max_connections 300, shared_buffers 2GB, effective_cache_size 6GB (vendor patch applied, reset defaults)

Drift Detection:
โ”œโ”€ Compares actual to declared for each server
โ”œโ”€ Server 1: No drift
โ”œโ”€ Server 2: No drift
โ”œโ”€ Server 3: THREE PARAMETER DRIFTS
โ”œโ”€ max_connections: 300 vs. 500 (16% underprovisioned)
โ”œโ”€ shared_buffers: 2GB vs. 4GB (50% underprovisioned)
โ”œโ”€ effective_cache_size: 6GB vs. 12GB (50% underprovisioned)

Root Cause Analysis:
โ”œโ”€ Drift happened 3 hours ago (detected via timestamp)
โ”œโ”€ Service: Postgres package auto-update from 13.x โ†’ 14.x
โ”œโ”€ Auto-update includes config reset to defaults
โ”œโ”€ Replica 2 was updated; Replicas 1 and 2 were not (stale, needs manual update or automation)

Impact Assessment:
โ”œโ”€ Replica 2 is running with half the declared resources
โ”œโ”€ Replication lag is increasing (seen in monitoring)
โ”œโ”€ Reads from Replica 2 are slow (less cache, less buffer)

Remediation:
โ”œโ”€ Option 1: Revert to baseline (restore tuned config from backup config)
โ”œโ”€ Option 2: Update IaC to match actual (accept default config, retune application)
โ”œโ”€ Option 3: Re-apply tuned config manually, then update automation to prevent auto-reset
โ”œโ”€ Recommended: Option 3 (restore config + fix automation)

Action: Restore config to Replica 2, then update package auto-update policy to preserve custom postgresql.conf

Example 3: Compliance Drift Report (CIS Benchmark)

Compliance Framework: CIS Benchmark for Linux v1.0.0

Baseline Requirements:
โ”œโ”€ 1.1.1: Disable unused filesystems (cramfs, freevxfs, jffs2, hfs, hfsplus, etc.)
โ”œโ”€ 1.3.1: Ensure mounting of ext4 filesystems includes nodev option
โ”œโ”€ 2.2.1: Ensure telnet client is not installed
โ”œโ”€ 5.1.1: Ensure cron daemon is enabled
โ”œโ”€ 5.2.1: Ensure SSH is set to loglevel INFO
โ””โ”€ ... (50+ more baseline items)

Scan Results (100 servers in production):

Server 1 (app-01):
โ”œโ”€ CIS 1.1.1: PASS (unused filesystems disabled)
โ”œโ”€ CIS 1.3.1: PASS (nodev option set)
โ”œโ”€ CIS 2.2.1: PASS (telnet not installed)
โ”œโ”€ CIS 5.1.1: PASS (cron enabled)
โ”œโ”€ CIS 5.2.1: FAIL (SSH loglevel is VERBOSE, expected INFO)
โ”œโ”€ Overall: 49/50 items pass

Server 2 (db-01):
โ”œโ”€ CIS 1.1.1: PASS
โ”œโ”€ ... (all pass)
โ”œโ”€ Overall: 50/50 items pass

...

Server 50 (cache-01):
โ”œโ”€ CIS 2.2.1: FAIL (telnet client is installed)
โ”œโ”€ Overall: 49/50 items pass

Aggregate Drift Report:
โ”œโ”€ Servers fully compliant (50/50): 96 servers (96%)
โ”œโ”€ Servers with 1 failure: 4 servers (4%)
โ”œโ”€ Servers with 2+ failures: 0 servers (0%)
โ”œโ”€ Total compliance rate: 99.8% (499/500 items)

Critical Failures:
โ”œโ”€ Server db-02: CIS 5.2.1 (SSH loglevel VERBOSE) - Security risk (logs insufficient)
โ”œโ”€ Server cache-01: CIS 2.2.1 (telnet installed) - Security risk (unencrypted telnet)

Remediation:
โ”œโ”€ Critical failures must be fixed within 7 days per policy
โ”œโ”€ Recommend automated remediation via Ansible:
โ”œโ”€ db-02: ssh_loglevel=INFO in sshd_config
โ”œโ”€ cache-01: apt remove telnet
โ””โ”€ Re-scan after fixes, confirm compliance

Compliance Report Output:
โ”œโ”€ Compliance status: 99.8% (2 failures out of 500 items across 100 servers)
โ”œโ”€ Remediation deadline: 7 days
โ”œโ”€ Trend: Last month 99.5%, this month 99.8% (improving)

Anti-Patterns

Anti-Pattern 1: Comparing Raw State Without Normalization

Team builds drift detection that compares raw configuration files. Server 1's config is:

max_connections = 500
shared_buffers = 4096 MB

Server 2's config is:

shared_buffers = 4 GB
max_connections=500

Naive comparison sees different formatting (4 GB vs. 4096 MB) and flags false drift. The values are identical (4 GB = 4096 MB), but the representation differs.

Fix: Normalize configuration values before comparing. Convert all sizes to a standard unit (MB), all booleans to true/false, all IP addresses to a standard format.

Anti-Pattern 2: Ignoring Generated/Dynamic Values

Configuration file includes an auto-generated UUID:

instance_id: i-0a1b2c3d4e5f6a7b8 (generated at boot)

Drift detection compares this every boot, sees the UUID changes, flags false drift.

Fix: Identify generated and dynamic values (UUIDs, timestamps, auto-generated IDs). Exclude them from comparison.

Anti-Pattern 3: Alerting on Harmless Drift

File modification time drifts (changes whenever anyone touches the file). Temporary file sizes drift (cache files grow/shrink). Drift detector fires 100 alerts per day on harmless changes. Ops team ignores all alerts (alert fatigue). Real drift gets lost in the noise.

Fix: Classify drift by significance. Alert only on meaningful drift (configuration parameters, security settings). Ignore harmless drift (timestamps, cache sizes). Use different alert levels (critical, warning, info).

Anti-Pattern 4: Manual Drift Remediation at Scale

Drift is detected on 50 servers. Ops team plans to manually SSH into each server and fix it. 50 servers ร— 15 minutes per server = 12.5 hours of work. Error-prone (typos, missed servers).

Fix: Use automated remediation for non-critical drift. Approve the fix once, apply to all 50 servers in parallel.

Anti-Pattern 5: Not Tracking Why Drift Happened

Drift is detected and reverted, but the root cause is never investigated. A week later, the same drift appears again on the same server.

Fix: For every remediation, investigate root cause. Is it a buggy automation script? A vendor patch that resets configs? A manual change by an engineer who forgot to update IaC? Fix the root cause, not just the symptom.

Human Judgment Checkpoints


  • Have you defined what "baseline" means for your environment? Is it your IaC, a snapshot from a known-good state, or the CIS benchmark? Be explicit.

  • Have you classified drift by significance? Before alerting, distinguish meaningful drift from noise. Configure your system to ignore harmless drift.

  • Does your remediation process account for human decision-making? Drift detection should recommend remediation options, not auto-fix everything. Ops should decide which option to take.

  • Are you integrating compliance frameworks into your drift detection? Map your configuration baseline to CIS, PCI-DSS, HIPAA, or whatever standards apply to your environment.

  • Have you tested drift detection on your actual infrastructure? Run it against 10% of your environment, see what false positives emerge. Tune classification before rolling out to 100%.

  • Is drift detection performance acceptable? Comparing 10,000 configuration parameters every hour across 100 servers should be fast. Use hash-based comparison and lazy evaluation to avoid timeouts.

Key Takeaways


  • Continuous drift detection beats manual quarterly audits: Compare actual state to baseline hourly, not quarterly. Catch drift when it's small, before it causes problems.

  • Classify drift by significance: Distinguish meaningful configuration changes from harmless noise (timestamps, cache contents). Alert only on meaningful drift.

  • Separate declaration, deployment, and actual state: Compare across all three dimensions. IaC matches deployment, but does deployment match actual infrastructure?

  • Capture baselines carefully: Use known-good states, version your baselines, document assumptions. A corrupted baseline ruins all subsequent drift detection.

  • Remediation is a human decision: Detect drift and recommend remediation options (revert, update IaC, acknowledge, investigate). Let ops decide the right course.

  • Integrate compliance frameworks: Map configuration drift to CIS benchmarks, PCI-DSS, HIPAA, or other standards. Detect compliance violations early.

  • Automate non-critical remediation: For low-risk drift (package versions, routine config updates), automate reversion. For high-risk drift (security settings, permissions), require manual approval.

  • Investigate root causes: When drift is found, ask why it happened. Fix the root cause (broken automation, vendor patches, manual processes) not just the symptom.

  • Version your baselines like code: Changes to baseline are tracked, approved, and audited. You can roll back a bad baseline change.

  • Measure drift trends: Over time, is drift increasing, decreasing, or stable? Increasing drift suggests broken infrastructure processes. Use this metric to improve.