检查 redhat 机器中的多个包是否已经安装,如果不可用则通过 ansible playbook 安装

Check if multiple packages in redhat machine are already installed if not available then install via ansible playbook

I want to check if certain packages are installed in my nodes or not. If not then install those packages via ansible playbook.

这是我作为输入提供给剧本的变量(要安装的节点 IP 和包):

exec_server: '10.50.10.40,34.228.208.5'
pkgs:
  - zip
  - unzip
  - git

这是我写的剧本,用于查看是否已安装任何软件包,如果没有,则安装它们。

- name: Check Package installation
  hosts: "{{ exec_server }}"
  become: yes
  gather_facts: no
  
  tasks:
    - name: Gather the packager facts
      package_facts:
        manager: "auto"
  
    - name: Package status
      debug:
        msg: "{{ item }} {{ 'installed' if item in ansible_facts.packages else 'not installed' }}"
      loop: "{{ pkgs | default([]) }}"
      register: find_output

    - name: install the latest version of not installed Packages
      yum:
        name: "{% if pkgs is undefined in ansible_facts.packages %}-{{ pkgs }}{% endif %}"
        state: latest 

我面临的错误:

Identity added: /tmp/awx_2137_f_94gy2c/artifacts/2137/ssh_key_data (/tmp/awx_2137_f_94gy2c/artifacts/2137/ssh_key_data)

PLAY [Check Package installation] **********************************************

TASK [Gather the packager facts] ***********************************************
ok: [34.228.208.5]
ok: [10.50.10.40]

TASK [Package status] **********************************************************
ok: [10.50.10.40] => (item=zip) => {
    "msg": "zip installed"
}
ok: [10.50.10.40] => (item=unzip) => {
    "msg": "unzip installed"
}
ok: [10.50.10.40] => (item=git) => {
    "msg": "git not installed"
}
ok: [10.50.10.40] => (item=python-pip) => {
    "msg": "python-pip not installed"
}
ok: [10.50.10.40] => (item=gcc) => {
    "msg": "gcc not installed"
}
ok: [34.228.208.5] => (item=zip) => {
    "msg": "zip installed"
}
ok: [34.228.208.5] => (item=unzip) => {
    "msg": "unzip installed"
}
ok: [34.228.208.5] => (item=git) => {
    "msg": "git not installed"
}
ok: [34.228.208.5] => (item=python-pip) => {
    "msg": "python-pip not installed"
}
ok: [34.228.208.5] => (item=gcc) => {
    "msg": "gcc not installed"
}

TASK [install the latest version of Uninstalled Packages] **********************
fatal: [10.50.10.40]: FAILED! => {"msg": "template error while templating string: expected token 'end of statement block', got 'ansible_facts'. String: {% if pkgs is undefined in ansible_facts.packages %}-{{ pkgs }}{% endif %}"}
fatal: [34.228.208.5]: FAILED! => {"msg": "template error while templating string: expected token 'end of statement block', got 'ansible_facts'. String: {% if pkgs is undefined in ansible_facts.packages %}-{{ pkgs }}{% endif %}"}

PLAY RECAP *********************************************************************
10.50.10.40                : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
34.228.208.5               : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

如何根据我的 pkgs 变量和 Ansible 收集的事实只获取未安装的软件包?

您不需要在执行任何操作之前检查软件包是否已安装,这就是 state: present 的用途:

present and installed will simply ensure that a desired package is installed.

来源:https://docs.ansible.com/ansible/latest/collections/ansible/builtin/yum_module.html#parameter-state

所以你的剧本应该像

一样简单
- name: Check Package installation
  hosts: "{{ exec_server }}"
  become: yes
  gather_facts: no
  
  tasks:
    - name: install the latest version of not installed Packages
      yum:
        name: "{{ pkgs }}"
        state: present 

现在,如果您想知道您的结构中有什么不正确的地方,那就是 if:

{% if pkgs is undefined in ansible_facts.packages %}-{{ pkgs }}{% endif %}

您不能 运行 在同一指令中对同一变量进行两次测试(即没有 orand)。
在这里,您正在尝试同时 运行 和 in and is undefined 测试。

如果你想保持在那个次优的路线上,你可以做的是使用 difference 过滤器:

- name: install the latest version of not installed Packages
  yum:
    name: "{{ pkgs | difference(ansible_facts.packages) }}"
    state: latest