A crashed run or killed CI job leaves the state lock held. The safe fix takes 30 seconds once you confirm nothing is actually running.
CI job killed mid-apply, laptop slept, Ctrl-C at the wrong moment. The lock never released.
Two pipelines ran at once and one holds the lock legitimately.
ps aux | grep terraform; # plus check your CI dashboard
terraform force-unlock <LOCK_ID>
terraform plan -detailed-exitcode
Force-unlocking while another apply is genuinely in progress can corrupt state. The 60 seconds spent verifying nothing is running is the whole safety margin.
First verify nobody is actually running an operation (check your team and CI): force-unlock after confirming the holder crashed. terraform force-unlock <lock-id> — the ID is in the error output. Force-unlocking an active run corrupts concurrent state writes.
A crashed runner (SIGKILL'd CI job) leaves the lock behind each run. Fix the crash-and-kill pattern — failed runs should exit, not be force-killed at the job level — or add a lock-cleanup step with verification to the pipeline.
An opinionated VPC module: per-AZ NAT, explicit dependencies, EKS-ready outputs.
Terraform AWS Foundation — $37 →One-time. Yours to modify. Instant download from the NinjaOps template store.