自定义Ansible模块使用'message'作为参数报错问题咨询
message参数的使用限制问题 你在自定义Ansible模块时定义了如下参数:
def run_module(): # defining available arguments/parameters a user can pass to the module module_args = dict( message_direction=dict(type='str', required=True, choices=['sent', 'received']), external_request_id=dict(type='str', required=True), message=dict(type='str'), protocol=dict(type='str', required=True) )
使用ansible-playbook运行剧本时,传入message参数会触发如下错误:
...ansible/module_utils/basic.py\", line 1989, in log TypeError: send() got multiple values for keyword argument 'MESSAGE' \", \"module_stdout\": \"\", \"msg\": \"MODULE FAILURE See stdout/stderr for the exact error\", \"rc\": 1 }
改用message_data、message1等名称则运行正常,且直接调用Ansible Python库时message参数可正常使用。针对这个问题的解答如下:
核心结论
message属于Ansible模块内部存在冲突风险的参数名,通过ansible-playbook运行时会触发内部逻辑冲突,因此不建议作为自定义模块的参数使用。
报错原因
Ansible核心模块工具类ansible/module_utils/basic.py中的日志相关方法(比如报错里的log方法),其内部调用的send()方法会使用MESSAGE作为关键字参数。当你将自定义模块的参数命名为message时,模块参数在解析传递过程中,会与内部方法的这个参数名(内部处理存在大小写不敏感的参数映射逻辑)产生冲突,导致send()方法同时接收到两个同名的关键字参数(一个是用户传入的模块参数,一个是内部日志逻辑生成的参数),最终抛出TypeError错误。
为什么Python脚本调用无问题?
直接通过Python脚本调用Ansible Python库时,参数传递的流程与ansible-playbook运行时的模块参数解析流程不同,不会触发这个内部参数冲突的场景,因此可以正常使用message参数。
解决方案
避免使用message作为自定义模块的参数名,改用message_data、payload、msg_content这类不会与Ansible内部关键字冲突的名称即可解决问题。
内容的提问来源于stack exchange,提问作者Surya

