Strategy for skipping sites that need to work when adding new sites

I have a dev server that faces web… so think of it like a production server that receives no traffic. It’s a fairly big server and I have dozens of sites on it… currently I have close to 30.

When I add a new site, I run the provision script with letsencrypt/wordpress tags only but it still takes a long time to iterate through all the tasks for the existing sites that don’t need any changes at all.

I suppose I could add a new variable in the wordpress_sites.yml to skip existing sites… or I may as well remove them altogether since they really don’t need to be present there anymore after they’ve been setup and the cron jobs are setup for letsencrypt renewal (if needed)

But I wish there was a cleaner more efficient way to handle this… a way for the ansible job to keep track of sites that have been entirely set up correctly and can be skipped on further provision jobs

Has anyone come up with a decent strategy for handling this?

@fullyint had a proposal for Trellis “2.0” which would easily support this, but I don’t believe there’s a way to do this currently. Maybe Phil has an idea to kind of hack it with the current setup.

@vesper8 I’m sympathetic to how long it can take to loop through a long collection of wordpress_sites when you’re only trying to update one or two of them. Indeed one way around it is to temporarily comment out all but the target site in wordpress_sites.

An (untested) alternative might be to

  1. add an underscore to (each instance of) the name of the wordpress_sites variable:
- wordpress_sites:
+ _wordpress_sites:
    (stuff)
  1. add this new var to group_vars/all/helpers.yml
wordpress_sites: '{
  {% for _site,data in _wordpress_sites.items() if _site in site | default(sites | default(_wordpress_sites.keys())) %}
  "{{ _site }}": {{ data }},
  {% endfor %}
}'

Then you can run commands like:
ansible-playbook server.yml -e env=production -e site=example.com
or
ansible-playbook server.yml -e env=production -e sites=example.com,site2.com

Suppose you have a group of sites and don’t want to type them out each time. You could create a file listing the sites…

# trellis/sites_group_1.yml
sites:
  - example.com
  - site2.com
  - site3.com

then tell Ansible to use that file for your extra_vars
ansible-playbook server.yml -e env=production -e @sites_group_1.yml

Note that I’ve suggested NOT putting that sites_group_1.yml file in the group_vars directory, because that would make Ansible always read it and always use that subset of sites, which is probably not what you want.

Subsetting sites is useful when you need to update just one site’s Nginx conf (e.g., just running --tags wordpress). Subsetting is also useful if you just changed DNS and want to set up a Let’s Encrypt cert for some specific site.

:warning: Note that if you run the letsencrypt role on a subset of sites, you’ll need to go back later and rerun the role on the entire site list so that the renew-certs.py script that cron runs will cover ALL your sites. If you forget to rerun letsencrypt for all sites then I think you’ll have some sites’ certs fail to renew eventually.

4 Likes