Using pre_tasks to install a role right before using it on a managed node?

I don’t know if this is a normal use-case but I am using packer.io and the local ansible provisioner to build docker images. I wanted to use a pre_task to actually install the role and then immediately use the role on a managed node. The problem is that I think there is a sanity check that runs before the pre_tasks actually gets called to make sure the referenced roles actually exist. So the play will fail with a message the role does not exist in which wouldn’t be true if the pre_tasks ran first. Is my assumption of this sanity check correct and is there a recommended approach? I can have packer upload the role to my docker image if need be but I thought there might be a cleaner way.

See the following simple example playbook:

  • name: Install openldap

hosts: all

sudo: True

pre_tasks:

  • name: Install the openldap role

command: ansible-galaxy install bennojoy.openldap_server creates=/etc/ansible/roles/bennojoy.openldap_server

roles:

  • role: bennojoy.openldap_server

openldap_server_domain_name: example.com

openldap_server_rootpw: passme

openldap_server_enable_ssl: true

openldap_server_country: US

openldap_server_state: Oregon

openldap_server_location: Portland

openldap_server_organization: IT

root@archvile:~/packer/openldap_server-packer# sudo packer build -var-file=variables.json packer.json

docker output will be in this color.

==> docker: Creating a temporary directory for sharing data…

==> docker: Pulling Docker image: jgrowl/ubuntu-ansible

docker: Pulling repository jgrowl/ubuntu-ansible

==> docker: Starting docker container…

docker: Run command: docker run -d -i -t -v /tmp/packer-docker258851345:/packer-files jgrowl/ubuntu-ansible /bin/bash

docker: Container ID: aa033de85e2009aea6d808ce9dc2ca5ae0dab7008b1de9de890955cf38d39780

==> docker: Provisioning with Ansible…

docker: Creating Ansible staging directory…

docker: Creating directory: /tmp/packer-provisioner-ansible-local

docker: Uploading main Playbook file…

docker: Executing Ansible: cd /tmp/packer-provisioner-ansible-local && ansible-playbook /tmp/packer-provisioner-ansible-local/openldap_server.yml -c local -i “127.0.0.1,”

docker: ERROR: cannot find role in /tmp/packer-provisioner-ansible-local/roles/bennojoy.openldap_server or /tmp/packer-provisioner-ansible-local/bennojoy.openldap_server or /etc/ansible/roles/bennojoy.openldap_server

==> docker: Killing the container: aa033de85e2009aea6d808ce9dc2ca5ae0dab7008b1de9de890955cf38d39780

Build ‘docker’ errored: Error executing Ansible: Non-zero exit status: 1

not a sanity check, the playbook gets ‘compiled’ before running.​

yeah I can’t guarantee this will work even if it happened to work now.

A better idea might be to have a requirements file and run “ansible-galaxy” (the CLI) against the requirements_file to slurp it all in. See ansible-galaxy --help for details.

If you have private roles, I recommend configuring the roles path in ansible.cfg, which it would be nice if this was exposed to Packer - not sure offhand if it is.