Migrate from HCP Terraform to Atlantis: what the move involves
Atlantis replaces the run and plan-approval path that a team uses in HCP Terraform when infrastructure changes are reviewed in pull requests, but it does not replace the private registry or a workspace UI, so those need a separate decision. The state backend must be external because Atlantis cannot use local state: it has no permanent storage and does not commit state files back to version control. Before any workspace moves, choose a remote backend such as S3 or GCS and confirm that the platform team can grant Atlantis access to it, its locks and its encryption keys.
The work is usually done by a platform or DevOps team that already owns the repositories, cloud accounts and CI credentials, sometimes with an implementation partner for the initial deployment and hardening. Atlantis is licensed under Apache 2.0 and is deployed as a standalone application in your own infrastructure, with the deployment documentation listing Kubernetes Helm charts, Kustomize, Docker and several cloud options. Effort depends mainly on the number of workspaces, how modules and environments are laid out, and the state backend you choose. Each workspace needs a matching entry in atlantis.yaml, and each must be checked after its state is moved.
Running OpenTofu instead of Terraform is a separate step. Atlantis documents a custom workflow in which the tofu binary is installed in an init container and ATLANTIS_TF_DOWNLOAD is set to false, as described in the Atlantis blog on integrating Atlantis with OpenTofu. Confirm the OpenTofu version your configurations need, pin it, and test one non-production directory before changing the rest. When requesting a quote, ask the partner to list the workspaces, modules, state backends and version pins in scope so the estimate reflects your actual layout.
Which HCP Terraform capabilities map to Atlantis and which need rework
This table compares the main HCP Terraform capabilities with what Atlantis provides, marking each as clean, needs rework or gap. Read it as a checklist: a clean row means Atlantis covers the behavior with configuration, rework means you must rebuild a practice or pipeline, and gap means a function you must supply elsewhere or accept losing. Confirm the items marked for your environment before you commit to a cutover date.
| Capability | HCP Terraform | Atlantis with OpenTofu | Status |
|---|---|---|---|
| Plan and apply | Remote runs execute plan and apply in HashiCorp-managed workers with run history in the UI | Commenting atlantis plan and atlantis apply on a pull request runs the commands in your infrastructure and posts output back | Clean |
| VCS-triggered runs | Workspaces connect to a VCS repository and trigger runs on commits and pull requests | Pull request webhooks trigger plans for changed directories; atlantis.yaml defines projects and workspaces | Needs rework |
| Variables and secrets | Workspace variables, variable sets and sensitive values are stored in the platform | Variables move to tfvars files, environment variables set on the Atlantis deployment, or your secrets manager; sensitive values need a new home | Needs rework |
| State storage | Managed remote state with state versions and locking per workspace | Requires a remote backend such as S3 or GCS; local state is not supported, so each workspace's state must be migrated first | Needs rework |
| Locking | Workspace-level locks managed by the platform | Directory or workspace locks held until the pull request is merged or the lock is deleted | Clean |
| Team access and permissions | Teams, workspace permissions and organization roles in the UI | Access comes from repository permissions and the Git host; Atlantis has no workspace-level team model of its own | Gap |
| Private registry | Built-in private module and provider registry | Atlantis does not provide a registry; modules move to Git sources, an object store or another registry you operate | Gap |
| Policy checks | Sentinel or OPA policy checks in the run lifecycle | Policy must run as a custom workflow step, such as conftest on the plan output, with approval rules set in the Git host | Needs rework |
| Run UI and audit history | Hosted run list, logs, workspace views and notifications | Output lives in pull request comments and Atlantis logs; any dashboard, retention or audit trail must come from your logging stack | Gap |
What state, variables and VCS links must move, and how state leaves HCP Terraform
Moving from HCP Terraform runs to Atlantis is mostly a state problem plus a re-creation problem. State is the only object you can export in bulk, while variables, workspace settings and VCS connections must be rebuilt in your repository and Atlantis server. Work through the cards in order so no workspace is cut over with state, secrets or triggers missing.
Download current state through the API
The state versions API exposes each workspace's current state, and for states created by Terraform 1.3 or later it offers a JSON download URL. Use the JSON form as your primary export because it is easier to inspect and validate than raw state. Pull the state for every workspace before you change any backend, and record the serial and lineage so you can confirm the copy matches what HCP Terraform held at cutover. Keep the export in an encrypted, access-controlled location, since state can contain sensitive values.
Use raw state only as a fallback
The API also offers a raw state download. Use it when a workspace's state was created before Terraform 1.3 and has no JSON form, or when you need the exact bytes for a restore comparison. Raw state is harder to review by hand, so validate it with tofu show -json after import. Do not mix the two formats for one workspace without recording which copy is authoritative.
Re-create variables outside the repository
HCP Terraform variables, including sensitive ones and environment variables, are not exported. Re-create them in the places Atlantis reads from: *.tfvars files for non-sensitive values, and your secrets manager or the Atlantis server environment for credentials. Be explicit about which values were marked sensitive in HCP Terraform, because those must not land in committed files. Confirm each workspace's variable list against a written inventory before the first atlantis plan.
Rebuild workspaces and layout in atlantis.yaml
Workspace names, module directories and custom tfvars layouts from HCP Terraform have no direct equivalent in Atlantis. Declare each project, its directory, workspace and any terraform_version in an atlantis.yaml file at the repository root. This file becomes the source of truth for which directories Atlantis plans, so an omitted project will silently stop being planned. Review the file in a pull request before enabling automatic planning on the repository.
Recreate VCS links as webhooks and server config
HCP Terraform's VCS connection does not move. In Atlantis, the equivalent is a webhook from your Git host to the Atlantis URL, a token or app credential that lets Atlantis comment and set status, and the server configuration that defines repository allow lists. Test the webhook with a no-op pull request, then confirm that atlantis plan and atlantis apply respond only from the repositories you intended. Document who owns the Git host credential, since rotating it breaks every project at once.
Check terraform_remote_state consumers first
The OpenTofu migration guide warns that configurations sharing data through the terraform_remote_state data source need additional care during migration, and links a separate guide for that case. Before cutting over a producer workspace, list every consumer that reads its outputs and confirm where their backend points after the move. A producer that moves its state to a new backend without updating its consumers will break those consumers on their next plan. Plan the cutover so producers and consumers move in a defined order.
How to sequence the cutover from HCP Terraform runs to pull requests
This sequence moves each workspace from HCP Terraform runs to Atlantis pull request automation without losing state or changing infrastructure unexpectedly. Each step closes with a check the team must pass before the next one starts.
Inventory every workspace and its state
The platform owner lists every HCP Terraform workspace, its working directory, its Terraform or OpenTofu version, its variables, its VCS link and any teams or run triggers that depend on it. Include workspaces that are rarely changed, because they are the ones most likely to be forgotten. The inventory is complete when every workspace maps to a repository path and a named owner, and the team has confirmed which workspaces hold state that other configurations read through terraform_remote_state, since OpenTofu's migration guide flags that pattern for extra care.
Select and provision the state backend
Choose a remote backend that Atlantis supports, such as Amazon S3 or Google Cloud Storage, and provision it in the account or project you control, with locking and access controls set according to your own security baseline. Atlantis cannot use local state because it has no permanent storage, so this decision blocks every later step. The output is a backend configuration reviewed by security and a test state file written and read by the platform team from an isolated path.
Pilot one non-production directory
Pick one low-risk, non-production directory with a small resource count. Write its atlantis.yaml entry, deploy Atlantis in your infrastructure, and connect it to the repository host through a webhook and a dedicated bot identity. Pull the state for that workspace through the HCP Terraform state versions API, verify its checksum, and push it to the new backend. Run plan from a pull request and confirm that the plan shows no changes. The pilot is done when a no-change plan is posted as a comment and the team has run a deliberate small change through apply and merge.
Run plan-only comments in parallel
Keep HCP Terraform as the system that applies changes while Atlantis runs in plan-only mode on pull requests for the remaining workspaces. Reviewers compare the Atlantis plan output with the plan HCP Terraform produces for the same commit. Investigate every difference, including provider versions, variable values and workspace-level settings that did not transfer. The check is passed when plans match for each workspace over a set of representative changes and every mismatch has a recorded cause and fix.
Freeze HCP runs and move state
Schedule a change window with the owners of each workspace. Disable VCS-triggered and manual runs in HCP Terraform so nothing writes new state during the move, then download the final state for each workspace and upload it to the new backend. Confirm the serial and lineage match the source, and run a no-change plan in Atlantis before anyone is allowed to apply. The step is complete when every workspace plans cleanly against the new backend and the freeze is lifted for Atlantis only.
Switch the workflow and apply through Atlantis
Enable apply through pull request comments for each migrated directory, and set branch protection so changes merge only after review. If the team is moving to OpenTofu, install the tofu binary in the Atlantis container and set ATLANTIS_TF_DOWNLOAD to false, as described in the Atlantis OpenTofu post, and confirm that the plan output matches the earlier Terraform output or document the intended differences. The check is that a real change is applied from a pull request, the lock is released on merge, and the apply output is recorded.
Decommission HCP Terraform after verification
Keep the HCP Terraform organization read-only for a retention period set by your records and audit policy, and archive the exported state, variables and workspace settings in storage you control. Remove VCS links and webhooks, revoke API tokens and team access, and update documentation and runbooks. Confirm with finance and procurement that the subscription or Free plan usage is closed, since the vendor's billing terms govern that step. Decommissioning is complete when no workspace is still executing, the archive has been checked, and the access review is signed off.
How Atlantis locks directories and applies changes from pull requests
Atlantis turns the pull request into the place where an infrastructure change is planned, reviewed and applied. Atlantis listens for pull request webhooks, runs terraform plan for the affected directory or workspace, and posts the output back as a comment. When a reviewer comments atlantis apply, Atlantis runs the apply and posts that output to the same pull request. The directory or workspace stays locked until the pull request is merged or someone deletes the lock, so a second pull request cannot change the same state in the meantime. Confirm during your pilot how your Atlantis version handles a lock left behind by a closed pull request, and who on your platform team is allowed to delete locks.
This differs from a hosted run UI. In HCP Terraform, reviewers usually open a run page that shows the plan, the policy results, the cost estimate, the confirmation step and the run history for each workspace. With Atlantis, the review record is the pull request itself: the plan text, the apply text, the approvals and the commit history sit together in the version control system. Reviewers who depend on a workspace dashboard or on run history across many workspaces will need to find that information elsewhere, for example in the pull request history, your CI logs or your own reporting. Decide before cutover which of those views your reviewers and auditors need, and test that each one can be reconstructed from the Atlantis output.
The practical consequence is that review discipline moves into the pull request. Approval rules, branch protection and who may comment atlantis apply must be set in your version control platform and checked against your change policy, because Atlantis will act on any command its configuration allows. Run a test change through a non-production directory, confirm that the plan comment matches what the apply later does, and record how the lock is released after a merge. Those checks show whether the review path you rely on today has an equivalent in Atlantis.
How the migration changes by starting point and team size
Large estates usually have many HCP Terraform workspaces, shared modules and several environments per product. In Atlantis, each of those becomes a project entry in atlantis.yaml, so the file grows with the number of directories, workspaces and tfvars files you need to map. Cutover is best done in waves, grouping workspaces by owner or blast radius, so that each wave has its own state migration, lock check and rollback plan.
- Project inventory: List every workspace with its directory, backend key, variables and dependent modules before writing any configuration.
- Generated configuration: Consider generating
atlantis.yamlfrom that inventory so new projects follow the same pattern and reviews stay consistent. - Module change detection: Map which projects depend on shared modules so a module change triggers plans in every affected directory.
- Wave-based cutover: Migrate low-risk workspaces first and keep HCP Terraform as a fallback for each wave until its state is verified.
- Lock ownership: Agree who releases stuck directory locks, since many projects increase the chance of blocked pull requests.
Confirm with your own environment how many projects one Atlantis instance will serve before you size the deployment.",
A small team with one repository and a few environments, such as development, staging and production, has a simpler mapping. The atlantis.yaml file can be short, often one project per environment directory, and the main risk is the production cutover rather than configuration volume. The migration touches fewer states, so one cutover window and one verification pass may cover everything.
- Short configuration: Define one project per environment with its own workspace or backend key and keep the file easy to review.
- Production last: Move non-production environments first so the team learns the plan and apply comment flow before production changes.
- Single state backend decision: Choose the S3 or GCS backend once and reuse the same bucket layout across environments.
- Approval habits: Agree which reviewers must approve before
atlantis applyis commented on production pull requests. - Parallel running: Keep HCP Terraform read-only for a short period so plans from both systems can be compared before the old workspaces are retired.
Check that your team can run a full plan and apply on a non-production environment end to end before scheduling the production change.
Teams that run HCP Terraform from a version control connection already plan on pull requests, so the workflow is familiar. The change is mostly in where the plan and apply run and who holds the state. Atlantis takes over the webhook, plan comments and apply commands, so the existing VCS connection is replaced by a webhook to your own Atlantis deployment.
- Webhook replacement: Point the repository webhooks at Atlantis and remove the HCP Terraform VCS connection only after both are tested.
- Trigger parity: Check which HCP Terraform trigger rules, such as working directory filters, have equivalents in
atlantis.yamlautoplan settings. - Run history: Plan the loss of the hosted run UI and decide where apply logs and audit records will be kept.
- Variable sources: Re-create workspace variables as environment variables, tfvars files or secrets in your own store.
- Team access: Map HCP Terraform teams to repository permissions and Atlantis approval rules.
Confirm with your VCS platform which of the supported providers your team uses and how its webhooks and permissions will be configured.
Teams that run tofu or terraform from laptops or CI jobs against HCP Terraform, with the cloud block or remote backend, have no pull request flow to preserve. Moving to Atlantis introduces a new review step, so the team must agree that changes go through pull requests and that local applies stop. The state migration is the same, but the operating habits change more than the configuration does.
- Backend change: Replace the
cloudblock with a supported state backend such as S3 or GCS, since Atlantis cannot use local state. - Local apply retirement: Remove the credentials that allow local applies to production once pull request applies work.
- Emergency path: Document how a break-glass change is made and recorded when Atlantis is unavailable.
- Credential scope: Give the Atlantis service identity only the permissions each project needs, instead of the personal credentials used at the CLI.
- Training: Run a short session on commenting
atlantis planandatlantis applyso engineers do not bypass the flow.
Check with your security team how the Atlantis service identity will be authenticated to each cloud account before any state is moved.
What drives the cost and duration of this migration
This table lists the drivers that change the cost and effort of moving from HCP Terraform to Atlantis, with why each matters and how to keep it down. Read it before requesting a quote, since the same workspace count can produce very different work depending on state backend setup, VCS footprint and approval rules.
| Driver | Why it changes cost or effort | How to keep it down |
|---|---|---|
| Workspace and state count | Each HCP Terraform workspace needs its state downloaded, verified and written to the new backend, and each one needs an atlantis.yaml project entry. | Group related workspaces by repository and migrate low-risk ones first. Confirm the count with an inventory export before scoping. |
| Module and cross-state dependencies | Configurations that read outputs through terraform_remote_state need coordinated cutover, since OpenTofu's migration guidance flags this case for extra care. | Map every remote state reference before migration and move producers before consumers. |
| State backend setup and access controls | Atlantis cannot use local state, so an S3 or GCS backend, its locking, bucket policies, encryption and per-project IAM must exist first. | Reuse an existing bucket and key layout where your standards allow. Ask the provider to state which access model it assumes. |
| Custom OpenTofu workflow | Running tofu instead of terraform means a custom workflow, an init container for the binary and ATLANTIS_TF_DOWNLOAD set to false, plus testing of each command path. | Pin one OpenTofu version across repositories first. Ask whether the quote covers workflow testing on a non-production repo. |
| Number of VCS providers | Atlantis supports GitHub, GitLab, Gitea and compatible forks, Bitbucket Cloud and Server and Azure DevOps. Each provider adds its own webhook, token and permission setup. | Consolidate repositories onto one provider where possible. Confirm which providers are in scope in the written statement of work. |
| Approval and policy requirements | Required approvals, policy checks such as conftest on plans, and rules for who may run apply each add configuration and testing work. | Document current HCP Terraform approval rules first and map them one to one. Ask for policy work to be a separate line item. |
| Kubernetes or container platform experience | Atlantis is deployed in your infrastructure through Helm, manifests, Fargate, GKE, OpenShift or Docker. Gaps in platform skills push effort into setup and ongoing operation. | Identify the platform owner and the deployment target before scoping. Ask who will operate upgrades after handover. |
| Cost component: Atlantis hosting and state storage | Recurring. You pay your cloud or cluster for the Atlantis workload, storage, versioning and logs. Atlantis itself is Apache 2.0 licensed. | Right-size the workload and set state bucket lifecycle and versioning deliberately. Ask for the expected resource list in the quote. |
| Cost component: setup labor and ongoing operation | One-time for design, migration and cutover. Recurring for upgrades, backups, access reviews and on-call. Quotes should separate these. | Ask for fixed scope for setup and a separate, optional retainer for operation. Confirm who holds the on-call duty after handover. |
What usually goes wrong when teams move to Atlantis
Most failed Atlantis cutovers come from state, not from the pull request workflow. The risks below connect because they all depend on which system owns each workspace's state at every moment, and on whether the team knows what the Atlantis server can reach.
Attempting local state
Atlantis cannot run against local state because it has no permanent storage and does not commit state files back to version control. A team that keeps a workspace on a local terraform.tfstate will see plans that look fine and then lose the state after the server restarts. Before the first pull request, confirm that every root module declares a supported remote backend such as S3 or GCS, and that the backend locks and versions state.
State drift after partial cutover
Moving workspaces one at a time leaves some in HCP Terraform and some in Atlantis. If a workspace is migrated but a teammate still runs apply from a laptop against the old state, the two copies diverge and the next plan proposes changes that undo recent work. Record the cutover date per workspace, freeze runs in HCP Terraform before downloading state, and run a no-change plan in Atlantis to confirm the state matches the infrastructure.
Missing terraform_remote_state dependencies
Configurations that read outputs through the terraform_remote_state data source depend on the state location of another workspace. If that upstream workspace moves, or its state path changes, downstream plans fail or read stale values. OpenTofu's migration guidance flags this case for extra care. Map every terraform_remote_state reference in your code, migrate upstream stacks first, and update each reference to the new backend in the same change set.
Running both systems against the same state
If HCP Terraform and Atlantis both point at one state object, each system can hold its own lock logic and write conflicting versions. Atlantis locks a directory or workspace only within its own pull request flow, so it cannot see a run started in HCP Terraform. Switch the backend configuration in code and in the remote workspace settings in one controlled step, then disable the HCP Terraform workspace's ability to run so no parallel path remains.
Lock conflicts from stale pull requests
Atlantis locks a directory or workspace until the pull request is merged or the lock is deleted. An abandoned pull request can therefore block every later change to that stack, and teams often discover this during an urgent fix. Set a rule that plans are discarded when a pull request closes without merging, document who may delete a lock, and check the lock list before scheduling a migration window.
Unreviewed credentials on the Atlantis server
The Atlantis server runs plan and apply with cloud credentials and reads secrets from its environment, so it becomes a high-value target. Migration often copies HCP Terraform variables into server config or a Helm values file without review. Keep credentials in a dedicated secrets store, scope the server role to the accounts each repository manages, restrict who can comment apply, and review every variable you re-create before the first production run.
Assuming full OpenTofu feature parity
OpenTofu aims to keep feature parity with Terraform, but its FAQ says compatibility with future Terraform releases is not guaranteed. A team that migrates to OpenTofu and assumes every Terraform feature will follow may face surprises on later upgrades. Pin the OpenTofu version in the custom workflow, test each upgrade in a non-production repository, and track which provider and module features your code actually uses.
Questions teams ask before moving from HCP Terraform to Atlantis
How long does a move from HCP Terraform to Atlantis take?
No fixed duration can be given here, because the time depends on how many workspaces you run, how many state files you must move, and how many modules and pipelines reference them. Teams with a small number of workspaces and clean module layouts usually finish faster than teams with shared state through terraform_remote_state, many VCS-linked workspaces, or policy checks that must be rebuilt. Ask for a timeline in the written scope, and confirm the workspace count and state sizes in your own environment before agreeing to one.
What does our team need to provide before migration starts?
The team needs an inventory of every HCP Terraform workspace, its current state, its variables, its VCS links and the modules it uses. You also need a target state backend that Atlantis can use, such as S3 or GCS, with access controls and locking set up, plus a Git provider that Atlantis supports, a place to run the Atlantis service, and named owners who can approve plans and applies. Someone must also decide how credentials for cloud accounts will be supplied to Atlantis.
Can our own platform team do this migration without outside help?
A capable platform team can move workspaces itself, provided it has experience with Terraform or OpenTofu, the target cloud's state storage and the pull request workflow it intends to use. The work that tends to take the longest is not the file changes but the review of each workspace's state, the rewrite of atlantis.yaml and the testing of a small change in every environment. Teams that want a fixed-scope plan, documented controls and a tested rollback can ask DeployOpen for a written scope, which is agreed before work starts.
Does Atlantis replace the HCP Terraform registry and workspace UI?
No. Atlantis is a pull request automation service that runs plans on pull requests, posts the output as comments and runs applies when an apply comment is made. It does not provide a private module or provider registry, a hosted workspace dashboard, managed state or a run history UI like HCP Terraform does. Modules can be referenced from Git or an object store, and the team should decide where its private modules will live and how they will be versioned before cutover.
Which state backends can Atlantis use?
Atlantis supports all Terraform state backend types except local state, because it has no permanent storage and does not commit state files back to version control. In practice this means a remote backend such as S3 or GCS, which are the options most teams evaluate first, with locking and encryption configured for the chosen backend. Confirm the exact backend configuration and its locking behavior with your cloud team and the Atlantis requirements documentation before moving any state.
Should we switch to OpenTofu at the same time as moving to Atlantis?
You can, but separating the two changes makes problems easier to isolate. OpenTofu is a drop-in replacement for Terraform that preserves existing workflows and configurations, and Atlantis documents running OpenTofu with a custom workflow in which the tofu binary is installed in an init container and ATLANTIS_TF_DOWNLOAD is set to false. Teams moving at the same time should first confirm the Terraform version used by each workspace, test the migration in a non-production environment and keep a documented rollback path, following the four steps in OpenTofu's migration guide.
What should a quote for this migration include?
A quote should follow from a written scope that lists the workspaces in scope, the target state backend, the Git provider, the deployment method for Atlantis and the number of environments to test. Ask for the deliverables in writing, including atlantis.yaml files, state migration steps, credential handling, backup and rollback procedures and documentation for your team. Confirm whether ongoing support, upgrades and testing are included or offered as a separate retainer, and what happens if the scope changes during the work.
What costs continue after the migration is finished?
After cutover, the recurring costs are the infrastructure that runs Atlantis, the state storage and its access logging, the Git provider licenses you already hold, and the staff time to upgrade Atlantis and OpenTofu and to review changes. Atlantis itself is licensed under Apache 2.0, so there is no per-run or per-resource license fee. Ask your team and your provider to estimate these recurring items for your own environment, and ask any implementation partner which upgrade and support work is included in the scope.
How DeployOpen scopes, runs and supports the Atlantis migration
DeployOpen plans, implements, hardens, documents and supports self-hosted open-source platforms inside your own infrastructure, including your cloud accounts, data centers or air-gapped networks. For an Atlantis migration, that means Atlantis itself, the state backend you choose, the atlantis.yaml layout, the OpenTofu custom workflow and the pull request controls that gate atlantis apply. Most engagements are fixed-scope, so the list of workspaces in scope, the state move for each one, the deliverables and the timeline are agreed in writing before any work starts. Ask for that written scope to name each HCP Terraform workspace, the target state bucket, the repositories to be wired up and who on your side signs off each cutover. A quote follows from that scope, and DeployOpen does not publish a price list.
Security work sits alongside the build. DeployOpen can run security testing against the Atlantis deployment and the pipeline around it, including the webhook endpoint, the credentials Atlantis holds for cloud accounts and the controls on who can comment atlantis apply. Where you need evidence for a compliance assessment, DeployOpen can prepare the systems, access records, change logs and configuration documentation that an assessor will ask for. DeployOpen does not issue audit reports, attestations or certifications. Independent auditors and certification bodies make those determinations, so confirm early with your assessor which evidence they expect from a pull-request-driven change process.
After go-live, ongoing support, upgrades and continuous testing are available as retainers. This matters for Atlantis because its releases, the OpenTofu versions your repositories pin and the plugin and provider versions in the init container all change over time, and each change should be tested before it reaches production stacks. Ask any implementation partner, including DeployOpen, how upgrades are rehearsed, who approves them, and how a rollback to the previous image and tofu binary would work. A retainer scope should state those responsibilities in writing alongside the initial fixed-scope deliverables.

