Bianca_K
Bianca_K

Reputation: 15

Stop ansible tasks from running on some hosts

I am trying to set up two different cronjobs. Some hosts need the standard cronjob while others need the failover cronjob

This is my hosts file, this is only one subset, there are others like [ukspare] and [usspare]

[zaspare]
host01.example.com
host02.example.com
host03.example.com
host04.example.com
host05.example.com
host06.example.com
host07.example.com
host08.example.com

This is my yaml file, as you can see I want to stop the standard cron from running on hosts 1-5 but must run on hosts 6-8, and I need to copy the somescript.sh to all hosts

---

- name: Updating somescript
  hosts: zaspare
  become: yes

  tasks:


  - name: Copy somescript.sh script to /usr/local/bin
    copy:
      src: somescript.sh
      dest: /usr/local/bin/
      owner: root
      group: root
      mode: 0755
      
  - name: Setup standard crontab for somescript    
    cron:
      name: Run somescript.sh
      job: /usr/local/bin/somescript.sh {{ inventory_hostname }} false 
      cron_file: somescript
      user: root
      minute: "10"
      hour: "22"
    when: inventory_hostname != "host01.example.com" or 
          inventory_hostname != "host02.example.com" or
          inventory_hostname != "host03.example.com" or
          inventory_hostname != "host04.example.com" or
          inventory_hostname != "host05.example.com"      

  - name: Setup failover crontab for somescript    
    cron:
      name: Run somescript.sh
      job: /usr/local/bin/somescript.sh {{ inventory_hostname }} true 
      cron_file: somescript
      user: root
      minute: "10"
      hour: "22"
    when: inventory_hostname == "host01.example.com" or 
          inventory_hostname == "host02.example.com" or
          inventory_hostname == "host03.example.com" or
          inventory_hostname == "host04.example.com" or
          inventory_hostname == "host05.example.com"

As you can see from the output below the standard cron runs on all the hosts, and then skips some hosts and updates the cron for the failover correctly

TASK [Setup standard crontab for somescript]******************************
changed: [host06.example.com]
changed: [host07.example.com]
changed: [host01.example.com]
changed: [host08.example.com]
changed: [host02.example.com]
changed: [host04.example.com]
changed: [host03.example.com]
changed: [host05.example.com]

TASK [Setup failover crontab for somescript]******************************
skipping: [host06.example.com]
skipping: [host07.example.com]
skipping: [host08.example.com]
changed: [host01.example.com]
changed: [host02.example.com]
changed: [host03.example.com]
changed: [host04.example.com]
changed: [host05.example.com]

      

I have tried with just one host and it appears to work correctly, the minute I start add ing multiple hosts to exclude on the standard cron it stop working

---

- name: Updating somescript
  hosts: zaspare
  become: yes

  tasks:


  - name: Copy somescript.sh script to /usr/local/bin
    copy:
      src: somescript.sh
      dest: /usr/local/bin/
      owner: root
      group: root
      mode: 0755
      
  - name: Setup standard crontab for somescript    
    cron:
      name: Run somescript.sh
      job: /usr/local/bin/somescript.sh {{ inventory_hostname }} false 
      cron_file: somescript
      user: root
      minute: "10"
      hour: "22"
    when: inventory_hostname != "host01.example.com"   

  - name: Setup failover crontab for somescript    
    cron:
      name: Run somescript.sh
      job: /usr/local/bin/somescript.sh {{ inventory_hostname }} true 
      cron_file: somescript
      user: root
      minute: "10"
      hour: "22"
    when: inventory_hostname == "host01.example.com"
          
TASK [Setup standard crontab for somescript]******************************
skipping:  [host01.example.com]

TASK [Setup failover crontab for somescript]******************************
changed: [host01.example.com]

      

Upvotes: 0

Views: 319

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68104

There are many options.

  1. For example, given the simplified inventory
shell> cat hosts
[zaspare]
host01.example.com
host02.example.com
host03.example.com

Put the hosts into a list and simplify the conditions. The playbook

shell> cat pb.yml 
- hosts: zaspare

  vars:

    standard:
      - host01.example.com
      - host02.example.com

  tasks:

    - debug:
        msg: Setup standard crontab
      when: inventory_hostname in standard

    - debug:
        msg: Setup failover crontab
      when: inventory_hostname not in standard

gives

shell> ansible-playbook -i hosts pb.yml
PLAY [zaspare] *******************************************************************************

TASK [debug] *********************************************************************************
ok: [host01.example.com] => 
  msg: Setup standard crontab
skipping: [host03.example.com]
ok: [host02.example.com] => 
  msg: Setup standard crontab

TASK [debug] *********************************************************************************
skipping: [host01.example.com]
skipping: [host02.example.com]
ok: [host03.example.com] => 
  msg: Setup failover crontab

PLAY RECAP ***********************************************************************************
host01.example.com: ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
host02.example.com: ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
host03.example.com: ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

  1. Use inventory plugin constructed. See
shell> ansible-doc -t inventory constructed

Given the tree

├── ansible.cfg
├── inventory
│   ├── 01-hosts
│   └── 02-constructed.yml
└── pb.yml

Put the variable cron_type into the inventory

shell> cat inventory/01-hosts 
[zaspare]
host01.example.com cron_type=standard
host02.example.com cron_type=standard
host03.example.com cron_type=failover

and create the configuration file 02-contructed.yml

shell> cat inventory/02-constructed.yml 
plugin: constructed
groups:
  cron_standard: "cron_type == 'standard'"
  cron_failover: "cron_type == 'failover'"

Test the inventory

shell> ansible-inventory -i inventory --list --yaml
all:
  children:
    cron_failover:
      hosts:
        host03.example.com:
          cron_type: failover
    cron_standard:
      hosts:
        host01.example.com:
          cron_type: standard
        host02.example.com:
          cron_type: standard
    ungrouped: {}
    zaspare:
      hosts:
        host01.example.com: {}
        host02.example.com: {}
        host03.example.com: {}

The playbook

shell> cat pb.yml 
- hosts: cron_standard
  tasks:
    - debug:
        msg: Setup standard crontab

- hosts: cron_failover
  tasks:
    - debug:
        msg: Setup failover crontab

gives

shell> ansible-playbook -i inventory pb.yml 

PLAY [cron_standard] *************************************************************************

TASK [debug] *********************************************************************************
ok: [host01.example.com] => 
  msg: Setup standard crontab
ok: [host02.example.com] => 
  msg: Setup standard crontab

PLAY [cron_failover] *************************************************************************

TASK [debug] *********************************************************************************
ok: [host03.example.com] => 
  msg: Setup failover crontab

PLAY RECAP ***********************************************************************************
host01.example.com: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host02.example.com: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host03.example.com: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Upvotes: 2

DerMolly
DerMolly

Reputation: 464

Maybe a good solution would be to put the hosts in additional groups and handle the execution with that? See https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#hosts-in-multiple-groups

That way you don't need to typeout the hosts in your playbooks, multiple places lead to multipe error sources and so on.

Upvotes: 2

Related Questions