如何在 ansible 的加壳器中将变量设置为列表?
how to set a variable as a list in packer for ansible?
当试图传递通常是 ansible 中的列表的 var 时,我无法在 packer 中执行此操作。
provisioner "ansible" {
playbook_file = "./ansible/houdini_module.yaml"
extra_arguments = [
"-vv",
"--extra-vars",
"houdini_major_version_list=[19.0]",
]
}
在我的剧本中,如果我用 {{ houdini_major_version_list|length }}
测试 houdini_major_version_list 的长度,它说长度是 6,而它应该是 1。
在加壳器中使用 --extra-vars 传递列表的正确方法是什么?
问题是 key=value format 中的额外变量 -e, --extra-vars
始终是字符串。给定下面的变量,在代码的任何地方声明,
l: [19.0]
下面的任务结果符合预期
- 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
但是,当您在命令行以 k=v
格式声明此变量时,类型为字符串且此字符串的长度为 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: [
要解决此问题,请使用 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
YAML 格式给出相同的结果
shell> ansible-playbook playbook.yml -e "l: [19.0]"
可选地,将变量放入 JSON or YAML file。声明更多变量时很实用。例如
shell> cat some_file.yml
l: [19.0]
k: [20.0]
会给
shell> ansible-playbook playbook2.yml -e "@some_file.yml"
...
msg: |-
l.0: 19.0
k.0: 20.0
如果您无法更改命令的格式,请自行转换变量。例如,
- 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 }}
然后,命令给出
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
您不能覆盖额外变量,即本例中的 l
,因为 extra vars
是 highest precedence。
另一个答案有助于解释为什么类型不正确作为通过 CLI 输入到 Ansible 的变量。满足此要求并解决您的问题的 Packer HCL2 模板更新为:
provisioner "ansible" {
playbook_file = "${path.root}/ansible/playbook.yaml"
extra_arguments = [
"-vv",
"--extra-vars",
jsonencode({ "houdini_major_version_list" = ["19.0"] }),
]
}
设置环境变量 PACKER_LOG=1
我们看到这会执行:
ansible-playbook ... -vv --extra-vars {"houdini_major_version_list":["19.0"]} ... /path/to/playbook.yaml
这表明 Packer 和 Ansible provisioner 之间的接口现在可以正确传递 list
类型变量。
请注意,jsonencode({ "houdini_major_version_list" = [19.0]
会导致 {"houdini_major_version_list":[19]}
,因为浮动会自动删除 .0
。
当试图传递通常是 ansible 中的列表的 var 时,我无法在 packer 中执行此操作。
provisioner "ansible" {
playbook_file = "./ansible/houdini_module.yaml"
extra_arguments = [
"-vv",
"--extra-vars",
"houdini_major_version_list=[19.0]",
]
}
在我的剧本中,如果我用 {{ houdini_major_version_list|length }}
测试 houdini_major_version_list 的长度,它说长度是 6,而它应该是 1。
在加壳器中使用 --extra-vars 传递列表的正确方法是什么?
问题是 key=value format 中的额外变量 -e, --extra-vars
始终是字符串。给定下面的变量,在代码的任何地方声明,
l: [19.0]
下面的任务结果符合预期
- 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
但是,当您在命令行以 k=v
格式声明此变量时,类型为字符串且此字符串的长度为 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: [
要解决此问题,请使用 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
YAML 格式给出相同的结果
shell> ansible-playbook playbook.yml -e "l: [19.0]"
可选地,将变量放入 JSON or YAML file。声明更多变量时很实用。例如
shell> cat some_file.yml
l: [19.0]
k: [20.0]
会给
shell> ansible-playbook playbook2.yml -e "@some_file.yml"
...
msg: |-
l.0: 19.0
k.0: 20.0
如果您无法更改命令的格式,请自行转换变量。例如,
- 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 }}
然后,命令给出
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
您不能覆盖额外变量,即本例中的 l
,因为 extra vars
是 highest precedence。
另一个答案有助于解释为什么类型不正确作为通过 CLI 输入到 Ansible 的变量。满足此要求并解决您的问题的 Packer HCL2 模板更新为:
provisioner "ansible" {
playbook_file = "${path.root}/ansible/playbook.yaml"
extra_arguments = [
"-vv",
"--extra-vars",
jsonencode({ "houdini_major_version_list" = ["19.0"] }),
]
}
设置环境变量 PACKER_LOG=1
我们看到这会执行:
ansible-playbook ... -vv --extra-vars {"houdini_major_version_list":["19.0"]} ... /path/to/playbook.yaml
这表明 Packer 和 Ansible provisioner 之间的接口现在可以正确传递 list
类型变量。
请注意,jsonencode({ "houdini_major_version_list" = [19.0]
会导致 {"houdini_major_version_list":[19]}
,因为浮动会自动删除 .0
。