如何根据循环项所具有的键来设置 Ansible 命令参数?

如何根据循环项所具有的键来设置 Ansible 命令参数?

语境

我正在使用 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')) }}"

  • 参数安装参数需要一个字符串。

相关内容