Skip to content

Migrating from Atlantis

Atlantis pioneered Terraform PR automation. But after 1-2 years, most teams outgrow it. If you’re hitting Atlantis’s limits, Yaffle is the natural next step.

Pain pointAtlantisYaffle
Operational overheadYou run it: servers, updates, monitoringManaged service, zero ops
Single-threadedOne run at a time, bottleneck on busy reposParallel runs across workspaces
No RBACAnyone with repo access can atlantis applyGranular approval policies
No drift detectionManual checks or external toolingBuilt-in (planned)
Plan-only previewsShows what would change, can’t test itReal infrastructure you can hit
State managementYou configure backendsFully managed
SecretsEnvironment variables or external toolsAWS Secrets Manager integration

Atlantis shows you a plan. Yaffle creates real infrastructure.

Atlantis: PR → terraform plan → read diff → merge → hope it works
Yaffle: PR → plan → apply preview → test it → merge → apply production

Your QA team can test against pr-42.staging.example.com before merge.

Stop patching Atlantis servers, debugging webhook issues, and scaling infrastructure. Yaffle runs in our infrastructure—you just connect your repo.

Atlantis’s access model is “if you can push, you can apply.” Yaffle supports:

[[approvals]]
workspaces = ["infra/production/*"]
environments = ["production"]
approvers = [
"github:team:acme/platform-engineering",
"github:user:alice",
]

Yaffle runs OpenTofu, the open-source fork under MPL 2.0. No BSL licensing concerns as your infrastructure scales.

  1. Install the GitHub App on your repository. This doesn’t affect Atlantis—both can run simultaneously.

  2. Create a config matching your Atlantis setup:

    version = 1
    [[environments]]
    name = "production"
    [[environments]]
    name = "staging"
    [[triggers.github.push]]
    branch = "main"
    environment = "production"
    [[triggers.github.pull_request]]
    branch_pattern = "*"
    [[workspaces]]
    path = "infra"
    environments = ["*"]
  3. Deploy the bootstrap module to create the IAM role Yaffle assumes.

  4. Open a test PR. Both Atlantis and Yaffle will run. Compare results.

  5. Once confident, remove the Atlantis webhook or uninstall the Atlantis GitHub App.

Atlantis:

version: 3
projects:
- name: network
dir: infra/network
workspace: default
autoplan:
when_modified: ["*.tf"]
enabled: true
- name: compute
dir: infra/compute
workspace: default

Yaffle:

version = 1
[[workspaces]]
path = "infra/network"
environments = ["*"]
[[workspaces]]
path = "infra/compute"
environments = ["*"]
Atlantis commandYaffle equivalent
atlantis planAutomatic on PR push
atlantis applyAutomatic after plan (previews) or on merge (production)
atlantis plan -d infra/networkPlans all affected workspaces automatically
atlantis unlockNot needed—Yaffle manages locking

Atlantis: Set in server environment or atlantis.yaml

Yaffle: Use the variables field or Secrets Manager:

[[workspaces]]
path = "infra"
environments = ["*"]
variables.region = "us-east-1"
secrets.db_password = "arn:aws:secretsmanager:us-east-1:123:secret:db-pass"

You can run Atlantis and Yaffle simultaneously:

  1. Both will post checks to PRs
  2. Both will plan on push
  3. Only one should apply—disable Atlantis autoplan for production
# atlantis.yaml - disable autoplan during migration
version: 3
projects:
- name: infra
dir: infra
autoplan:
enabled: false # Manual only during migration

Once you’re confident in Yaffle, remove Atlantis entirely.

Can I migrate incrementally?

Yes. Add specific workspaces to Yaffle while Atlantis handles others. Yaffle only manages workspaces defined in yaffle.toml.

What about existing state?

Yaffle manages its own state. Your existing Terraform state stays where it is. For new workspaces, Yaffle starts fresh. For existing resources, use tofu import.

Do I need to change my Terraform code?

No. Yaffle runs standard OpenTofu, which is compatible with Terraform configurations. Your .tf files work as-is.

What if something goes wrong?

Yaffle provides full run logs in the dashboard and GitHub checks. If a preview fails, it doesn’t affect production. If you need to rollback, revert your PR and Yaffle applies the previous state.