Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Atlantis: Pull-Request Automation for Terraform

By Kokil Thapa | Last reviewed: September 2026

Your team opens a Terraform pull request. Someone runs terraform plan locally, pastes the output into a comment, and hopes nothing changed before merge. That workflow breaks under pressure. Atlantis: Pull-Request Automation for Terraform fixes it by running plan and apply from one server, posting results on the PR, and locking projects so two changes cannot fight over the same state. If you already treat infrastructure as code, as covered in our Infrastructure as Code with Terraform practical guide, Atlantis is the missing review layer between Git and your remote backend.

What is Atlantis and how does pull-request automation for Terraform work?

Atlantis is an open-source Go application maintained at runatlantis/atlantis on GitHub. It sits between your Git host and your Terraform code. When a developer opens or updates a pull request, Atlantis clones the branch, discovers which Terraform projects changed, runs plan, and posts the output back to the PR thread.

After review, a team member comments atlantis apply. Atlantis runs terraform apply using credentials stored on the server—not on a laptop. Every command is logged. Every plan is tied to a commit SHA. That is the core value of Atlantis pull-request automation for Terraform: infrastructure changes follow the same review path as application code.

Atlantis Terraform PR AutomationDeveloperOpens PRGit HostWebhookAtlantisPlan / ApplyTerraformCLI 1.xRemote StateS3 + DynamoDB lockCloud APIsAWS / GCP / AzurePR CommentsPlan outputProject LockingOne apply at a time per project directory
Atlantis pull-request automation for Terraform connects Git webhooks, centralized plan/apply execution, and remote state locking.

Core commands developers use

Atlantis responds to PR comments. The ones you will use daily:

  • atlantis plan — re-runs plan after new commits
  • atlantis apply — applies the approved plan for that PR
  • atlantis unlock — releases a stuck project lock
  • atlantis plan -p staging — targets a named project from atlantis.yaml

Plans run automatically on opened and synchronized PRs when autoplan is enabled. Applies never run without an explicit comment or merge policy you configure. That separation mirrors how I run build pipeline automation best practices on application repos: build on every push, deploy only after approval.

How do you install and configure Atlantis for Terraform pull requests?

You can run Atlantis as a single binary, a Docker container, or a Kubernetes deployment. For a small team on Ubuntu 24 with Docker, the container path is fastest. Point it at a GitHub or GitLab repo that holds your Terraform modules and environment roots.

Step 1: Deploy the Atlantis server

Create a dedicated VM or container with outbound access to your cloud APIs and inbound HTTPS from your Git host. Store secrets in environment variables—not in the repo.

# docker-compose.yml (minimal example)
services:
  atlantis:
    image: ghcr.io/runatlantis/atlantis:v0.30.0
    ports:
      - "4141:4141"
    environment:
      ATLANTIS_GH_USER: "atlantis-bot"
      ATLANTIS_GH_TOKEN: "${ATLANTIS_GH_TOKEN}"
      ATLANTIS_GH_WEBHOOK_SECRET: "${ATLANTIS_WEBHOOK_SECRET}"
      ATLANTIS_REPO_ALLOWLIST: "github.com/your-org/*"
      ATLANTIS_DATA_DIR: "/atlantis-data"
    volumes:
      - ./atlantis-data:/atlantis-data

Mount a persistent volume for /atlantis-data. Atlantis stores cloned repos and lock files there. Ephemeral containers without a volume lose locks on restart and confuse operators.

Step 2: Register the webhook

In GitHub repo settings, add a webhook pointing to https://atlantis.example.com/events. Subscribe to pull request, issue comment, and push events. Paste the same secret into ATLANTIS_GH_WEBHOOK_SECRET. Without matching secrets, every event returns 401 and plans never trigger.

Step 3: Define projects in atlantis.yaml

Place atlantis.yaml at the repo root. It tells Atlantis which directories are separate Terraform projects and how they relate to Terraform workspaces and environments.

version: 3
automerge: false
parallel_plan: true
parallel_apply: false

projects:
  - name: production-vpc
    dir: environments/production/vpc
    workspace: default
    autoplan:
      when_modified: ["*.tf", "*.tfvars", "../../modules/**/*.tf"]
      enabled: true
    apply_requirements: [approved, mergeable]

  - name: staging-vpc
    dir: environments/staging/vpc
    workspace: default
    autoplan:
      when_modified: ["*.tf", "*.tfvars"]
      enabled: true

The apply_requirements array is your governance gate. Require approved so a second engineer must sign off. Require mergeable so conflicting branches cannot apply. On teams where I also manage application deploys with Deployer and GitLab CI, this file plays the same role as a protected branch rule.

PR Workflow Steps1. Developer opens or updates PR2. Atlantis autoplan runs terraform plan3. Plan posted as PR comment4. Reviewer approves PR5. atlantis apply → terraform apply
Standard Atlantis pull-request automation workflow: autoplan on update, human review, explicit apply command.

Step 4: Wire remote state and provider credentials

Atlantis runs Terraform on the server. Configure the backend the same way you would locally, as described in Terraform remote state on S3 with locking. Use an IAM role, workload identity, or scoped service account attached to the Atlantis host—not long-lived root keys.

# environments/production/vpc/backend.tf
terraform {
  backend "s3" {
    bucket         = "company-terraform-state"
    key            = "production/vpc/terraform.tfstate"
    region         = "ap-southeast-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

If you use Terragrunt to keep Terraform DRY, set workflow: terragrunt in atlantis.yaml and install Terragrunt on the Atlantis image. The PR comment flow stays identical; only the underlying command changes.

How does Atlantis compare to Terraform Cloud and GitHub Actions?

Teams evaluating Atlantis pull-request automation for Terraform usually compare three options: self-hosted Atlantis, HashiCorp Terraform Cloud (or HCP Terraform), and custom Terraform CI/CD with GitHub Actions. Each can run plan on PR and apply on merge. The trade-offs are cost, lock-in, and operational burden.

CriteriaAtlantis (self-hosted)Terraform Cloud / HCPGitHub Actions
HostingYour VM, K8s, or DockerHashiCorp SaaSGitHub-hosted runners
Cost modelServer cost only (Rs 3,000–15,000/mo, ~USD 22–110)Per-seat or run-based pricingMinutes-based; free tier limits
PR comment UXNative, polishedNative via VCS integrationCustom with actions/github-script
State lockingUses your existing backendBuilt-in remote stateUses your existing backend
Policy as codeExternal (Checkov, OPA, Sentinel via TFC only)Sentinel (paid tiers)Bring your own scanner
Vendor lock-inLow — open sourceMedium — TFC featuresLow — YAML in repo
Ops responsibilityYou patch, monitor, secureHashiCorp manages platformGitHub manages runners

Pick Atlantis when you already run Terraform with S3 or GCS backends and want PR-native workflows without SaaS per-run fees. Pick Terraform Cloud when you want managed state, Sentinel policies, and private module registry in one bill. Pick GitHub Actions when your Terraform footprint is small and you want everything inside existing CI YAML.

For a broader tool comparison, see Terraform vs Pulumi vs OpenTofu. Atlantis works with all three CLIs because it shells out to whatever binary you install on the server.

Which Tool Fits Your Team?Need PR automation?Self-host OKPrefer SaaSAtlantisExisting S3 backendTerraform CloudManaged state + SentinelSmall repo?Try GitHub ActionsProduction ChecklistLocking, approval gates, drift scansScoped cloud credentials
Decision flow for Atlantis pull-request automation versus managed Terraform platforms and DIY CI pipelines.

What are the best practices for securing Atlantis in production?

Atlantis holds cloud credentials and can modify production infrastructure. Treat the server like a CI controller with root-level cloud access. A misconfigured instance is worse than no automation at all.

Restrict repository access

Set ATLANTIS_REPO_ALLOWLIST to explicit org/repo patterns. Never use a wildcard on public GitHub if the server is internet-facing. Forked PRs from untrusted contributors are a known attack surface—disable autoplan on forks or require approval before planning.

Scope IAM and use short-lived credentials

Attach an IAM role to the EC2 instance or K8s service account. Grant only the actions your modules need. Rotate keys if you must use them. This mirrors how I harden Ubuntu servers for client workloads under Linux system administration engagements: least privilege, no shared root keys, audit logs enabled.

Add policy scanning before apply

Run Checkov to scan Terraform for misconfigurations in a custom workflow step or as a pre-plan hook. Block applies when critical rules fail—public S3 buckets, open security groups, missing encryption. For HashiCorp-only shops, Sentinel policy as code lives inside Terraform Cloud, not native Atlantis, but OPA and Conftest integrate cleanly.

Protect state and secrets

Remote backends must use encryption and locking, as outlined in manage Terraform state safely. Never commit .tfvars with secrets. Inject sensitive values through environment variables referenced in Terraform or through a secrets manager Atlantis reads at runtime. Validate JSON payloads from webhooks—our JSON formatter tool helps debug malformed event bodies during setup.

Atlantis Security LayersHTTPS + Webhook SecretRepo Allowlist + Fork PolicyScoped IAM / Workload IdentityCheckov / OPA Policy GateEncrypted Remote State + DynamoDB LockDefense in depth for production Terraform automation
Layered security model for Atlantis pull-request automation for Terraform in production environments.

How do you troubleshoot common Atlantis failures with Terraform?

Most production tickets fall into five buckets. Work through them in order before reinstalling anything.

  1. Webhook not firing. Check GitHub delivery logs. Confirm the URL, secret, and TLS certificate. A self-signed cert without proper trust breaks silently.
  2. Plan succeeds locally but fails in Atlantis. Compare Terraform and provider versions. Pin versions in required_version and required_providers blocks per Terraform provider version pinning guidance.
  3. Project lock stuck after crash. Run atlantis unlock -p project-name on the PR. Investigate why the container restarted without graceful shutdown.
  4. Backend access denied. The Atlantis role lacks s3:GetObject or DynamoDB lock permissions. Fix IAM—not Terraform code.
  5. Drift after apply. Something changed outside Terraform. Schedule regular plans from main and read Terraform drift detection strategies.

Enable debug logging with ATLANTIS_LOG_LEVEL=debug temporarily. Redact tokens before sharing logs. For module errors, reproduce with atlantis plan -p project-name -- -target=module.foo to narrow scope.

On sister sites I maintain with Deployer 7 and GitLab CI—similar to the pipeline behind Notary Kathmandu—the same discipline applies: one change at a time, visible logs, quick rollback path. Atlantis gives Terraform the same operational hygiene.

When should you adopt Atlantis for your Terraform workflow?

Adopt Atlantis pull-request automation for Terraform when:

  • Two or more engineers touch the same Terraform repos weekly
  • You already use remote state with locking via S3, GCS, or Azure Blob
  • PR review is mandatory but plan output is inconsistent or missing
  • Terraform Cloud cost or data residency rules push you toward self-hosting
  • You need multi-repo, multi-directory monorepo layouts with independent project locks

Skip Atlantis—for now—if you have a single engineer, one environment, and five resources. A Makefile and pre-commit hooks suffice. Scale into automation when review friction costs more than a small VM.

Structure modules first using patterns from Terraform modules for reusable infrastructure. Then add Atlantis. Automating messy roots only speeds up mistakes.

For larger platform work—multi-environment Laravel apps on AWS with Terraform-provisioned VPCs—see how enterprise application development ties application and infrastructure lifecycles together. Atlantis sits at the infrastructure side; your app CI sits beside it, not inside it.

Official Terraform docs at developer.hashicorp.com/terraform cover CLI behaviour Atlantis wraps. Atlantis-specific server flags and server-side repo config are documented at runatlantis.io/docs.

Key Takeaways

  • Atlantis automates terraform plan on every PR and apply only after explicit approval comments or configured merge rules.
  • Define projects in atlantis.yaml with apply_requirements, autoplan paths, and optional Terragrunt workflows.
  • Run Atlantis on a hardened host with scoped IAM, repo allowlists, and encrypted remote state—not developer laptops.
  • Compare cost and ops burden against Terraform Cloud and GitHub Actions before committing; Atlantis wins on PR UX plus backend flexibility.
  • Add Checkov or OPA scanning and drift detection on main to catch misconfigurations before and after apply.
  • Pin Terraform and provider versions so Atlantis plans match local runs and CI does not surprise you on merge day.

People Also Ask

Does Atlantis work with GitLab and Bitbucket?

Yes. Atlantis supports GitHub, GitLab, Gitea, and Bitbucket Cloud through VCS-specific environment variables. The PR comment workflow is identical; only webhook setup and token scopes differ. GitLab self-managed instances need outbound access from the Atlantis server to both the GitLab API and your cloud provider.

Can Atlantis run OpenTofu instead of Terraform?

Yes. Set the ATLANTIS_TFE_LOCAL_EXECUTION or custom workflow to call the tofu binary. Many teams migrating under the OpenTofu fork keep Atlantis unchanged and swap the CLI on the server image. Lock files and provider sources must match the binary you execute.

How many repos can one Atlantis server handle?

A single modest VM—2 vCPU, 4 GB RAM—handles dozens of repos with moderate PR volume. Bottlenecks appear when many parallel plans run large modules. Disable parallel_plan or shard across multiple Atlantis instances with repo-based routing if plan queues grow past acceptable wait times.

Is Atlantis free for commercial use?

Atlantis is open source under the Apache 2.0 license. There is no per-run fee. You pay for compute, storage, and engineer time to operate and secure the server. That cost model suits agencies and product teams that already self-host CI controllers.

Ship reviewable infrastructure changes with confidence

Atlantis pull-request automation for Terraform turns opaque infrastructure edits into reviewable, logged, repeatable workflows. Install it on a locked-down host, define projects in atlantis.yaml, connect your existing remote backend, and require approvals before apply. Pair it with policy scanning and drift checks on main. Your future self—and whoever inherits the repo—will thank you on the first avoided outage.

Need help designing Terraform modules, CI pipelines, or production server hardening for a Nepali or global product team? Contact us to discuss your infrastructure and build automation roadmap, or browse the Adventure Third Pole Trek portfolio entry for an example of a Laravel platform backed by disciplined deploy practices.

Frequently Asked Questions

Atlantis is an open-source Go application that sits between your Git host and Terraform code. It runs terraform plan on pull requests, posts formatted output as PR comments, and runs apply only after explicit approval—centralising execution, locking state, and keeping every infrastructure change auditable.

When a developer opens or updates a pull request, Atlantis clones the branch via Git webhooks, discovers which Terraform projects changed, runs plan, and posts the output back to the PR thread. After review, a team member comments atlantis apply. Atlantis runs terraform apply using credentials stored on the server—not on a laptop. Every command is logged and tied to a commit SHA, mirroring application code review workflows.

The daily commands are atlantis plan to re-run plan after new commits, atlantis apply to apply the approved plan for that PR, atlantis unlock to release a stuck project lock, and atlantis plan -p staging to target a named project from atlantis.yaml. Plans run automatically on opened and synchronized PRs when autoplan is enabled. Applies never run without an explicit comment or a merge policy you configure.

Run Atlantis as a single binary, Docker container, or Kubernetes deployment. For a small team on Ubuntu 24 with Docker, deploy ghcr.io/runatlantis/atlantis:v0.30.0 with environment variables for your Git user, token, webhook secret, and repo allowlist. Mount a persistent volume at /atlantis-data so locks survive restarts. Register a webhook pointing to https://atlantis.example.com/events for pull request, issue comment, and push events. Place atlantis.yaml at the repo root to define projects.

Place atlantis.yaml at the repo root with version 3, automerge settings, parallel_plan and parallel_apply flags, and a projects array. Each project needs a name, dir, workspace, autoplan paths, and apply_requirements such as approved and mergeable. Autoplan when_modified paths tell Atlantis which file changes trigger plans. The apply_requirements array acts as your governance gate—requiring approved ensures a second engineer signs off before apply runs.

Yes. Atlantis is open source under the Apache 2.0 license with no per-run fee. You pay only for compute, storage, and engineer time to operate and secure the server.

Server cost only—typically Rs 3,000–15,000 per month, roughly USD 22–110—depending on VM size and PR volume. No per-seat or per-run SaaS fees unlike Terraform Cloud.

All three can run plan on PR and apply on merge, but trade-offs differ. Atlantis is self-hosted on your VM, K8s, or Docker with native PR comment UX and your existing S3 or GCS backend—low vendor lock-in but you handle patching and security. Terraform Cloud offers managed state, Sentinel policies, and a private module registry in one bill. GitHub Actions suits small Terraform footprints already inside CI YAML but needs custom scripting for PR comment UX.

Treat the Atlantis server like a CI controller with root-level cloud access. Restrict ATLANTIS_REPO_ALLOWLIST to explicit org/repo patterns—never wildcard on public GitHub. Disable autoplan on forked PRs or require approval before planning. Attach scoped IAM roles instead of long-lived root keys. Run Checkov or OPA before apply to block misconfigurations like public S3 buckets. Use encrypted remote backends with locking and inject secrets via environment variables, never committed .tfvars files.

Work through five buckets in order: webhook not firing—check GitHub delivery logs, URL, secret, and TLS certificate; plan succeeds locally but fails in Atlantis—compare and pin Terraform and provider versions; project lock stuck—run atlantis unlock -p project-name on the PR; backend access denied—fix IAM permissions for S3 or DynamoDB; drift after apply—schedule regular plans from main. Enable ATLANTIS_LOG_LEVEL=debug temporarily and redact tokens before sharing logs.

Adopt Atlantis when two or more engineers touch the same Terraform repos weekly, you already use remote state with locking via S3, GCS, or Azure Blob, PR review is mandatory but plan output is inconsistent, Terraform Cloud cost or data residency rules push you toward self-hosting, or you need multi-repo monorepo layouts with independent project locks. Skip it if you have a single engineer, one environment, and five resources—a Makefile suffices until review friction costs more than a small VM.

Yes. Atlantis supports GitHub, GitLab, Gitea, and Bitbucket Cloud through VCS-specific environment variables. The PR comment workflow is identical—atlantis plan, atlantis apply, and atlantis unlock work the same way. Only webhook setup and token scopes differ. GitLab self-managed instances need outbound access from the Atlantis server to both the GitLab API and your cloud provider endpoints.

Yes. Set ATLANTIS_TFE_LOCAL_EXECUTION or a custom workflow to call the tofu binary instead of terraform. Many teams migrating under the OpenTofu fork keep Atlantis unchanged and swap the CLI on the server image. Lock files and provider sources must match whichever binary you execute. The PR comment flow stays identical regardless of which Terraform-compatible CLI runs underneath.

A single modest VM with 2 vCPU and 4 GB RAM handles dozens of repos with moderate PR volume. Bottlenecks appear when many parallel plans run large modules simultaneously. Disable parallel_plan in atlantis.yaml or shard across multiple Atlantis instances with repo-based routing if plan queues grow past acceptable wait times. Monitor CPU and memory during peak PR activity to size appropriately.

Yes. Configure your backend the same way you would locally—S3 with DynamoDB locking is a common pattern. If you use Terragrunt to keep Terraform DRY, set workflow: terragrunt in atlantis.yaml and install Terragrunt on the Atlantis image. Wire scoped IAM roles or workload identity to the Atlantis host rather than long-lived root keys. The PR comment flow stays identical; only the underlying command changes from terraform to terragrunt.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: