To deploy a second site

Goal. Site-1 on server-1, site-2 on server-2.

Trellis defaults. The Trellis default is to put all sites for an environment (e.g., all sites listed in group_vars/production/wordpress_sites.yml) on all servers listed in the hosts file (aka “inventory file”) for that environment (e.g., hosts/production). As discussed above, you can easily put multiple sites on a single server just by adding multiple sites to the wordpress_sites list. If you happen to list multiple server IPs in hosts/production, that would be a step toward setting up some kind of load-balancing, where all sites are being served from all servers (oversimplification).

Those Trellis defaults don’t accommodate the scenario you asked about: “site-1 on server-1 and site-2 on server-2”. Some customization would be required. I’ll list some options that come to mind and others can critique or expand on them. UNTESTED.

Option 1: Use a second Trellis project

Attitude: “For this project, I can’t spend much time tinkering. I’ll choose the most hassle-free approach to my goal, even if it is not particularly DRY.”

You could just leave your first Trellis project for site-1 on server-1, then create another Trellis project (separate code, etc.) for site-2 on server-2. I think that is perfectly respectable and will be reasonably easy to maintain.

Option 2: Add the two IPs to your hosts file but only deploy one site to each (bad hack)

Attitude: “I’m willing to tinker, but this time I’ll go with a shortcut instead of understanding. I’ve got a hack that appears to work and I’m unconcerned about unintended consequences that may bite me in the future.”

I discourage this approach, but it might work. You could stick with a single Trellis project but add the IPs for server-1 and server-2 to your hosts/production and run server.yml. That would provision the two servers so they are ready to receive a deployment of either site. Then, only deploy site-1 to server-1 and only deploy site-2 to server-2. I wouldn’t do this. I mentioned it only to provide a little more perspective on what the various hosts files and playbook files are doing.

Option 3: Use Ansible’s host_vars

Attitude: “I’m willing to tinker and I’m committed to understanding and finding an appropriate implementation for my slightly different use-case. I understand this will be more work to apply updates from the Trellis upstream to my customized fork, but I’m comfortable with having my fingers in the code.”

To achieve “site-1 on server-1 and site-2 on server-2” you need the wordpress_sites list to differ per server/host. You can use Ansible’s host_vars in two steps.

Step 1. Adjust hosts/production

[web]
site-1 ansible_ssh_host=site.1.server.ip
site-2 ansible_ssh_host=site.2.server.ip

[production:children]
web

Step 2. Add a new host_vars directory at Trellis root (e.g., next to group_vars directory):

host_vars/
  site-1.yml
  site-2.yml

Those two .yml files are copies of wordpress_sites, each with only the site info for the given site. You could also structure it with directories per site if you want:

host_vars/
  site-1/
    wordpress_sites.yml
  site-2
    wordpress_sites.yml

Once you have that set up, you don’t need to change your ansible-playbook commands at all. Things should work as normal. You may want to edit group_vars/production/wordpress_sites.yml with a note to yourself that wordpress_sites values are actually being drawn from the host_vars files.

UNTESTED. Would love to hear if it works for you.

EDIT. The host_vars in option 3 above makes no distinction between environments (e.g., staging vs. production). Perhaps there’s an easy way to address this next level of complexity, but I haven’t explored it yet.

7 Likes