Ansible playbook to deploy vientos stack
It assumes Ubuntu 18.04TLS, playbook tested to work in LXD containers
Firs of all add entry to inventory/hosts.yml
following other existin entries and ansible inventory documentation eg.
mx:
children:
mx-staging:
hosts:
staging.vientos.coop:
ansible_host: 136.243.86.184
ansible_port: 2222
ansible_python_interpreter: /usr/bin/python3
Add configuration specific to the group of hosts you maintain to inventory/group_vars/
eg.
inventory.group_vars/mx.yml
---
ssh_key_urls:
- https://github.com/elf-pavlik.keys
language: es
country: mx
map:
latitude: 19.43
longitude: -99.13
zoom: 9
tilelayer: "https://api.mapbox.com/styles/v1/vientos/cixqjuql4002y2rrsrjy004fg/tiles/256/{z}/{x}/{y}@2x?access_token=
Configuration specific to each host goes to inventory/host_vars/
, you need to create a directory for each host with two files in it config.yml
and secrets.yml
(this one stays git ignored!) eg.
inventory/host_vars/staging.vientos.coop/config.yml
---
common:
env: staging
backups:
destination: user@domain.tld:backups
website:
name: website
domain: staging.vientos.coop
alternative_domain: www.staging.vientos.coop
app:
name: app
domain: app.staging.vientos.coop
service:
name: service
domain: data.staging.vientos.coop
port: 8000
idp:
name: idp
domain: idp.staging.vientos.coop
port: 8001
webhooks:
name: webhooks
domain: webhooks.staging.vientos.coop
port: 8002
To disable any of the services simply leave its domain
undefined eg.
common:
env: staging
website:
name: website
app:
name: app
service:
name: service
domain: data.staging.vientos.coop
port: 8000
idp:
name: idp
webhooks:
name: webhooks
inventory/host_vars/staging.vientos.coop/secrets.yml
---
secrets:
common:
letsencryptEmail: # email used to agree to Let's encrypt Terms of Service
fromEmail: # email used as *From* in emails sent by service and idp
mailjet:
public: # get it from https://app.mailjet.com/account/api_keys
secret: # get it from https://app.mailjet.com/account/api_keys
app:
sentry: # get it from https://sentry.io/settings/
google:
apiKey: # get it from https://console.developers.google.com
cloudinary:
cloud: # get it from https://cloudinary.com/console
preset: # get it from https://cloudinary.com/console/settings/upload
service:
cookie: # generate eg. openssl rand -base64 32
sentry: # get it from https://sentry.io/settings/
google:
clientId: # get it from https://console.developers.google.com
clientSecret: # get it from https://console.developers.google.com
gcmApiKey: # get it from https://console.developers.google.com
facebook:
clientId: # get it from https://developers.facebook.com/
clientSecret: # get it from https://developers.facebook.com/
idp:
cookie: # generate eg. openssl rand -base64 32
sentry: # get it from https://sentry.io/settings/
clientId: # choose one eg. staging-idp
clientSecret: # generate eg. openssl rand -base64 32
webhooks:
secret: # set in https://github.com/vientos/{repo}/settings/hooks
ansible-playbook site.yml
For testing purposes Let's Encrypt provides a staging environemnt
ansible-playbook site.yml --extra-vars "letsencrypt_staging=yes"
- Cloudinary - http://cloudinary.com
- Google - https://console.developers.google.com
- Firebase - https://console.firebase.google.com
- Facebook - https://developers.facebook.com/
- Sentry - https://sentry.io
- Github - https://github.com
Included nginx blocks configuration includes
- listens on IPv4 and IPv6 interfaces
- uses HTTP/2
- enables gzip compression
- uses Let's Encrypt certificates
- redirects HTTP to HTTPS
- servers
index.html
for app if requested path doesn't exist - disables buffering on data service (needed for Server Sent Events to work)
- sets max body size
Systemd manages deployed serivces as user units, systemctl --user
provides interface to them e.g.
systemctl --user status vientos-service
In similar way journalctl --user
provides interface to see logs of those services e.g.
journalctl --user -u vientos-service
Commands above should get executed as unpriviledged user, by default vientos
.
If you specified destination for backups in the config.yaml
of particular host
(e.g backups.destination: user@domain.tld:backups
) it will install a cron job
which daily runs backup script which does following steps:
- dumps compressed mongo databases to
~/backups
- rsyncs
~/backups
to specified destination
It will use ssh key generated for unpriviledged user (vientos
by default).
To to bootstrap authentication manually do following steps:
- append content of
/home/vientos/.ssh/id_rsa.pub
to~/.ssh/authorized_keys
on the destination server - as
vientos
user on deployed host, try ssh to specified destination server and accept adding its key fingreprint to the list of known hosts
Setup follows: https://www.digitalocean.com/community/tutorials/how-to-host-multiple-web-sites-with-nginx-and-haproxy-using-lxd-on-ubuntu-16-04
Required for journalctl --user
to work, if you have ZFS filesystem for staging
container in default
pool
sudo zfs set acltype=posixacl default/containers/staging
sudo zfs set xattr=sa default/containers/staging
Otherwise journalctl --user
results in error Failed to search journal ACL: Operation not supported
We need to forward ports 80
and 443
to haproxy container
sudo iptables -A PREROUTING -t nat -i your_network_dev -p tcp --dport 80 -j DNAT --to-destination your_haproxy_ip:80
sudo iptables -A PREROUTING -t nat -i your_network_dev -p tcp --dport 443 -j DNAT --to-destination your_haproxy_ip:443
As well as map custom SSH ports to coresponding containers
sudo iptables -A PREROUTING -t nat -i your_network_dev -p tcp --dport your_custom_ssh_port -j DNAT --to your_container_ip:22
sudo iptables -A FORWARD -p tcp -d your_container_ip --dport 22 -j ACCEPT
To remove those mappings simply replace iptables -A
with iptables -D
Make sure you make those rules persistent
sudo apt-get install iptables-persistent
every time you change them
sudo netfilter-persistent save
You can import SSH keys from github using ssh-import-id