packer version
: Packer v1.2.4PACKER_LOG=1 packer build template.json
.
Executing Ansible: ansible-playbook --extra-vars packer_build_name=amazon-ebs packer_builder_type=amazon-ebs -i ../ansible/inventories/ec2/ /home/wmd/git/myrepo/ansible/coreos.yaml -e ansible_ssh_private_key_file=/tmp/ansible-key962358977 --limit default
"provisioners": [
{
"type": "ansible",
"inventory_directory": "/path/to/ansible/inventory/directory",
"playbook_file": "/path/to/ansible/playbook.yaml"
}
]
When the remote Ansible provisioner is run with inventory_directory
, the -i
option is provided to Ansible as inventory_directory
, rather than the path to the temporary inventory file in inventory_directory
. This runs counter to what is stated in the documentation:
The directory in which to place the temporary generated Ansible inventory file. ... The fully-qualified name of this temporary file will be passed to the -i argument of the ansible command when this provisioner runs ansible.
This results in the Ansible playbook running against all matching hosts in the inventory, rather than just the host being provisioned by Packer, which is extremely undesirable.
The issue can be worked around by using extra_arguments
to pass --limit
to ansible-playbook.
The error is here. The inventory
variable is replaced with the inventory directory, rather than the path to the inventory file in the inventory directory.
This might be a mistake in the documentation, but it feels much more likely that this is a bug in the code. It is NOT desirable to have Packer running Ansible against more hosts than just the one it's operating on. In my opinion, if the user actually desires that Packer should be aware of more hosts than just the one it's provisioning, they should explicitly configure that with inventory_file
. And, if they desire that this inventory should be a directory, then inventory_file
should support directories, as described in #4510. The stated purpose of inventory_directory
in the docs is to allow users to take advantage of existing host_vars and group_vars, not to be the directory version of inventory_file
.
I'm getting this same bug. It's causing ansible to recursively parse every file in inventory_directory
as an inventory file, and it will execute any bash scripts it finds.
My inventory_directory
looks like this:
inventory
playbook.yml
roles/
my-role/
files/
install.sh
tasks/
main.yml
Which means ansible tries to parse inventory
, playbook.yml
, main.yml
and install.sh
as inventory files. Which gives me a bunch of errors that look like this for every yaml file:
packer: [WARNING]: * Failed to parse
packer: roles/my-role/tasks/main.yml with
packer: ini plugin:
packer: b'roles/my-role/tasks/main.yml':2:
packer: Expected key=value host variable assignment, got: name:
When it comes across a bash script, it gets executed with the script plugin:
packer: [WARNING]: * Failed to parse
packer: roles/my-role/files/install.sh with script plugin: Inventory script
packer: (roles/my-role/files/install.sh) had an execution error:
packer: roles/my-role/files/install.sh: line 2: apt-get: command not found
packer: roles/my-role/files/install.sh: line 3: apt-get: command not found
...
and it continues to execute the script, even though it failed. Using the --limit
workaround suggested doesn't prevent ansible from parsing and executing all the files in the directory.
I agree with @geekofalltrades, this is definitely not desired behaviour.
This also causes issues with vars being defined and overridden in different inventory files, assuming you have per environment inventory files.
+1, it doesn't seem that inventory_directory behaves as it says on the documentation
I think all we need to do is revert https://github.com/hashicorp/packer/pull/6065 to get the behavior to work as documented. I think that the person who made that PR probably should have introduced a new template option. Can you confirm this for me? Here's a build of Packer 1.3.2 with that PR reverted:
Linux:
packer.zip
OSX:
packer.zip
Windows:
packer.zip
@SwampDragons I tried your build on Arch Linux (which was version 1.4.0 according to packer --version
) and the issue seems to be fixed. It loaded the inventory in the expected way.
I came across this issue when trying to use inventory_directory
as described in https://www.packer.io/docs/provisioners/ansible.html#inventory_directory .
According to ansible docs, if ansible gets a directory as inventory, it will treat it differently and it will allow you to use host_vars
and group_vars
(my desired use case).
As for packer/ansible trying to run shell scripts and YAML files, the correct solution would be to set ANSIBLE_INVENTORY_IGNORE
env var.
Should I open a new ticket or could this ticket be reopened?
I think you want #4510.
It sounds to me like you already have what you want, though:
it will allow you to use host_vars and group_vars (my desired use case)
This is what inventory_directory
does currently. Just make sure that you have the host in the right groups though, by using the groups
arg to the provisioner.
No, it doesn't.
This is the current (packer 1.3.4) ansible command that is being generated:
==> vagrant: Executing Ansible: ansible-playbook --extra-vars packer_build_name=vagrant packer_builder_type=vagrant -o IdentitiesOnly=yes -i inventory/packer-provisioner-ansible650316513 /Users/DaviVidal/Projects/ansible-ng/testing.yml -e ansible_ssh_private_key_file=/var/folders/h1/k1xskb210yx895nw0mzzk6p80000gp/T/ansible-key127423242 --skip-tags foo,bar
And here is the relevant portion of my packer.json
{
"type": "ansible",
"groups": [
"s_all_nginx",
"s_all_php",
"s_all_consul"
],
"empty_groups": [
"a_all",
"b_all",
"c_all"
],
"extra_arguments": [
"--skip-tags",
"foo,bar"
],
"inventory_directory": "inventory/",
"playbook_file": "../ansible-ng/testing.yml"
}
EDIT: what I expected was to have something like ansible-playbook -i inventory (...)
Packer was doing that temporarily. I opened this bug to specifically revert that behavior, since it results in Ansible doing a lot more than I or probably most other users would want or expect.
-i inventory/packer-provisioner-ansible650316513
is the expected behavior after this fix. If you have host_vars/
and group_vars/
defined in inventory/
, they should be getting used.
If I set inventory_directory
the expected behavior is to ignore that and use a file instead?
Yes.
https://www.packer.io/docs/provisioners/ansible.html#inventory_directory
inventory_directory (string) - The directory in which to place the temporary generated Ansible inventory file. By default, this is the system-specific temporary file location. The fully-qualified name of this temporary file will be passed to the -i argument of the ansible command when this provisioner runs ansible. Specify this if you have an existing inventory directory with host_vars group_vars that you would like to use in the playbook that this provisioner will run.
I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.