Graham Nicholls
Graham Nicholls

Reputation: 561

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

I'm using Ansible to build a base image from a base installation of RHEL7.5 One of the things I want to do is to disable unwanted services. So I do this:

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

Which works fine, testing on localhost; then I try it on a test build, and it errors because one of the services I'm trying to manage isn't even present.

Say for example that disabled_services == "ntp postfix ip6tables", but ip6tables isn't installed. I'll get an error from the module like so:

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

So I'm calling the service_facts module to generate a list of running services. What ( and where) in this loop would I put the "if service in services" conditional in this loop:

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

So that it will only attempt to disable services from the array in "disabled_services" if the software is present?

I'd rather not use a fail_when: never, as this can hide other errors.

Thanks

Upvotes: 0

Views: 4483

Answers (2)

if firewalld not installed/not running you can simply ignore error message using "failed_when:"

To avoid Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg

- 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

Below is the anisble playbook execution output

# 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

If your ansible version 2.9 and later , follow below "service_facts" method

- 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

Upvotes: 0

Paul Hodges
Paul Hodges

Reputation: 15273

After you load the list of running services, use the union filter.

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

Upvotes: 2

Related Questions