Home > Mobile >  how to set a variable as a list in packer for ansible?
how to set a variable as a list in packer for ansible?

Time:05-17

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.

  • Related