
In this podcast, CEO and co-founder Ohad Maislish discusses a number of topics with Gordon Haff:
- Enabling developers
- Why many organizations don't want to be tied to a single public cloud,
- Challenges in hybrid cloud and multi-cloud environments,
- The open source Terratag project
Related Content

Today we're launching the env zero Free Tier, a free-forever plan that gives platform teams the full env zero orchestration experience rather than a locked-down demo of it. If you've been waiting for a way to try real IaC orchestration on your own terms, this is your front door.
Why we built the env zero Free Tier
Platform engineering is a bottom-up discipline. You don't adopt a new IaC platform because someone signed a contract. You adopt it because you spun it up on a Friday, pointed it at a repo, and saw it solve the orchestration and self-service problems you live with every day.
For too long, trying env zero meant talking to us first, and that's the wrong answer to "I just want to see if this works for my team." So we changed it. The Free Tier is self-serve from the first click. Create an org, connect your VCS, and run.
With the IaC landscape shifting and long-standing free options disappearing, a lot of teams are re-evaluating how they orchestrate Terraform and OpenTofu right now. We wanted env zero to be the obvious place to land. We looked hard at the competitive landscape and sought to include a feature and entitlements set that would make env zero the superior option.
Who it's for
The Free Tier is built for the platform engineer standing up self-service infrastructure for their org, whether that's a solo practitioner proving out a workflow or a small platform team giving developers a paved road to deploy on.
It's a fit if you want to:
- Give your developers self-service environments without handing them the keys to production
- Run drift detection against your live infrastructure so state surprises stop being surprises
- Wire in SSO and bring your whole team in from day one, not just yourself and one teammate
- Orchestrate Terraform and OpenTofu with real guardrails, before you've had a single procurement conversation
What you get
The Free Tier ships with the complete env zero Navigator feature set. We took the position early that a paying customer should never receive less than a free user does, so instead of carving out a feature-limited "lite" plan, we gave the free tier the full product and set generous usage limits around it.
| Price | $0, in perpetuity |
|---|---|
| Runs | 250 / month |
| Environments | Up to 30 |
| Deploying users | Unlimited, humans and agents |
| Features | Full Navigator feature set, including drift detection and OIDC SSO |
| Support | Community support |
A few things worth spelling out for the way platform teams actually work:
A "run" is an outcome. One run equals one successful apply or one drift detection. Plans and failed runs don't burn your monthly allowance, so you're only metered on work that actually happened.
Unlimited users, including agents. There's no per-seat gate and no "invite two people, then pay." Bring your whole platform team and your automation. As IaC pipelines increasingly include non-human actors, we didn't want a seat cap to be the thing that boxed you in.
Drift detection and SSO are included. These are the capabilities teams usually have to upgrade to reach elsewhere. On env zero they're part of the free experience, because they're part of running infrastructure responsibly.
Where the limits are, and what's next
The Free Tier is designed to run real workloads, not just a hello-world. The two dials that define it are 250 runs per month and 30 environments. When your team consistently pushes past those, that's the natural signal you've outgrown free. Our paid tiers, Cloud Navigator and Cloud Pilot, lift those ceilings and add direct support and more advanced capabilities as you scale.
There's no downgrade trap and no bait-and-switch. Free stays free, and the path up is there when you need it and not before.
Get started
You can be deploying in minutes:
- Sign up for env zero. Every new self-serve account lands on the Free Tier automatically.
- Connect your VCS and point env zero at an IaC repo.
- Run your first deployment, turn on drift detection, and invite your team.
No trial countdown. No credit card. No gatekeeper.
FAQ
Is it really free forever? Yes. The Free Tier is $0 in perpetuity. It isn't a promotional rate or a countdown to a paid plan.
Is there a trial? Do I need a credit card? No trial and no credit card. Every new self-serve account lands directly on the Free Tier, so you start on Free from your very first login and stay there. There's no trial period to expire and nothing that quietly downgrades on you later.
What counts as a run? A run is one successful apply or one drift detection. Plans and failed runs don't count against your monthly total, so you're only ever metered on work that completed.
What happens when I hit 250 runs or 30 environments? Those are the two limits that define the Free Tier. When you reach a cap, env zero lets you know and shows you the path to more capacity through Cloud Navigator or Cloud Pilot. Your existing environments and configuration stay intact.
Do I get fewer features on Free than on a paid plan? No. The Free Tier includes the complete Navigator feature set, drift detection and OIDC SSO included. The paid tiers raise your usage limits and add direct support and more advanced capabilities as you scale, rather than unlocking basic functionality.
Can I add my whole team? Yes. Deploying users are unlimited on Free, both human teammates and automation or agents. There's no per-seat charge.
What support is included? Free Tier comes with community support. Direct support is part of the Cloud Navigator and Cloud Pilot tiers. Paid support plans are available for Free Tier users, simply Contact Us.
How do I upgrade when I outgrow Free? When your team consistently pushes past the run or environment limits, you can move up to Cloud Navigator or Cloud Pilot for higher ceilings, direct support, and additional capabilities. Your work carries over.
Introducing the env zero Free Tier: full-featured IaC orchestration, free forever


You run [.code]terraform apply[.code], it fails partway through, and the next command you run refuses to move: [.code]Error acquiring the state lock[.code]. Nothing is broken yet, but nothing will proceed either until the lock is cleared.
This guide covers what [.code]force-unlock[.code] actually does, when it is safe to use, how to find the lock ID on every major backend, and what to do if the command itself does not fix things.
What does terraform force-unlock do?
Terraform locks state before any operation that could write to it. The lock stops two processes from writing to the same state file at once, which is the most common way a state file gets corrupted. Locking happens automatically and silently on every plan and apply where the backend supports it. You will not see a message unless acquiring the lock takes longer than expected.
[.code]force-unlock[.code] is the manual override for when that automatic process gets stuck. It removes the lock record so a new operation can proceed. According to HashiCorp, the command does not modify your infrastructure, and on most backends it does not touch your state data either. It just clears the record that says the state is currently held.
Usage:
terraform force-unlock [options] LOCK_ID
The only option is [.code]-force[.code], which skips the yes or no confirmation prompt. That is useful inside a script or CI job where nothing is available to type “yes” into. Otherwise leave it off, since the confirmation step is the last chance to catch a mistake before you unlock something someone else is actively using.
The lock ID is not optional and is not guessable. Terraform prints it in the error message when a lock is already held, and [.code]force-unlock[.code] requires an exact match. Per HashiCorp's own documentation, the ID works as a nonce, a one-time verification token that ensures a lock and an unlock target the same lock. That is deliberate: you can only release a lock you can identify, not just any lock on the state file.
One thing worth flagging up front: on the local backend, a stuck lock can only be cleared by the same machine and user that created it. There is no separate process to force it from elsewhere, which is one more reason most teams move to a remote backend, such as the ones covered in this backend configuration guide, before this becomes a live problem.
When should you use the force-unlock command?
Treat [.code]force-unlock[.code] as a last resort, not a first response. If two operations are genuinely running against the same state at the same time, forcing a lock open defeats the entire purpose of state locking and can leave you with a corrupted state file. Only run it when you are certain the process that created the lock is no longer active.
A stuck lock usually traces back to one of a few causes:
- A [.code]terraform apply[.code] or [.code]plan[.code] was cancelled or errored mid-run, for example because a CI job timed out or someone hit Ctrl+C, so Terraform never reached the step where it releases the lock.
- The machine or build agent running Terraform lost its network connection to the backend before the lock could be released.
- The backend storage itself changed mid-operation, for example a Terraform run modifying firewall rules, private endpoints, or access policies on the very storage account that holds the state file.
If none of those match your situation and you are not sure why the lock exists, treat that as a reason to investigate before clearing it, not a reason to assume it is safe to force.
Where to find the lock ID for every backend
In most cases you will not need to go looking. The lock ID appears directly in the [.code]Error acquiring the state lock[.code] message, under the [.code]ID:[.code] field, alongside who holds it and when it was created. The backend-specific detail below matters mainly when you are troubleshooting secondhand, for example clearing a lock a teammate reported without a fresh error message in front of you.
Local backend
Terraform writes a [.code].terraform.tfstate.lock.info[.code] file next to the state file while an operation is in progress. It is a small JSON object containing the lock [.code]ID[.code], the operation type, and who created it. On clean exit, Terraform deletes this file automatically. As noted above, a lock created by one machine cannot be released by [.code]force-unlock[.code] from a different one.
Amazon S3
As of Terraform 1.11, the S3 backend supports native state locking through the [.code]use_lockfile[.code] argument, and no longer requires a separate DynamoDB table. Setting it to [.code]true[.code] tells Terraform to create a lock object in the same S3 bucket as your state, using conditional writes so only one process can create it at a time.
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
use_lockfile = true
}
}
With native locking, the lock ID is whatever the error message reports; there is no separate table to query. If your configuration still uses the older [.code]dynamodb_table[.code] argument, note that HashiCorp has deprecated it in favor of [.code]use_lockfile[.code]. On that legacy path, the lock lives as an item in the DynamoDB table, keyed by a partition key named [.code]LockID[.code], and you can inspect it directly:
aws dynamodb get-item \
--table-name your-lock-table \
--key '{"LockID": {"S": "your-bucket/path/to/terraform.tfstate"}}'
Azure Blob Storage
Azure Blob Storage implements locking through native blob leases, with no extra backend configuration required. If a run is interrupted mid-apply, the lease can be left in place. The lock ID appears in the error message, but you can also inspect the lease state directly:
az storage blob show \
--account-name YOUR_STORAGE_ACCOUNT \
--container-name YOUR_CONTAINER \
--name path/to/terraform.tfstate \
--query 'properties.lease'
If [.code]force-unlock[.code] is not an option, for example the lock ID is unavailable, you can break the lease directly through the Azure CLI, which achieves the same result at the storage layer:
az storage blob lease break \
--account-name YOUR_STORAGE_ACCOUNT \
--container-name YOUR_CONTAINER \
--blob-name path/to/terraform.tfstate
Google Cloud Storage
The GCS backend also locks natively with zero extra configuration. Terraform writes a lock object at [.code]/.tflock[.code] in the same bucket as your state, and the lock ID is the object's generation number, which is included in the error message. Deleting that object directly is the manual equivalent of [.code]force-unlock[.code] if the CLI command fails for some reason.
HCP Terraform and Terraform Enterprise
This is a common point of confusion: [.code]terraform force-unlock[.code] is a CLI command that works against backends where Terraform itself manages the lock file. HCP Terraform and Terraform Enterprise instead lock and unlock workspaces through their own UI and API, not the CLI command. In the workspace's Actions menu, you can select Lock workspace or Unlock workspace directly, or call the workspaces API endpoint to do the same thing from automation.
Consul
With the Consul backend, lock information lives in the Consul key-value store rather than in a file. You can list it with the [.code]consul kv get [.code] command, or query the same data through Consul's HTTP API.
Using terraform force-unlock: a worked example
- Identify the lock ID from the error message. For example: [.code]Lock Info: ID: b8814894-4a5f-217b-e97b-c4f5c02a1f88[.code].
- Confirm nobody else is running an operation against this state. Check your CI/CD dashboard, ask your team, or check the environment's deployment history if you are running on a platform that centralizes this, before assuming the lock is actually stale.
- Run the command with the ID from step one: [.code]terraform force-unlock b8814894-4a5f-217b-e97b-c4f5c02a1f88[.code]. Confirm the prompt with [.code]yes[.code], or add [.code]-force[.code] if you are running this non-interactively.
- Verify the fix by re-running the command that originally failed, such as [.code]terraform plan[.code]. If it proceeds past the locking step without error, the lock is cleared.
Unlocking remote state: alternatives to force-unlock
Wait instead of forcing: -lock-timeout
If two operations occasionally overlap for a few seconds, for example two CI jobs kicking off close together, [.code]force-unlock[.code] is the wrong tool. The [.code]-lock-timeout[.code] flag tells Terraform to wait for the lock to clear on its own instead of failing immediately:
terraform plan -lock-timeout=5m
This is worth setting as a default in CI pipelines that run plan, apply, or destroy operations back to back, so a brief overlap resolves itself instead of surfacing as a lock error at all.
Manual removal as a last resort
Occasionally [.code]force-unlock[.code] itself fails, usually because the backend is unreachable or credentials cannot reach the lock record. HashiCorp's guide to recovering state from backup covers this scenario directly. In that situation, the remaining options are backend-specific: delete the lock object from S3 or GCS, edit or remove the DynamoDB item, or break the Azure blob lease as shown above. All of these bypass Terraform entirely, so treat them with the same caution as [.code]force-unlock[.code] itself.
Coordinate before you unlock
Whichever method you use, confirm no other process is mid-write before you touch the lock, and consider pulling a backup first with [.code]terraform state pull[.code]. Never use [.code]-lock=false[.code] as a standing workaround for frequent lock errors. It disables the protection entirely rather than resolving whatever is causing the contention.
Troubleshooting force-unlock errors
The lock ID does not match
[.code]force-unlock[.code] will refuse an ID that does not match the current lock. This almost always means you are using a stale ID from an old error message. Re-run the failing command to get the current lock's ID and try again.
Permission errors during force-unlock
Clearing a lock requires write or delete access to wherever the lock record lives, for example [.code]s3:DeleteObject[.code] on the lock object, or the equivalent DynamoDB, GCS, or Azure permission. A permissions error here usually points to the credentials Terraform is running with, not the lock itself.
The same lock error comes back immediately
If you clear a lock and it reappears right away, something is still actively writing to that state. Stop and investigate before unlocking again. This pattern usually means step two of the worked example above was skipped.
Managing state locking at scale with env zero
Clearing a stuck lock by hand does not scale once a platform team is managing hundreds of environments across multiple backends. Ad Hoc Tasks in env zero let you run a command, including [.code]terraform force-unlock -force LOCK_ID[.code], directly on the environment's deployment container from the UI. That means resolving a stuck lock does not require local CLI access, a checked-out copy of the Terraform configuration, or direct credentials to the backend that holds the state.
By default, ad hoc tasks are restricted to organization administrators, since they allow arbitrary commands against a live deployment container. Teams that want to delegate lock-clearing to platform engineers without granting full admin access can do that with a custom role scoped to just that permission.
It is worth distinguishing this from Environment Locking in env zero, which is a separate, deliberate governance control rather than Terraform's automatic state lock. Locking an environment in env zero blocks deploys, destroys, plans, and drift detection outright, with a reason attached for anyone else who looks at it, and it stays in effect until someone with permission unlocks it. A Terraform state lock, by contrast, is transient by design and normally clears itself within seconds. If you are troubleshooting a “locked” environment in env zero and [.code]force-unlock[.code] does not seem relevant, this distinction is usually why.
Key takeaways
- [.code]terraform force-unlock LOCK_ID[.code] manually clears a stuck state lock. It does not touch your infrastructure, and on most backends it does not touch your state data either.
- Only use it when you are certain the process that created the lock is no longer running. Unlocking an active operation risks a corrupted state file.
- The lock ID is usually sitting right in the error message. You only need to hunt through backend-specific tooling when troubleshooting without that message in hand.
- S3 no longer needs DynamoDB for locking. [.code]use_lockfile = true[.code] has been the supported path since Terraform 1.11.
- [.code]-lock-timeout[.code] prevents most stuck-lock situations in CI before they happen, by waiting instead of failing immediately.
Frequently asked questions
Q. How do I fix a Terraform state lock?
Run [.code]terraform force-unlock LOCK_ID[.code], using the ID from the [.code]Error acquiring the state lock[.code] message. Only do this once you are certain no other operation is currently running against the same state.
Q. What is Terraform state locking for?
State locking prevents two operations from writing to the same state file at the same time, which is one of the most common causes of state corruption. Terraform acquires the lock automatically before any operation that could write state and releases it when the operation finishes.
Q. Can force-unlock corrupt my Terraform state?
[.code]force-unlock[.code] itself does not modify your infrastructure or your state data; it only removes the lock record. The risk is indirect: if you unlock a state that another process is actively writing to, that process and yours can both write at once, which can corrupt the state file.
Q. Does the S3 backend still need DynamoDB for state locking?
No. Since Terraform 1.11, the S3 backend supports native locking through [.code]use_lockfile = true[.code], using S3 conditional writes instead of a separate DynamoDB table. The older [.code]dynamodb_table[.code] argument still works but is deprecated.
Q. How do I avoid stuck state locks in the first place?
Avoid cancelling Terraform runs mid-operation, set [.code]-lock-timeout[.code] in CI so brief overlaps wait instead of failing, and use a platform that centralizes deployment history so you can quickly confirm whether a lock is stale before clearing it.
Terraform Force-Unlock: How to Safely Unlock a Locked State File

Hello, env zero fans! As some of you know, we have almost unlimited extensibility with 3rd party tools, using our custom workflows. You can hook in pretty much any tool, in any phase of the deployment. Today, we’re going to talk about how to prevent cloud misconfigurations before they start. We’re going to do this by chaining a tool in the deployment after the terraform plan phase. This is where our friends at Bridgecrew come in. Just like we at env zero have open-sourced the Terratag module of our platform, Bridgecrew has open-sourced Checkov!
Checkov
Checkov is a static code analysis tool for infrastructure-as-code. It scans cloud infrastructure managed in Terraform, Cloudformation, Kubernetes, Arm templates, or Serverless Framework and detects misconfigurations.

Setup
For illustration purposes, we’re going to use Bridgecrew’s demo application called TerraGoat. TerraGoat is Bridgecrew’s “Vulnerable by Design” Terraform repository. TerraGoat is a learning and training project that demonstrates how common configuration errors can find their way into production cloud environments.
DISCLAIMER: DO NOT ACTUALLY DEPLOY THIS APPLICATION INTO YOUR CLOUD INFRASTRUCTURE. IT IS PURPOSELY COMPROMISED.
I have created a template of TerraGoat inside of env zero and linked it to our Bridgecrew Demo project.

The only other thing we have to do is to actually call Checkov to do the check during the deployment. We need to do this after the Terraform plan phase, so that we have a plan to check. Here is what the env0.yml file will look like:
This adds 3 commands that run after the Terraform Plan, and before Terraform Apply. We put it here so that the Apply doesn’t run in case of failures. We don’t want to see the errors after the resources are applied. We want the deployment to fail if there are errors.
This command installs Checkov into our runtime environment using the pip3 package installer so we can run it against our Terraform plan.
This command essentially formats our .tf-plan file into tf.json so that it can be parsed and run against Checkov.
This command has a lot going on and is in 2 parts. First, it quietly executes Checkov against our tf.json (the reformatted tf.plan file) and looks for a 0 exit code. The double pipe || tells bash to only execute the 2nd command if the exit code of the first command is not 0. So if your Checkov results are clear, your deployment gets the 0 exit code and continues on with the deployment.
If not, then the second part of the command runs. Knowing if this part runs, it is because of a failure, we’re just going to format our error message here. We run Checkov again so we can pipe the error with the echoed error notification text to the console. The 1>&2 routs stdout to stderror, and the exit 1 code tells env zero that the stage failed, and to end the deployment run.

The env zero platform will parse the error, and give you the clear error printed on the Environment deployment page. But, if you want the full logs from Checkov, you can find those in the After: Terraform Plan deployment logs.

And that’s it! A little bit of YAML, and you’ve implemented Checkov to protect yourself against the deployment of misconfigured cloud resources. That is instantly added value to your organization by shifting the security left in your deployment process with env0.
You can find more information on Checkov here. You can find the open-source repository on GitHub. And be sure to see how you can automate your infrastructure security from commit to cloud at Bridgecrew.io.
Better Together: Checkov and env0


env zero Extends Workflow Platform for Provisioning Infrastructure


Troy Knapp
Senior DevOps Engineery
| The Challenge: |
|---|
|
| The Solution: |
|
| The Impact: |
|
Background
Zip Co Limited (abbreviated as Zip Co) is a global 'buy now pay later' financial technology company with operations in Australia, New Zealand, and the USA used by millions of customers to handle billions of dollars in annual transactions.
The Challenge
Before using env0, ZipCo utilized a monolithic Terraform repository and a rigid tool that functioned similarly to a conventional Git workflow, involving numerous pull requests from the master branch.
This resulted in a cumbersome process that ended up locking out any other developer from making changes.
Moreover, for change, the propagation occurred linearly, where each environment would update one by one, further lengthening the time to deploy.
As a result, it wasn’t uncommon for a simple change to take multiple hours to deploy, during which the codebase was locked, preventing anyone else from working on it.
The Solution
- Parallel Deployments: Before env0, ZipCo would have to deploy their code linearly. After moving to env0, multiple environments could now be deployed simultaneously.
- Robust UI: The interface env zero provides has given each developer a deeper insight in a much more organized fashion that doesn't rely on local code execution. The interface is also much easier to understand, well documented, and has fewer clicks than their previous solution.
The Impact
- Time to Deploy Cut by 50% - Simultaneous environment deployments have drastically reduced deployment times, thereby optimizing the development cycle and saving valuable time for the company.
- Transparency and Accountability - By exposing "tribal knowledge" and eliminating hidden shortcuts and backdoors, all team members now have a clear understanding of the deployment environments, fostering a culture of openness and accountability.
- Streamlined Operations - The UI simplifies the deployment process, requires fewer steps compared to previous solutions, and is more intuitive. This improvement has enhanced productivity.
- Shortening Issue Resolution - Using env zero drift detection and logging capabilities, issues could be identified and resolved quicker, within hours rather than days or weeks.
What’s Next
There are still daily challenges ZipCo faces as they continue to integrate their worldwide Azure solution with env0. As each challenge presents itself, the flexibility of env zero coupled with the newfound agility gives ZipCo multiple paths to solve issues they traditionally saw as not reasonably achievable.
ZipCo Doubles Deployment Velocity via Unlimited Concurrency


