Atlantis
Videos
Overview: Atlantis on Ubuntu 24.04 LTS on Azure: overview (watch on YouTube)
Launch and log in: Atlantis on Ubuntu 24.04 LTS on Azure: launch and log in (watch on YouTube)
Deep Dive: Atlantis on Ubuntu 24.04 LTS on Azure: deep dive (watch on YouTube)
Overview
Atlantis is an open-source, self-hosted server that automates Terraform through your pull requests. It listens for webhooks from GitHub, GitLab, Bitbucket or Azure DevOps. When someone opens a pull request, it runs terraform plan and posts the output back to the pull request as a comment.
A reviewer then types atlantis apply in the pull request, and Atlantis runs terraform apply. It locks the workspace, so two pull requests can never modify the same state at the same time.
This SecureAnyCloud image installs Atlantis 0.44.0 as a single Go binary, runs it as a dedicated atlantis system user, and puts an nginx reverse proxy with HTTP Basic authentication in front of the web UI.
What you get:
- Atlantis 0.44.0 at
/usr/local/bin/atlantis - Terraform 1.15.6 at
/usr/local/bin/terraform, as a base binary (Atlantis can also manage per-project Terraform versions on demand) - The Atlantis web UI (the locks and jobs dashboard), served through nginx on TCP
:80 - HTTP Basic authentication with a unique password generated on the first boot of every VM and stored in a root-only file
- An unauthenticated
/healthzliveness endpoint - An editable
/etc/atlantis/atlantis.env, where you connect your own VCS provider, webhook secret and repo-allowlist atlantis.serviceandnginx.serviceas enabled, active systemd units- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting size. Scale up for larger Terraform states and more concurrent plans.
Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp. Port 80 lets your VCS provider deliver webhooks and lets your browser reach the server. For public exposure, put TLS in front of it (see Enabling HTTPS).
You also need a Git repository, with permission to add a webhook and a bot access token to it. The examples below use GitHub.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Atlantis by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Select Review + create, then Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:atlantis-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name atlantis \
--image sac1647283583153:atlantis-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name atlantis --port 80 --priority 1010Step 3 - Connect to your VM
Connect over SSH with the key pair you selected at deployment:
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
Check that Atlantis and nginx are active:
systemctl is-active atlantis.service nginx.serviceBoth services report active. Atlantis starts within seconds. Until you connect a repository, it runs with a deny-all repo-allowlist and acts on nothing.
Step 5 - Retrieve your web password
Your VM generates its own web password on first boot and writes it to a root-only file. Read the file with sudo:
sudo cat /root/atlantis-credentials.txtThe file contains ATLANTIS_WEB_USER (admin) and ATLANTIS_WEB_PASSWORD. It also lists the URLs for the web UI, the /healthz liveness endpoint and the /events webhook endpoint. Store the password somewhere safe.
Step 6 - Check the health endpoints
nginx serves an unauthenticated static health endpoint for load balancers. It also proxies Atlantis's own /healthz liveness endpoint without authentication. Request both:
curl -s http://localhost/health
curl -s http://localhost/healthz/health returns ok and /healthz returns {"status":"ok"}.
Step 7 - Open the web UI
Browse to http://<vm-public-ip>/ and sign in as admin with the password from Step 5.
The Atlantis dashboard lists active workspace Locks and recent Jobs. It also lets you enable or disable apply commands globally. Before you connect a repository, both sections read "No locks found" and "No jobs found". This is the expected empty state of a fresh server.
Step 8 - Confirm the bundled binaries
The image ships both Atlantis and a base Terraform, so the server can run plans as soon as you connect a repository. Check their versions:
sudo /usr/local/bin/atlantis version /usr/local/bin/terraform versionThe output reports Atlantis 0.44.0 and Terraform v1.15.6.
Step 9 - Connect your GitHub repository
Atlantis needs three things to act on a repository:
- A bot user and access token, so it can read the repository and write pull request comments.
- A shared webhook secret, so it can verify incoming webhooks.
- A repo-allowlist that names the repositories it may touch.
The image ships sample values for these in /etc/atlantis/atlantis.env. You replace them with your own.
On GitHub, create a Personal Access Token (classic) with the repo scope for a bot user, and choose a random webhook secret string. Then edit the environment file on the VM:
sudo nano /etc/atlantis/atlantis.envSet these four values, using your own bot user, token, secret and organization:
ATLANTIS_REPO_ALLOWLIST=github.com/your-org/* ATLANTIS_GH_USER=your-github-bot-user ATLANTIS_GH_TOKEN=<set-at-first-boot> ATLANTIS_GH_WEBHOOK_SECRET=<set-at-first-boot>Restart Atlantis to apply the change:
sudo systemctl restart atlantisThe repo-allowlist supports wildcards. github.com/your-org/* allows every repository in your organization, and github.com/your-org/infra allows a single repository. Atlantis refuses any pull request from a repository that does not match the allowlist.
Step 10 - Add the webhook to your repository
In your GitHub repository, open Settings, then Webhooks, then Add webhook. Configure these fields:
- Payload URL:
http://<vm-public-ip>/events - Content type:
application/json - Secret: the same value you set for
ATLANTIS_GH_WEBHOOK_SECRET - Events: select Let me select individual events, then tick Pull requests, Pushes and Issue comments
Save the webhook. GitHub sends a ping, which Atlantis verifies against the shared secret.
The /events endpoint is intentionally served without HTTP Basic authentication. The webhook secret is its authentication, because GitHub cannot send Basic-auth credentials.
Step 11 - Try it on a pull request
Add a Terraform configuration to your repository and open a pull request that changes it. Atlantis automatically comments with the terraform plan output. The workspace is now Locked, which you can see in the Locks section of the web UI.
Comment atlantis apply on the pull request to run terraform apply. Comment atlantis unlock, or merge the pull request, to release the lock.
The startup log confirms that Atlantis is listening and shows which VCS host it supports:
GitLab, Bitbucket and Azure DevOps work the same way. Set the corresponding ATLANTIS_GITLAB_*, ATLANTIS_BITBUCKET_* or ATLANTIS_AZUREDEVOPS_* variables instead of the ATLANTIS_GH_* ones, and point that provider's webhook at /events.
Enabling HTTPS
The nginx reverse proxy terminates plain HTTP on port 80. Webhooks carry your repository contents and plan output, so put TLS in front of Atlantis for any non-trivial use.
Add a DNS name for the VM, then choose one of two routes. Use the companion SecureAnyCloud nginx-ssl-certbot image as a TLS reverse proxy. Or install certbot and extend the existing nginx site with a "listen 443 ssl;" server block and your certificate paths.
After you add TLS, set your webhook Payload URL to the https:// address. Update ATLANTIS_ATLANTIS_URL in /etc/atlantis/atlantis.env to match.
Maintenance
- Configuration: all Atlantis server flags live in
/etc/atlantis/atlantis.envasATLANTIS_-prefixed variables. Edit the file and runsudo systemctl restart atlantisto apply changes. - Repository configuration: commit an
atlantis.yamlto your repository to control workspaces, the Terraform version per project, and apply requirements, such as requiring pull request approval before apply. - Upgrades: replace
/usr/local/bin/atlantisor/usr/local/bin/terraformwith a newer release and restart the service. - Security patches: unattended-upgrades stays enabled, so the OS keeps receiving security updates automatically.
Support
SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.
Atlantis and the Atlantis logo are projects of the runatlantis open-source community. Terraform is a registered trademark of HashiCorp, Inc. SecureAnyCloud is not affiliated with or endorsed by the Atlantis project or HashiCorp. Atlantis is distributed under the Apache License 2.0.
Deploy on Azure
Launch Atlantis Terraform Automation on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Atlantis is an open source server that automates Terraform and OpenTofu pull request workflows. It listens for webhooks from your Git provider and runs plan and apply on your pull requests. It posts the plan output back to the pull request as a comment and locks each workspace, so two changes cannot touch the same state at once.
This image runs Atlantis 0.46 (Apache-2.0) on Ubuntu 24.04 LTS. The single Go binary is run by an unprivileged atlantis system account under a systemd service that starts it on boot and restarts it on failure.
What you get:
- OpenTofu, not Terraform. OpenTofu 1.12 (Mozilla Public License 2.0) is installed at
/usr/local/bin/tofu, and Atlantis is configured withATLANTIS_DEFAULT_TF_DISTRIBUTION=opentofuso it drives OpenTofu. OpenTofu is a fully open source, drop-in replacement for Terraform. Terraform itself moved to the Business Source License in version 1.6, so this image deliberately ships OpenTofu. If you prefer your own Terraform, you can install it and repoint the engine. - A private application port. Atlantis serves its web UI (the locks and jobs dashboard) on the loopback address
127.0.0.1:4141. Theatlantis serverprocess has no bind-address flag, so port 4141 is never opened in the security group. - Authenticated access. nginx fronts the application on port 80 and enforces HTTP Basic authentication for the dashboard, the only intended access path.
- A unique password per instance. On the first boot of every deployed instance, a one-shot service generates a fresh web password. It writes the password into the nginx htpasswd file and to
/root/atlantis-credentials.txt(mode0600, root only), and sets the Atlantis base URL to the instance's public IP. Two instances launched from the same AMI never share a password, and no default password ships in the image. - Safe defaults until you connect version control. The image ships with non-functional sample VCS credentials and a deny-all repository allowlist. The server starts and serves its dashboard, but it acts on no repository until you add your own GitHub, GitLab, Bitbucket or Azure DevOps credentials, webhook secret and allowlist (Step 7). Nothing is automated behind your back.
- A minimal default security group. The default security group for this listing opens port 22 (SSH) and port 80 (HTTP) only.
Prerequisites
- An AWS account subscribed to this product in AWS Marketplace.
- An EC2 key pair in your target region for SSH access.
- A security group that allows inbound TCP 22 (SSH) from your IP and TCP 80 (HTTP) from your users. If you connect a repository, also allow TCP 80 from your Git provider's webhook egress.
- Recommended instance type:
m5.largeor larger.
Connecting to your instance
SSH in as the default login user for your operating system variant, using the key pair you launched with.
OS variant Login user Example
Ubuntu 24.04 ubuntu ssh -i your-key.pem ubuntu@<instance-public-ip>
Step 1 - Launch from the AWS Marketplace console
- Open the product page in AWS Marketplace and choose Continue to Subscribe, then Continue to Configuration.
- Select the software version and your AWS Region, then choose Continue to Launch.
- Choose an instance type (
m5.largeor larger), your VPC subnet, the security group described above, and your EC2 key pair. - Launch the instance and wait for it to reach the running state with status checks passed.
Step 2 - Launch from the AWS CLI (alternative)
Run the command below, replacing the AMI ID, key name, security group and subnet with your own values:
aws ec2 run-instances \
--image-id ami-xxxxxxxxxxxxxxxxx \
--instance-type m5.large \
--key-name your-key \
--security-group-ids sg-xxxxxxxx \
--subnet-id subnet-xxxxxxxx \
--metadata-options "HttpTokens=required" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=atlantis}]'Step 3 - Retrieve the per-instance web password
SSH to the instance and read the credentials file that was written on first boot. The file is mode 0600 and owned by root, so read it with sudo:
sudo cat /root/atlantis-credentials.txtThe file shows the unique URL and web password generated for this instance:
# Atlantis - generated on first boot by atlantis-firstboot.service
# This password is unique to this instance. Store it somewhere safe. ATLANTIS_URL=http://203.0.113.10/ ATLANTIS_WEB_USER=admin ATLANTIS_WEB_PASSWORD=... (unique per instance)Step 4 - Sign in to the Atlantis dashboard
Browse to http://<instance-public-ip>/ and sign in with user admin and the password from Step 3.
The dashboard shows the workspace Locks, the running Jobs and the apply-lock controls. Locks and Jobs stay empty until you connect a repository.
Step 5 - Verify the service and the OpenTofu engine
On the instance, confirm that both services are active and check the Atlantis and OpenTofu versions. The unauthenticated liveness endpoint returns {"status":"ok"}:
systemctl is-active atlantis nginx atlantis version tofu version | head -1 curl -s http://127.0.0.1/healthzYou can also open the liveness endpoint in a browser at http://<instance-public-ip>/healthz. It needs no authentication, so load balancers and probes can reach it directly:
The dashboard itself refuses unauthenticated requests and accepts the per-instance password. Substitute the password from Step 3:
# Without credentials the dashboard is refused (401)
curl -s -o /dev/null -w 'no-auth: %{http_code}\n' http://127.0.0.1/
# With the per-instance admin password it succeeds (200)
curl -s -o /dev/null -w 'auth: %{http_code}\n' -u admin:YOUR_PASSWORD http://127.0.0.1/Step 6 - Run the bundled OpenTofu plan round-trip self-test
Every instance ships a small self-test that runs a real OpenTofu plan through the same engine Atlantis drives. It proves that the plan machinery works end to end before you connect any repository. Run it as the atlantis service user:
sudo -u atlantis bash /opt/sac/atlantis-selftest/plan-proof.shThe self-test runs tofu init, tofu plan and tofu show against a tiny bundled configuration. It asserts that the known resource is planned for creation and that the known value appears in the saved plan, then prints PLAN_PROOF_OK.
To inspect the plan yourself, copy /opt/sac/atlantis-selftest/main.tf into a working directory owned by the atlantis user and run tofu init then tofu plan. The plan reports one resource to add:
# terraform_data.sac_plan_probe will be created + resource "terraform_data" "sac_plan_probe" { + input = "sac-atlantis-plan-proof" } Plan: 1 to add, 0 to change, 0 to destroy.Step 7 - Connect your Git provider and webhook
Atlantis does nothing until you connect it to your own version control. Edit the environment file and replace the sample values:
sudo nano /etc/atlantis/atlantis.envSet your VCS credentials and replace the deny-all allowlist with your own repositories. For GitHub:
ATLANTIS_GH_USER=your-github-user ATLANTIS_GH_TOKEN=<set-at-first-boot> ATLANTIS_GH_WEBHOOK_SECRET=<set-at-first-boot> ATLANTIS_REPO_ALLOWLIST=github.com/your-org/*GitLab, Bitbucket and Azure DevOps work with the equivalent ATLANTIS_GITLAB_*, ATLANTIS_BITBUCKET_* and ATLANTIS_AZUREDEVOPS_* variables. Restart Atlantis to apply the change:
sudo systemctl restart atlantisThen add a webhook in your repository that points at your instance:
- Payload URL:
http://<instance-public-ip>/events - Content type:
application/json - Secret: the same value as
ATLANTIS_GH_WEBHOOK_SECRET - Events: Pull requests, Pushes, Issue comments
Open a pull request and comment atlantis plan. Atlantis clones the repository, runs the OpenTofu plan and posts the result back on the pull request.
Step 8 - Enable HTTPS (recommended)
A continuous-delivery server that can run apply against your cloud is a high-value target, so run it over TLS. You can terminate HTTPS at an upstream AWS Application Load Balancer or CloudFront. Or you can install a certificate directly on the instance with Let's Encrypt:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.comPoint your webhook at the https:// URL once TLS is in place.
Step 9 - Maintenance
- Configuration:
/etc/atlantis/atlantis.envholds the server flags, VCS credentials and allowlist. - Service management:
sudo systemctl status atlantisandsudo systemctl status nginx. - Web password: stored in
/root/atlantis-credentials.txt. To rotate it, edit the nginx htpasswd withsudo htpasswd /etc/nginx/.htpasswd adminand reload nginx. - Logs:
sudo journalctl -u atlantis -f. - Data: ephemeral repository clones and plan working directories live under
/var/lib/atlantis. Durable infrastructure state lives in your own OpenTofu or Terraform backend, not on this instance.
Support
SecureAnyCloud provides 24/7 technical support for this product by email and live chat, with a one-hour average response for critical issues. Our engineers help with deployment, connecting Git providers and webhooks, repository allowlists, workflow customization, OpenTofu, TLS termination and upgrades.
- Email: sales@secureanycloud.com
- Live chat: available 24/7 at secureanycloud.com
Deploy on AWS
Launch Atlantis on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com