我使用以编程方式生成的 Ansible 剧本。一般来说,由于剧本只是 YAML,所以这很简单。但是,当使用“简单”key=value
形式时,剧本不是纯 YAML——它们包含嵌入shlex
可解析形式的内容。
为了避免这种形式的歧义(该key=value
对是命令的参数还是 ansible 的参数?),并且只需解析和生成一种格式,我无条件地使用了示例中演示的复杂参数机制ansible-examples 存储库。
这使用以下类型的语法:
action: module-name
args:
key1: value1
key2: value2
...这很好。但是,当尝试将此形式用于shell
或command
模块时(其文件描述实际命令作为名为的参数传递free_form
),但效果不太好:
action: shell
args:
free_form: echo hello_world >/tmp/something
creates: /tmp/something
调用时,将运行以下命令:
/bin/sh -c " free_form='echo hello_world >/tmp/something' "
...这根本就不是我想要实现的。
使用纯 YAML 语法采用“自由格式”命令的 Ansible 模块的正确方法是什么?
答案1
简短回答:不要使用command
、raw
、script
或shell
模块。编写您自己的模块,将该命令作为“正常”参数接受。
长答案:
大多数情况下,你可以这样做:
- shell: echo hello_world > /tmp/something
args:
creates: /tmp/something
然而,在某些特殊情况下,这种方法会失败:
- shell: echo hello_world > creates=something
args:
creates: creates=something # The file is named "creates=something"
我不知道处理这个问题的通用方法,但是特定于 bash 的解决方案是:
- shell: echo hello_world > "creates=something"
args:
creates: creates=something
答案2
这是在Ansible 文档现在。
# You can also use the 'args' form to provide the options. This command
# will change the working directory to somedir/ and will only run when
# /path/to/database doesn't exist.
- command: /usr/bin/make_database.sh arg1 arg2
args:
chdir: somedir/
creates: /path/to/database
请注意,没有名为“free_form”的参数。