Packer validate fails when using ansible galaxy

I’m writing a packer file that use a galaxy collection and ansible provisioner:

provisioner "ansible" {
    user          = "${var.username}"
    playbook_file = "${var.home}/.ansible/collections/ansible_collections/devops/playbooks/basic.yml"
    extra_arguments = [
      "--extra-vars", "install_docker=true", "-vvvv", "--scp-extra-args", "'-O'"
    ]
    ansible_ssh_extra_args = [                                                    
      "-oHostKeyAlgorithms=+ssh-rsa -oPubkeyAcceptedKeyTypes=+ssh-rsa"
    ]  
    galaxy_file = "collection-requirements.yml"
  }

The execution fails with the following error:

Error: Failed preparing provisioner-block "ansible" ""

on main.pkr.hcl line 29:
(source code not available)

1 error(s) occurred:

* playbook_file:
/home/me/.ansible/collections/ansible_collections/devops/playbooks/openvpn.yml
is invalid: stat
/home/me/.ansible/collections/ansible_collections/devops/playbooks/openvpn.yml:
no such file or directory

Packer wants to check if the file exists, but those playbook files are not meant to be there until packer will pull the galaxy ansible collection. Interestingly, if I just create the folder structure, and touch an empty openvpn.yml file, validate will work, packer starts, pulls all the collection correctly overwriting the empty file, and runs the playbook remotely as expected.

Is there any way to avoid such check? Ansible provisioner and galaxy support is especially convenient in order to avoid a manual galaxy collection prior the packer execution, which is actually performed later by packer itself. Why so packer is looking for a file that are later downloaded by packer itself? That is actually forcing me to pre-install the collection, defeating the purpose of the galaxy_file support. I’m wondering if is a bug or my misunderstanding of the ansible provisioner. Can you please advise?

1 Like

Same issue on my side, how to avoid to “manually” install dependencies before packer execution?

Hi @NGAJean,

You can define the required plugins under packer.required_plugins, and when you do a packer init the dependencies will be automatically downloaded.

ref:

Thanks @Ranjandas for your answer but the original question was a little different.
I found the answer by myself.
I share my solution here to help another persons which may encounter the same problem.

With my words:

  • galaxy_file refer to all ansible requirements (collections/roles) that will be used by the playbook_file
  • playbook_file is the playbook that will be executed by packer which will use collections/roles installed through galaxy.

So playbook_file directive shouldn’t refer to a downloaded file, it have to be defined locally.

1 Like

Thank you for explaining this! This was driving me nuts. The implementation is not good with modern ansible since we can now have playbooks IN collections. In this case there is no way to get this to work without downloading the collection and caching it locally.