The conditional check 'missing_hosts | count' failed

Trying to provision a new staging server.
Latest Trellis with head up to #735.
No SSL enabled on any of the sites.
I receive the following error:

TASK [letsencrypt : Create needed Nginx confs for challenges] ******************
System info:
  Ansible; Linux
  Trellis at "Add `apt_packages_custom` to customize Apt packages"
The conditional check 'missing_hosts | count' failed. The error was: {{
site_uses_letsencrypt | ternary(site_hosts, []) |
difference((current_hosts.results | selectattr('item.key', 'equalto',
item.key) | selectattr('stdout_lines', 'defined') |
sum(attribute='stdout_lines', start=[]) | map('trim') | list | join('
')).split(' ')) }}: no test named 'equalto'

The error appears to have been in
'/home/my/path/to/trellis/roles/letsencrypt/tasks/nginx.yml': line
16, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- name: Create needed Nginx confs for challenges
  ^ here

I see that Jinja2 Version 2.8 was released July 26th, 2015 and includes equalto:

• Added equalto filter that helps with select filters.

You could check whether your version of Jinja2 is at least 2.8:

pip show Jinja2

You could use pip to update Jinja2 if necessary. That’s not something I’ve updated manually before, so I’m not sure what you might run into.

If you can’t update Jinja2, you might avoid the problem by skipping the Let’s Encrypt role, given that you’re not using it:

ansible-playbook server.yml -e env=production --skip-tags letsencrypt

As a last resort, you could comment out the instances of missing_hosts, which isn’t a good or permanent solution, but might get you back up and running.

Thanks for your response.
That’s Jinja2 on my own machine right?
I’ve updated from 2.7.2 to 2.9.5, rebooted and on reprovision of staging I still receive the same error.

Yep, whichever machine is your local Ansible “control machine,” where you run the ansible-playbook command. Looks like you’re probably running some flavor of Linux as your dev machine – that’s the machine in question. If you’re actually running Windows and running ansible commands inside a vagrant VM, you’d need to be sure the VM has a Jinja2 version 2.8+ (I’d be surprised if it didn’t already).

Edit. Actually, Ansible seems to interact with the python on the remote machine too, so I guess it’s worth checking the Jinja2 version on your remote, just for the sake of more info/leads. Maybe that’s naive. I just don’t know. /edit

If pip show jinja2 now shows version 2.8 or higher, then I’m a bit stumped. This is not a familiar issue to me but searching around it looked like most people solve it by updating Jinja2 directly.

Perhaps there are other factors at play that I don’t understand, like which versions of Jinja2 might be packaged with python, or if you’re using something like virtualenv or pyenv to manage different python versions on your machine. You might check your python version and potentially update. Ansible seems to run best on 2.7.x (but not yet on python 3).

^ Maybe it’ d be simpler to just comment out the letsencrypt role in server.yml instead.

I appreciate your help. Still no luck though, same error when provisioning a fresh droplet.
I’m on Ubuntu 14.04 not a VM in Windows, also Python 2.7.6 and Jinja2 2.9.5.

I could comment out letsencrypt on staging, but wouldn’t I then run into the same issue provisioning a production server? Where I do have SSL enabled.

You’re right. It won’t work to comment out the letsencrypt role if you use Let’s Encrypt for production.

If you’re up to it, it might be worth a shot to update python on your local machine, perhaps to 2.7.13, or at least to 2.7.11 (released around December 2015).

If you’re running 2.7.6, it looks like it was released roughly November 2013 so maybe it struggles to run the equalto feature that arrived in Jinja2 around mid 2015.

If nothing else works, you could use these edits to avoid the equalto test.
(tested minimally)

# roles/letsencrypt/defaults/main.yml

  site_uses_letsencrypt: "{{ ssl_enabled and item.value.ssl.provider | default('manual') == 'letsencrypt' }}"
- missing_hosts: "{{ site_uses_letsencrypt | ternary(site_hosts, []) | difference((current_hosts.results | selectattr('item.key', 'equalto', item.key) | selectattr('stdout_lines', 'defined') | sum(attribute='stdout_lines', start=[]) | map('trim') | list | join(' ')).split(' ')) }}"
+ current_hosts_nginx: "{% for host in current_hosts.results if host.item.key == item.key and host.stdout_lines is defined %}{{ host.stdout_lines | map('trim') | list }}{% endfor %}"
+ missing_hosts: "{{ site_uses_letsencrypt | ternary(site_hosts, []) | difference(current_hosts_nginx) }}"

In short, it replaces selectattr(attr, 'equalto', val) with {% for x in y if z %}.

You might even try just putting those two new/revised vars in group_vars/all/main.yml and not edit roles/letsencrypt/defaults/main.yml at all. But maybe the error will persist until you remove or comment out the old missing_hosts.

I think selectattr is probably a more appropriate tool for the job, however, so I don’t think Trellis core should change unless more users report experiencing this problem.

1 Like

Thanks for your support Phil. Based on your analysis that it probably had to do with an outdated or incompatible version of something on my system, I’ve reinstalled and updated my system to 16.04. Server provisioning works fine now.