Automating Terraform Workflows on VPS: A Comprehensive Guide to Setting Up Atlantis for GitOps
Introduction to GitOps and Terraform Automation
In the landscape of modern cloud infrastructure management, Infrastructure as Code (IaC) has become the gold standard. Tools like Terraform allow engineering teams to define, provision, and manage cloud resources safely and predictably. However, as teams scale, managing Terraform state files, preventing concurrent execution conflicts, and ensuring rigorous peer review processes can become highly complex.
Entering Atlantis: an open-source application that transforms your Git workflow into a control plane for Terraform. By self-hosting Atlantis on a Virtual Private Server (VPS), your team can execute terraform plan and terraform apply directly within Pull Requests (PRs). This approach, fundamentally known as GitOps, centralizes visibility, enforces collaboration, and provides a clear audit trail for every infrastructure change.
Why Run Atlantis on a Self-Hosted VPS?
While managed CI/CD platforms can run Terraform scripts, a dedicated VPS configuration offers several distinct advantages for enterprise environments:
- Enhanced Security: Your infrastructure credentials and cloud provider access tokens remain within your private boundary rather than being exposed to third-party SaaS environments.
- Cost Efficiency: Running a lightweight, persistent Atlantis binary on a standard VPS is significantly cheaper than high-tier enterprise CI/CD runner subscriptions.
- Customization: You have complete control over the underlying operating system, caching layers, custom scripts, and specific Terraform versions required by your projects.
Prerequisites and System Requirements
Before proceeding with the installation, ensure your environment meets the following baseline criteria:
- A Provisioned VPS: Ubuntu 22.04 LTS or newer is highly recommended, equipped with at least 2 vCPUs and 4GB of RAM.
- Domain Name and SSL Certificate: A fully qualified domain name (FQDN) pointing to your VPS IP address, secured with Let's Encrypt SSL via Nginx.
- Git Provider Credentials: Personal Access Tokens (PAT) and Webhook secrets from GitHub, GitLab, or Bitbucket.
- Cloud Access: Appropriate IAM roles or API keys configured on the VPS to allow Terraform to authenticate with your cloud providers (e.g., AWS, Azure, GCP).
Step-by-Step Installation and Configuration
Step 1: Preparing the VPS Environment
First, access your VPS via SSH and update the core system packages to ensure a secure baseline. We will also install essential dependencies like unzip and curl.
sudo apt update && sudo apt upgrade -y
sudo apt install unzip curl nginx git -yNext, install the specific version of the Terraform CLI required for your environment. Download the official binary package from HashiCorp, unpack it, and move it to your global system path:
wget [https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_linux_amd64.zip](https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_linux_amd64.zip)
unzip terraform_1.7.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/Step 2: Installing the Atlantis Binary
Create a dedicated, non-privileged system user to run Atlantis securely. This minimizes risk by ensuring the application cannot modify system-level configurations outside its scope.
sudo useradd --system --no-create-home --shell /bin/false atlantis
sudo mkdir -p /etc/atlantis /var/lib/atlantis
sudo chown -R atlantis:atlantis /var/lib/atlantisDownload the latest stable release of Atlantis from GitHub and set its executable permissions:
atlantis_version="0.27.0"
curl -LO [https://github.com/runatlantis/atlantis/releases/download/v$](https://github.com/runatlantis/atlantis/releases/download/v$){atlantis_version}/atlantis_linux_amd64.zip
unzip atlantis_linux_amd64.zip
sudo mv atlantis /usr/local/bin/
sudo chmod +x /usr/local/bin/atlantisStep 3: Configuring Git Provider Webhooks
For Atlantis to orchestrate pull requests, it must listen to events from your Git provider. Here is how to configure a GitHub repository integration:
- Navigate to your GitHub repository or organization settings, select Webhooks, and click Add Webhook.
- Set the Payload URL to
[https://atlantis.yourdomain.com/events](https://atlantis.yourdomain.com/events). - Change the Content type to
application/json. - Generate a strong, random string for the Secret token. Record this value safely.
- Select individual events: Issue comments, Pull requests, Pull request reviews, and Pushes.
Important Security Note: Always ensure your webhook configurations use HTTPS connections to guarantee that validation signatures cannot be intercepted or tampered with during transmission.
Step 4: Defining the Configuration File
Create an atlantis.yaml server configuration file inside /etc/atlantis/ to safely pass configuration parameters, variables, and operational paths to the daemon binary.
sudo nano /etc/atlantis/server.yamlPopulate the file with the following configuration structural layout, making sure to substitute placeholders with your real values:
atlantis-url: "[https://atlantis.yourdomain.com](https://atlantis.yourdomain.com)"
repo-allowlist: "[github.com/your-organization/](https://github.com/your-organization/)*"
gh-user: "atlantis-bot-user"
gh-token: "ghp_YourGitHubPersonalAccessToken"
gh-webhook-secret: "your_generated_webhook_secret"
data-dir: "/var/lib/atlantis"
port: 4141Secure the file permissions so that unauthorized local system users cannot read sensitive tokens:
sudo chown -R atlantis:atlantis /etc/atlantis
sudo chmod 600 /etc/atlantis/server.yamlStep 5: Setting Up a systemd Service
To ensure Atlantis launches automatically when the VPS boots up and restarts gracefully in the event of an unexpected crash, manage the process using a systemd service unit file.
sudo nano /etc/systemd/system/atlantis.serviceInsert the following service definition text block:
[Unit]
Description=Atlantis Terraform Automation
After=network.target
[Service]
Type=simple
User=atlantis
Group=atlantis
ExecStart=/usr/local/bin/atlantis server --config /etc/atlantis/server.yaml
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=atlantis
[Install]
WantedBy=multi-user.targetReload the systemd daemon, enable the service to start automatically on boot, and initiate the system process:
sudo systemctl daemon-reload
sudo systemctl enable atlantis.service
sudo systemctl start atlantis.serviceStep 6: Setting Up Nginx Reverse Proxy with SSL
Atlantis listens locally on port 4141 by default. To securely expose it over standard HTTPS port 443, configure Nginx as a reverse proxy coupled with a Let's Encrypt certificate.
sudo nano /etc/nginx/sites-available/atlantisAdd the following virtual host configuration layout:
server {
listen 80;
server_name atlantis.yourdomain.com;
location / {
proxy_pass http://localhost:4141;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Enable the site configuration, test your Nginx configuration syntax, and restart the service to apply changes:
sudo ln -s /etc/nginx/sites-available/atlantis /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginxTo secure your domain with Let's Encrypt SSL, run the automated Certbot configuration wizard:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d atlantis.yourdomain.com---The GitOps Execution Workflow
With your new setup fully initialized, managing infrastructure follows a clean, auditable, and automated continuous integration lifecycle directly through your Git interface:
- Create a Branch: An engineer creates a feature branch containing modifications to existing Terraform configuration scripts.
- Open a Pull Request: Pushing the branch and opening a PR triggers an automated GitHub webhook event sent directly to your Atlantis installation.
- Automated Review: Atlantis detects changes and runs
terraform planasynchronously, adding the stdout output log directly into the PR comments section. This gives peers visibility into the proposed infrastructure impact. - Collaborative Command Approval: Reviewers assess the planned output changes. Once approved, an authorized team member posts a command comment containing
atlantis applyinside the PR timeline. - State Enforcement: Atlantis executes the apply step locally, locks the state workspace to prevent concurrent conflicts, writes the execution results back to the PR comment chain, and merges the PR automatically.
Conclusion and Operational Best Practices
Configuring Atlantis on a VPS transitions your operations away from siloed manual infrastructure adjustments and toward an optimized, transparent GitOps framework. By ensuring that state files are dynamically locked during execution, you can protect production state registries against corruption while streamlining engineering visibility.
As next steps to secure this production ecosystem, ensure you lock down network traffic to your VPS using firewall solutions like UFW, limiting incoming traffic on port 443 strictly to your Git provider's public IP address ranges. Furthermore, configure periodic automated log rotation strategies to maintain optimal server storage capacity over long production horizons.
