Welcome to Railroad, Railcar's companion project. A repository with Ansible playbooks and roles to configure a Ubuntu 20.04 server with a Rails 7 environment (Rbenv, Nginx, LetsEncrypt/TLS, Unicorn, and Postgres).
The build.yml
playbook, as currently set up, is not idempotent. The most effective way to utilize this playbook is through tag slicing. For instance, to update the nginx config for the Rails app, run ansible-playbook -i inventory/production playbooks/build.yml -v --diff --tags=nginx-site-config
.
To achieve idempotency, you can move the destructive roles into a separate playbook. The prime candidates for this move would be the nginx-reverse-proxy
and nginx-certbot
roles. Further implementing logic to determine when to reload a service, rather than restarting it, could also improve idempotency.
Ensure ssh-agent is operational by running:
pkill ssh-agent && eval `ssh-agent` && ssh-add ~/.ssh/id_rsa.
Update your .ssh/config
to enable KeyForwarding to your host. See GitHub's SSH agent forwarding guide.
After configuring the project, run the ansible-playbook
command to apply the roles and confgs to the production server.
ansible-playbook -i inventory/production playbooks/build.yml -v --diff
- Create a local Python virtual environment with
make venv
. - Activate the environment using
source venv/bin/activate
. - Install Ansible and its dependencies with
make install
.
This project uses Ansible Vault to store secrets and keys.
- With the virtual environment active,
run ENV=production make ansible_vaults
to set up the Ansible Vault password and create empty vault files. - Generate a secret key with
bin/rails secret
from a Rails app root directory. Assign this tov_secret_key_base
in your vault. - Generate a random password for PostgreSQL database access and assign to
v_app_db_user_password
.
- Replace
1.1.1.1
ininventory/production
with your server's IP. - Set
server_name
to your domain ininventory/group_vars/production/vars.yml
. Ensure DNS entry matches IP above. - Assign
admin_email
to your email where LetsEncrypt will send expiry notifications.
- Update
ssh_key
for rails user ininventory/group_vars/production/vars.yml
with your public SSH key. - Replace shey with your preferred login username and update the
ssh_key
.
- Always protect your host with a firewall.
- The method for handling secrets is best suited for a one or two-person team.
- The
build.yml
playbook is not idempotent.