We’ve got a CI/CD pipeline where GitHub Actions runs terraform plan on PRs and apply on merge to main. The plan step works fine, but the apply step fails with a state lock error claiming the plan run hasn’t finished. The backend is S3 with DynamoDB locking. Is there a race condition in how the provider handles the lock release? Here’s the workflow config:
- run: terraform apply -auto-approve
It seems like the lock isn’t clearing.
Docs state: “The Terraform provider uses the AWS SDK to manage DynamoDB locks for state consistency.” You’re hitting a race condition because terraform plan acquires a lock to read the state, but if the step times out or fails silently before releasing it, that lock remains active. The subsequent apply sees the lock and aborts. It’s not a provider bug. It’s a workflow configuration issue.
You need to ensure the lock is released even if the plan step fails. Add a post step to your GitHub Actions workflow to force unlock if necessary, or better yet, ensure the plan step completes cleanly. Here’s a pattern that works:
- name: Terraform Plan
id: plan
run: terraform plan -out=tfplan
continue-on-error: true
- name: Terraform Apply
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: terraform apply -auto-approve tfplan
If you still see locks, check your DynamoDB table for stale entries with LockInfo containing a who field that matches your runner ID. You can delete them manually via the AWS console if they’re truly orphaned. The SDK handles lock acquisition and release automatically, but it doesn’t clean up after abrupt terminations.