Pular para o conteúdo

Atlantis Cheat Sheet

Overview

Atlantis is an open-source, self-hosted application that automates Terraform workflows via pull requests. When a pull request modifying Terraform files is opened, Atlantis automatically runs terraform plan and posts the output as a comment. Team members review the plan in the PR, and when approved, use a comment command (atlantis apply) to execute the changes. This workflow ensures all infrastructure changes go through code review and creates an auditable trail of every change.

Atlantis supports GitHub, GitLab, Bitbucket Cloud, and Bitbucket Server with webhook-based integration. It handles multiple Terraform workspaces, custom workflows, parallel planning, locking to prevent concurrent modifications to the same state, and server-side repository configuration for enforcing organizational standards. By running Terraform operations server-side, Atlantis eliminates the need for developers to have cloud credentials locally and ensures consistent execution environments.

Installation

Docker

# Run Atlantis with Docker
docker run -d \
  --name atlantis \
  -p 4141:4141 \
  -e ATLANTIS_GH_USER="atlantis-bot" \
  -e ATLANTIS_GH_TOKEN="github-pat-token" \
  -e ATLANTIS_GH_WEBHOOK_SECRET="webhook-secret" \
  -e ATLANTIS_REPO_ALLOWLIST="github.com/your-org/*" \
  -e ATLANTIS_ATLANTIS_URL="https://atlantis.example.com" \
  -e AWS_ACCESS_KEY_ID="your-key" \
  -e AWS_SECRET_ACCESS_KEY="your-secret" \
  ghcr.io/runatlantis/atlantis:latest \
  server

# With persistent data
docker run -d \
  --name atlantis \
  -p 4141:4141 \
  -v atlantis-data:/atlantis-data \
  -e ATLANTIS_DATA_DIR="/atlantis-data" \
  -e ATLANTIS_GH_USER="atlantis-bot" \
  -e ATLANTIS_GH_TOKEN="github-pat-token" \
  -e ATLANTIS_GH_WEBHOOK_SECRET="webhook-secret" \
  -e ATLANTIS_REPO_ALLOWLIST="github.com/your-org/*" \
  ghcr.io/runatlantis/atlantis:latest \
  server

Kubernetes via Helm

# Add Atlantis Helm repo
helm repo add atlantis https://runatlantis.github.io/helm-charts
helm repo update

# Install Atlantis
helm install atlantis atlantis/atlantis \
  --namespace atlantis \
  --create-namespace \
  --values atlantis-values.yaml

# Minimal values file
cat > atlantis-values.yaml << 'EOF'
orgAllowlist: "github.com/your-org/*"
github:
  user: atlantis-bot
  token: github-pat-token
  secret: webhook-secret

atlantisUrl: https://atlantis.example.com

# AWS credentials
environmentSecrets:
  - name: AWS_ACCESS_KEY_ID
    secretKeyRef:
      name: aws-credentials
      key: access-key-id
  - name: AWS_SECRET_ACCESS_KEY
    secretKeyRef:
      name: aws-credentials
      key: secret-access-key

ingress:
  enabled: true
  host: atlantis.example.com

replicaCount: 1

resources:
  requests:
    memory: 256Mi
    cpu: 100m
  limits:
    memory: 1Gi
    cpu: 500m
EOF

Binary Installation

# Download binary
curl -fsSL https://github.com/runatlantis/atlantis/releases/latest/download/atlantis_linux_amd64.zip -o atlantis.zip
unzip atlantis.zip
sudo mv atlantis /usr/local/bin/

# Run server
atlantis server \
  --gh-user="atlantis-bot" \
  --gh-token="github-pat-token" \
  --gh-webhook-secret="webhook-secret" \
  --repo-allowlist="github.com/your-org/*" \
  --atlantis-url="https://atlantis.example.com" \
  --port=4141

Core Commands — PR Comments

Plan and Apply

# In a GitHub/GitLab pull request comment:

# Run plan for all modified projects
atlantis plan

# Plan a specific project
atlantis plan -p myproject

# Plan a specific directory
atlantis plan -d terraform/production

# Plan with a specific workspace
atlantis plan -w production

# Plan with extra Terraform flags
atlantis plan -- -var="environment=production"

# Plan with a specific var file
atlantis plan -- -var-file=production.tfvars

# Apply after reviewing plan
atlantis apply

# Apply a specific project
atlantis apply -p myproject

# Apply a specific directory
atlantis apply -d terraform/production

# Apply a specific workspace
atlantis apply -w production

# Unlock a project (discard pending plan)
atlantis unlock

# Check Atlantis version
atlantis version

# Import a resource
atlantis import -d terraform/production ADDRESS ID

Lock Management

# View locks via web UI
# Navigate to https://atlantis.example.com

# Unlock via PR comment
atlantis unlock

# Force unlock via API
curl -X DELETE "https://atlantis.example.com/api/locks?id=LOCK_ID"

# List all locks
curl -s "https://atlantis.example.com/api/locks" | jq '.'

Configuration

Server-Side Repo Configuration (atlantis.yaml)

# atlantis.yaml — Place in repository root
version: 3
automerge: false
delete_source_branch_on_merge: true
parallel_plan: true
parallel_apply: true

projects:
  - name: production-vpc
    dir: terraform/vpc
    workspace: production
    terraform_version: v1.7.0
    autoplan:
      when_modified:
        - "*.tf"
        - "*.tfvars"
        - "modules/**/*.tf"
      enabled: true
    apply_requirements:
      - approved
      - mergeable
    workflow: default

  - name: staging-vpc
    dir: terraform/vpc
    workspace: staging
    terraform_version: v1.7.0
    autoplan:
      when_modified:
        - "*.tf"
        - "staging.tfvars"
      enabled: true

  - name: production-eks
    dir: terraform/eks
    workspace: production
    terraform_version: v1.7.0
    autoplan:
      enabled: true
    apply_requirements:
      - approved
      - mergeable
    depends_on:
      - production-vpc

  - name: production-rds
    dir: terraform/rds
    workspace: production
    autoplan:
      enabled: true
    apply_requirements:
      - approved
      - mergeable

Custom Workflows

# atlantis.yaml with custom workflows
version: 3
projects:
  - name: production
    dir: terraform/production
    workflow: production-workflow
    apply_requirements:
      - approved
      - mergeable

workflows:
  production-workflow:
    plan:
      steps:
        # Custom init with backend config
        - init:
            extra_args: ["-backend-config=production.backend.hcl"]
        
        # Run tflint before planning
        - run: tflint --init && tflint
        
        # Run checkov security scan
        - run: checkov -d . --quiet --compact
        
        # Standard plan
        - plan:
            extra_args: ["-var-file=production.tfvars"]
        
        # Show cost estimate
        - run: |
            infracost breakdown --path . --format table
    
    apply:
      steps:
        - apply

  # Terragrunt workflow
  terragrunt-workflow:
    plan:
      steps:
        - env:
            name: TERRAGRUNT_TFPATH
            command: 'which terraform'
        - run: terragrunt plan -input=false -out=$PLANFILE
    apply:
      steps:
        - run: terragrunt apply $PLANFILE

Server-Side Configuration (repos.yaml)

# repos.yaml — Server-side config to enforce policies across all repos
repos:
  # Default settings for all repos
  - id: /.*/
    allowed_overrides:
      - workflow
      - apply_requirements
      - delete_source_branch_on_merge
    apply_requirements:
      - approved
      - mergeable
    allowed_workflows:
      - default
      - custom-with-checks
    allow_custom_workflows: false

  # Specific repo overrides
  - id: github.com/your-org/infrastructure
    allowed_overrides:
      - workflow
      - apply_requirements
    apply_requirements:
      - approved
      - mergeable
    allow_custom_workflows: true

  # Restrict certain repos
  - id: github.com/your-org/production-infra
    apply_requirements:
      - approved
      - mergeable
    allowed_overrides: []
    allow_custom_workflows: false

workflows:
  custom-with-checks:
    plan:
      steps:
        - init
        - run: tflint
        - plan
    apply:
      steps:
        - apply

Helm Values (Full Example)

# atlantis-values.yaml
orgAllowlist: "github.com/your-org/*"
atlantisUrl: "https://atlantis.example.com"

github:
  user: atlantis-bot
  token: ghp_xxxxxxxxxxxx
  secret: webhook-secret-123

# Server-side repo config
repoConfig: |
  ---
  repos:
    - id: /.*/
      apply_requirements: [approved, mergeable]
      allowed_overrides: [workflow, apply_requirements]
      allow_custom_workflows: true

# Environment variables for cloud credentials
environmentSecrets:
  - name: AWS_ACCESS_KEY_ID
    secretKeyRef:
      name: aws-credentials
      key: access-key-id
  - name: AWS_SECRET_ACCESS_KEY
    secretKeyRef:
      name: aws-credentials
      key: secret-access-key
  - name: INFRACOST_API_KEY
    secretKeyRef:
      name: infracost-key
      key: api-key

# Default Terraform version
defaultTFVersion: "1.7.0"

# Resource limits
resources:
  requests:
    memory: 512Mi
    cpu: 200m
  limits:
    memory: 2Gi
    cpu: 1000m

# Persistence
dataStorage: 10Gi

# Ingress
ingress:
  enabled: true
  ingressClassName: nginx
  host: atlantis.example.com
  tls:
    - secretName: atlantis-tls
      hosts:
        - atlantis.example.com

Advanced Usage

Conftest Policy Checking

# atlantis.yaml — Run conftest policies
workflows:
  policy-checked:
    plan:
      steps:
        - init
        - plan
        - run: |
            terraform show -json $PLANFILE > plan.json
            conftest test plan.json --policy policy/ --no-color

Multi-Environment Promotion

# atlantis.yaml — Promote through environments
version: 3
projects:
  - name: dev
    dir: terraform/app
    workspace: dev
    autoplan:
      enabled: true

  - name: staging
    dir: terraform/app
    workspace: staging
    apply_requirements: [approved]
    depends_on: [dev]

  - name: production
    dir: terraform/app
    workspace: production
    apply_requirements: [approved, mergeable]
    depends_on: [staging]

Webhook Configuration

# GitHub webhook setup
# URL: https://atlantis.example.com/events
# Content type: application/json
# Secret: your-webhook-secret
# Events: Pull requests, Pull request reviews, Issue comments, Pushes

# GitLab webhook
# URL: https://atlantis.example.com/events
# Secret: your-webhook-secret
# Triggers: Push events, Comments, Merge request events

# Test webhook
curl -X POST "https://atlantis.example.com/events" \
  -H "Content-Type: application/json" \
  -H "X-GitHub-Event: ping" \
  -d '{"zen": "test"}'

Troubleshooting

IssueCauseSolution
Atlantis not commenting on PRWebhook not configuredVerify webhook URL and secret in GitHub settings
Plan failing with auth errorMissing cloud credentialsSet AWS/GCP/Azure credentials as environment variables
Lock conflictAnother PR holds the lockMerge or close the conflicting PR, or force unlock
Autoplan not triggeringFiles outside when_modified patternUpdate when_modified to include changed files
Apply requirements not metPR not approved or not mergeableGet PR approval and resolve merge conflicts
Custom workflow not foundWorkflow name mismatchVerify workflow name in atlantis.yaml matches project config
Slow plansLarge state fileUse state file splitting or -target flag
Atlantis pod OOMKilledInsufficient memory for large plansIncrease memory limit in Helm values
# Check Atlantis health
curl https://atlantis.example.com/healthz

# View Atlantis logs
kubectl logs -n atlantis deploy/atlantis --tail=100

# Check webhook deliveries (GitHub)
# Go to repo Settings > Webhooks > Recent Deliveries

# Debug: view active locks
curl -s https://atlantis.example.com/api/locks | jq '.'

# Force unlock all
curl -X DELETE "https://atlantis.example.com/api/locks?id=LOCK_ID"

# Test connectivity from Atlantis to Git
kubectl exec -n atlantis deploy/atlantis -- git ls-remote https://github.com/org/repo.git

# Verify Terraform version
kubectl exec -n atlantis deploy/atlantis -- terraform version