When trying to pass a var that is normally a list in ansible, I cannot do this in packer.
provisioner "ansible" {
playbook_file = "./ansible/houdini_module.yaml"
extra_arguments = [
"-vv",
"--extra-vars",
"houdini_major_version_list=[19.0]",
]
}
In my playbook if I test the length of houdini_major_version_list with {{ houdini_major_version_list|length }}
it says the length is 6, when it should be 1.
What is the correct way to pass a list using --extra-vars in packer?
CodePudding user response:
The problem is that the extra variable -e, --extra-vars
in key=value format is always a string. Given the variable below, declared anywhere in a code,
l: [19.0]
the result of the task below is as expected
- debug:
msg: |-
l|type_debug: {{ l|type_debug }}
l|length: {{ l|length }}
l.0|type_debug: {{ l.0|type_debug }}
l.0: {{ l.0 }}
msg: |-
l|type_debug: list
l|length: 1
l.0|type_debug: float
l.0: 19.0
But, when you declare this variable at the command line in the k=v
format the type is a string and the length of this string is 6
shell> ansible-playbook playbook.yml -e l=[19.0]
...
msg: |-
l|type_debug: str
l|length: 6
l.0|type_debug: str
l.0: [
To fix this, use JSON string format
shell> ansible-playbook pb1.yml -e '{"l": [19.0]}'
...
msg: |-
l|type_debug: list
l|length: 1
l.0|type_debug: float
l.0: 19.0
The YAML format gives the same result
shell> ansible-playbook playbook.yml -e "l: [19.0]"
Optionally, put the variable into a JSON or YAML file. It's practical when declaring more variables. For example
shell> cat some_file.yml
l: [19.0]
k: [20.0]
would give
shell> ansible-playbook playbook2.yml -e "@some_file.yml"
...
msg: |-
l.0: 19.0
k.0: 20.0
Convert the variable on you own if you're not able to change the format of the command. For example,
- set_fact:
l_local: "{{ l.split('=')|last|from_yaml }}"
- debug:
msg: |-
l_local|type_debug: {{ l_local|type_debug }}
l_local|length: {{ l_local|length }}
l_local.0|type_debug: {{ l_local.0|type_debug }}
l_local.0: {{ l_local.0 }}
Then, the command gives
shell> ansible-playbook playbook.yml -e "l=[19.0]"
...
msg: |-
l_local|type_debug: list
l_local|length: 1
l_local.0|type_debug: float
l_local.0: 19.0
You can't override the extra variable, i.e l
in this case, because the extra vars
is the highest precedence.
CodePudding user response:
The other answer is instructive in explaining why the type is incorrect as a variable input to Ansible through the CLI. The update to the Packer HCL2 template to satisfy this requirement and solve your problem would be:
provisioner "ansible" {
playbook_file = "${path.root}/ansible/playbook.yaml"
extra_arguments = [
"-vv",
"--extra-vars",
jsonencode({ "houdini_major_version_list" = ["19.0"] }),
]
}
setting the env var PACKER_LOG=1
we see that this executes:
ansible-playbook ... -vv --extra-vars {"houdini_major_version_list":["19.0"]} ... /path/to/playbook.yaml
This demonstrates the interfacing between Packer and the Ansible provisioner is now correct for passing a list
type variable.
Note that jsonencode({ "houdini_major_version_list" = [19.0]
results in {"houdini_major_version_list":[19]}
because the float automatically drops the .0
.