Self Hosting Atlantis
I’ve been interacting with Atlantis at work. But I am not responsible for its deployment or configuration, it was a bit of a magic black box.
Considering I use some terraform for managing my personal Cloudflare DNS settings, I figured I may as well try and get Atlantis setup for my own use!
Not every step will be documented here, this is not intended to be a full walkthrough.
I will attempt to link the relevant documentation I used.
The problem
So there were a few requirements I had to meet before setting this into the wild.
- I must self host the Atlantis service
- GitHub is my go to repo host, it must be able to reach Atlantis
- No exposing Atlantis completely to the entire internet
Attempt one
I attempted to first try using Tailscale Funnel and mapping atlantis to Tailscale in docker from this example
This worked great, I self hosted Atlantis and can access it externally! ✅
Unfortunately as much as Tailscale is awesome the ACLs do not support controlled access to services hosted with funnel. ❌
Attempt Two (Success)
Revisiting the toolbox of poking safe holes through my firewall, and since I am already using Cloudflare for my DNS, I looked at their Cloudflare Tunnel offering.
After creating a tunnel I was quickly able to access to Atlantis over the open internet. ✅
Thankfully unlike Tailscale, Cloudflare does have a WAF that works alongside the tunnel to control access. ✅
Grabbing the webhook CIDR blocks from GitHub Meta API I quickly put together a WAF rule to block access:
1
(not ip.src in {192.30.252.0/22 185.199.108.0/22 140.82.112.0/20 143.55.64.0/20} and http.host eq "atlantis.domain.ca")
Putting it together
Following the Atlantis GitHub app docs I was able to meet all my personal requirements.
I ended up with the following docker-compose.yml
that binds the Atlantis containers networking to the cloudflared
container.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
---
version: "2.2"
services:
atlantis:
image: ghcr.io/runatlantis/atlantis:latest
restart: unless-stopped
volumes:
- ${PWD}/config:/config
- ${PWD}/data:/data
environment:
ATLANTIS_CONFIG: /config/atlantis.yml
ATLANTIS_DATA_DIR: /data
AWS_ACCESS_KEY_ID: <Access Key ID>
AWS_SECRET_ACCESS_KEY: <Secret Key>
AWS_REGION: us-west-2
CLOUDFLARE_API_TOKEN: <Cloudflare Access Token>
networks:
- atlantis
tunnel:
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel run
environment:
- TUNNEL_TOKEN=<Your CF Tunnel Token>
networks:
- atlantis
volumes:
tailscale-data-atlantis:
networks:
atlantis:
Most importantly, I can now safely access the Atlantis UI locally, and the webhooks from GitHub work great! Now I can atlantis plan
and atlantis apply
on my terraform PRs for my personal cloud infrastructure! ✅
The Atlantis UI is safely accessible
GitHub interactions are automated and work great!
Extra notes
My terraform code is private, so I will not be sharing that. Additionally Atlantis specifically calls out not to use public repos. Setting up terraform is an exercise for the reader.