语境
我正在使用 Ansible 设置 Windows 服务器赢巧克力模块。
在我的group_vars/windows_servers.yml
档案中我有:
choco_packages:
- 7zip
- git
- vscode
在我的剧本任务中我有:
- name: Install and upgrade software using Chocolatey
hosts: windows_servers
tasks:
- name: Install latest package versions
chocolatey.chocolatey.win_chocolatey:
name: "{{ item }}"
state: latest
loop: "{{ choco_packages }}"
到目前为止,一切都很好。
但是,现在我有一些软件包需要安装特定版本和/或需要传递某些安装参数。我可以在我的 中创建三个列表group_vars/windows_servers.yml
,每个目标一个(最新软件包、特定版本、带参数的软件包),并由每个列表提供三个任务,设置适当的键。
但为了减轻维护负担,我宁愿有一个单独的包列表,我可以在其中随意设置所需的键,并有 1 个任务,根据可用的项目键设置适当的选项。例如:
choco_packages:
- { name: "7zip", version: "22.1" }
- { name: "git" , install_args: [ "/NoGuiHereIntegration", "/NoGitLfs"] }
- { name: "vscode" }
问题
如果提供了版本和安装参数,我应该如何编写 Ansible 任务来设置它们,如果没有,则安装最新版本?我希望**kwargs
在 Python 中找到类似的东西。
我尝试过的方法
使用when:
条件我可以创建三个处理适用列表部分的任务:
- name: Install and upgrade software using Chocolatey
hosts: windows_servers
tasks:
- name: Install latest versions
chocolatey.chocolatey.win_chocolatey:
name: "{{ item.name }}"
state: latest
loop: "{{ choco_packages }}"
when: item.version is not defined and item.install_args is not defined
- name: Install specific versions
chocolatey.chocolatey.win_chocolatey:
name: "{{ item.name }}"
version: "{{ item.version }}"
state: present
loop: "{{ choco_packages }}"
when: item.version is defined
- name: Install with parameters
chocolatey.chocolatey.win_chocolatey:
name: "{{ item.name }}"
install_args: "{{ item.install_args }}"
state: present
loop: "{{ choco_packages }}"
when: item.install_args is defined
但这不能处理version
和的组合install_args
,而且相当冗长。
答案1
您将需要使用循环,并使用带有“省略”的默认过滤器。类似这样的操作...
- name: Install stuff
chocolatey.chocolatey.win_chocolatey:
name: "{{ item.name }}"
state: "{{ item.version is defined | ternary('present','latest') }}"
version: "{{ item.version | default(omit) }}"
choco_args: "{{ item.choco_args | default(omit) }}"
install_args: "{{ item.install_args | default(omit) }}"
loop: "{{ choco_packages }}"
这将与此变量一起工作修改的来自你的原文。
choco_packages:
- { name: "7zip", version: "22.1" }
- { name: "git" , choco_args: ["/NoGuiHereIntegration", "/NoGitLfs"] }
- { name: "vscode" }
这应该:
- 如果版本已定义,则安装指定版本(定义版本时,三元过滤器将返回“present”,否则将返回“latest”
- choco_args 仅在定义时才会传递
- 版本仅会在定义后才被传递。
无关,但看起来你试图传递一个列表,install_args
根据文档,仅有的接受一个字符串。
choco_args
另一方面,能列出清单。我碰巧知道这个包,这些是包参数(尽管它们在传递给本机安装程序时也可能起作用,所以随便)。只需确保仔细检查您要传递的是哪个(传递给包的参数(choco_args
),还是直接传递给安装程序的参数(install_args
)
答案2
中唯一必需的参数赢巧克力是姓名。其他参数是可选的。使用过滤器默认(别名:d)和特殊忽略变量以省略未定义的参数。请参阅省略参数。
例如,下面的任务应该做你想做的事
- chocolatey.chocolatey.win_chocolatey:
name: "{{ item.name }}"
version: "{{ item.version | d(omit) }}"
install_args: "{{ item.install_args | d(omit) }}"
state: "{{ item.state | d(omit) }}"
loop: "{{ choco_packages }}"
笔记:
- 这样,您可以根据需要使用其他模块参数(可能是全部)。
- 在您的代码中
state: present
是多余的,因为参数的默认值状态是展示。 - 如果需要,您可以重新定义默认值。例如,
state: "{{ item.state | d('latest') }}"
- 在您的问题中,不清楚您如何决定应使用哪种状态。您将属性状态进入choco_packages,或者您可以为此目的定义一个变量。例如,下面的声明保持所有选项打开
state: "{{ item.state | d(my_state|d('present')) }}"
- 参数安装参数需要一个字符串。