Ansible:遍历服务列表并从实际存在的不需要的服务列表中禁用这些服务

Ansible: Loop over a list of services and disable those from a list of unwanted services which are actually present

我正在使用 Ansible 从 RHEL7.5 的基本安装构建基本映像 我想做的一件事是禁用不需要的服务。所以我这样做:

- name: "| disable unwanted services"
  service:
    name: "{{ item }}"
    enabled: no
    state: stopped
  loop: "{{ disabled_services }}"
  when: disabled_services is defined

哪个工作正常,在本地主机上测试;然后我在测试版本上尝试它,但它出错了,因为我试图管理的服务之一甚至不存在。

例如说 disabled_services == "ntp postfix ip6tables",但未安装 ip6tables。我会从模块中得到这样的错误:

ok: [udggsydasd48] => (item=postfix)
failed: [udggsydasd48] (item=ip6tables) => {"changed": false, "item":"ip6tables", "msg": "Could not find the requested service ip6tables: host"}

所以我正在调用 service_facts 模块来生成 运行 服务列表。这个循环中的什么(和哪里)我会把 "if service in services" 条件放在这个循环中:

- name: "| disable unwanted services"
  service:
    name: "{{ item }}"
    enabled: no
    state: stopped
  loop: "{{ disabled_services }}"
  when: disabled_services is defined

如果软件存在,它只会尝试从 "disabled_services" 中的阵列禁用服务?

我宁愿不使用 fail_when:从不,因为这会隐藏其他错误。

谢谢

加载 运行 services 列表后,使用 union filter

  loop: "{{ disabled_services | union(services) }}"

如果 firewalld 不是 installed/not 运行 您可以使用“failed_when:”

简单地忽略错误消息

为了避免弃用警告,可以通过在 ansible.cfg

中设置 deprecation_warnings=False 来禁用
- name: 'Disable firewalld Services'
   service:
     name: "{{item}}"
     state: stopped  
     enabled: no
   loop:
     - firewalld
   register: firewalld_service_disable
   failed_when: "firewalld_service_disable|failed and ('Could not find the requested service' not in firewalld_service_disable.msg)"
   ignore_errors: yes
   tags: test

下面是anisble playbook的执行输出

# ansible-playbook main.yml --tags test

PLAY [all] **********************************************************

TASK [Gathering Facts] **********************************************
ok: [ANSIBLECLIENTNODE]

TASK [hardening : Disable firewalld Services] ***********************
changed: [ANSIBLECLIENTNODE] => (item=firewalld)

PLAY RECAP **********************************************************

ANSIBLECLIENTNODE             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

如果你的 ansible 版本是 2.9 及更高版本,请按照下面的“service_facts”方法

- name: 'Populate service facts'
  service_facts:

- name: 'Disable firewalld Services'
  service:
    name: "{{item}}"
    state: stopped
    enabled: no
  loop:
   - firewalld
  when: ansible_facts.services[item] is defined
  ignore_errors: yes