Restart a service on group hosts except on the host witch the playbook is running - ansible

I have a playbook where i update a cluster of 3 machines.
I use "serial: 1" to run one machine at a time.
And what I need is after each reboot I need to restart a list of services on other two machines.
How I can do that?
Sample of what I have:
- name: "Stop from booting and stop service"
service:
name: "{{item}}"
enabled: no
state: stopped
loop: "{{service_list}}"
when: standby.changed
register: stop_service
##Reboot
- name: "Reboot Server"
reboot:
pre_reboot_delay: 120
post_reboot_delay: 60
reboot_timeout: 600
when: stop_service.changed
register: reboot_1
##Upgrade
- name: "Upgrade SO"
apt:
update_cache: yes
upgrade: dist
when: reboot_1.changed
register: upgrade
##Reboot
- name: "Reboot Server"
reboot:
pre_reboot_delay: 60
post_reboot_delay: 60
reboot_timeout: 600
when: upgrade.changed
register: reboot_2
##Start Services
- name: "Start service and enable start on booting"
service:
name: "{{item}}"
state: started
enabled: yes
loop: "{{service_list}}"
when: reboot_2.changed
register: start_service
- name: "Restart service on other machines"
service:
name: "{{item}}"
state: restarted
loop: "{{service_list}}"
delegate_to: other machines....
Thanks for your help!

This won't scale well, and its not dynamic for shifting inventories, but for just a couple of servers you could do something like this, and just build one for each server that you are configuring:
- name: "Restart service on other machines"
service:
name: "{{item}}"
state: restarted
loop: "{{service_list}}"
delegate_to: server1
when: inventory_hostname != 'server1'
Since you are running through them in a serial fashion already, when you are on server1, its conditional will fail, but it will pass for servers 2 and 3, and delegate that task to them.

Related

Stop/Start Windows services only when state not in manual or disabled

I have an Ansible playbook to start or stop services and I needed to add a condition to pick up services that are neither in Manual nor Disabled State. Appreciate your help !!!
My code looks like this.
---
- name: windows start services
hosts: all
tasks:
- name: Include primary app services
include_vars:
file: inventory/vars/servicestart.yml
- name: Start task
win_service:
name: "{{ item }}"
state: started
loop: "{{ services }}"
when: inventory_hostname in groups['primaryappservers']

Multi VM Create using ansible playbook from Templates

Problem Statement:
while trying to create a VM from a template especially in the case of a windows OS template(working fine for linux OS template). VM after being created through ansible playbook is "powered off".
Here is my playbook to create multiple VMS from template, please help me in making this playbook more efficient...thanks in advance.
---
- name: Create a multiple VMs asynchronously
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Clone the template
vmware_guest:
hostname: xxx.xxx.xx
username: username
password: password
validate_certs: False
name: "{{ item }}"
template: Template-Win-2016
cluster: cluster
datacenter: Dev and QA DC
folder: /
state: poweredon
hardware:
memory_mb: 12288
num_cpus: 4
disk:
- size_gb: 60
type: thin
autoselect_datastore: True
wait_for_ip_address: yes
with_items:
- testvm001
- testvm002
register: vm_create
async: 600
poll: 0
- name: Waiting for status
async_status:
jid: "{{ item.ansible_job_id }}"
register: job_result
until: job_result.finished
delay: 60
retries: 60
with_items: "{{ vm_create.results }}"

Ansible AWX workflow

I am new to ansible and AWX. Making good progress with my project but am getting stuck with one part and hoping you guys can help.
I have a Workflow Template as follows
Deploy VM
Get IP of the VM Deployed & create a temp host configuration
Change the deployed machine hostname
Where I am getting stuck is once I create the hostname when the next template kicks off the hostname group is missing. I assume this is because of some sort of runspace. How do I move this information around? I need this as later on I want to get into more complicated flows.
What I have so far:
1.
- name: Deploy VM from Template
hosts: xenservers
tasks:
- name: Deploy VM
shell: xe vm-install new-name-label="{{ vm_name }}" template="{{ vm_template }}"
- name: Start VM
shell: xe vm-start vm="{{ vm_name }}"
---
- name: Get VM IP
hosts: xenservers
remote_user: root
tasks:
- name: Get IP
shell: xe vm-list name-label="{{ vm_name }}" params=networks | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1
register: vm_ip
until: vm_ip.stdout != ""
retries: 15
delay: 5
Here I was setting the hosts and this works locally to the template but when it moves on it fails. I tried this in a task and a play.
- name: Add host to group
add_host:
name: "{{ vm_ip.stdout }}"
groups: deploy_vm
- hosts: deploy_vm
- name: Set hosts
hosts: deployed_vm
tasks:
- name: Set a hostname
hostname:
name: "{{ vm_name }}"
when: ansible_distribution == 'Rocky Linux'
Thanks

Ansible how restart service one after one on different hosts

Hy every one !
pls help .
I have 3 server. Each of them have one systemd service. I need reboot this service by one.
So after i reboot service on host 1 , and this service is up ( i can check tcp port), i need reboot service on host 2 and so on.
How i can do it with ansible
Now i have such playbook:
---
- name: Install business service
hosts: business
vars:
app_name: "e-service"
app: "{{ app_name }}-{{ tag }}.war"
app_service: "{{ app_name }}.service"
app_bootstrap: "{{ app_name }}_bootstrap.yml"
app_folder: "{{ eps_client_dir }}/{{ app_name }}"
archive_folder: "{{ app_folder }}/archives/arch_{{ansible_date_time.date}}_{{ansible_date_time.hour}}_{{ansible_date_time.minute}}"
app_distrib_dir: "{{ eps_distrib_dir }}/{{ app_name }}"
app_dependencies: "{{ app_distrib_dir }}/dependencies.tgz"
tasks:
- name: Copy app {{ app }} to {{ app_folder }}
copy:
src: "{{ app_distrib_dir }}/{{ app }}"
dest: "{{ app_folder }}/{{ app }}"
group: ps_group
owner: ps
mode: 0644
notify:
- restart app
- name: Copy service setting to /etc/systemd/system/{{app_service}}
template:
src: "{{ app_distrib_dir }}/{{ app_service }}"
dest: /etc/systemd/system/{{ app_service }}
mode: 0644
notify:
- restart app
- name: Start service {{ app }}
systemd:
daemon-reload: yes
name: "{{ app_service }}"
state: started
enabled: true
handlers:
- name: restart app
systemd:
daemon-reload: yes
name: "{{ app_service }}"
state: restarted
enabled: true
and all service restart at one time.
try serial and max_fail_percentage, max_fail_percentage value is percent of the whole number of your hosts, if server 1 failed, then the rest server will not run,
---
- name: Install eps-business service
hosts: business
serial: 1
max_fail_percentage: 10
Try with
---
- name: Install eps-business service
hosts: business
serial: 1
By default, Ansible will try to manage all of the machines referenced in a play in parallel. For a rolling update use case, you can define how many hosts Ansible should manage at a single time by using the serial keyword
https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html
create a script that reboots your service and then add a loop that will check whether the service is up or not and once it is executed successfully based on the status it has returned you can go for the next service.

ansible check non-existent service [duplicate]

I have an Ansible playbook for deploying a Java app as an init.d daemon.
Being a beginner in both Ansible and Linux I'm having trouble to conditionally execute tasks on a host based on the host's status.
Namely I have some hosts having the service already present and running where I want to stop it before doing anything else. And then there might be new hosts, which don't have the service yet. So I can't simply use service: name={{service_name}} state=stopped, because this will fail on new hosts.
How I can I achieve this? Here's what I have so far:
- name: Check if Service Exists
shell: "if chkconfig --list | grep -q my_service; then echo true; else echo false; fi;"
register: service_exists
# This should only execute on hosts where the service is present
- name: Stop Service
service: name={{service_name}} state=stopped
when: service_exists
register: service_stopped
# This too
- name: Remove Old App Folder
command: rm -rf {{app_target_folder}}
when: service_exists
# This should be executed on all hosts, but only after the service has stopped, if it was present
- name: Unpack App Archive
unarchive: src=../target/{{app_tar_name}} dest=/opt
See the service_facts module, new in Ansible 2.5.
- name: Populate service facts
service_facts:
- debug:
msg: Docker installed!
when: "'docker' in services"
Of course I could also just check if the wrapper script exists in /etc/init.d. So this is what I ended up with:
- name: Check if Service Exists
stat: path=/etc/init.d/{{service_name}}
register: service_status
- name: Stop Service
service: name={{service_name}} state=stopped
when: service_status.stat.exists
register: service_stopped
I modified Florian's answer to only use the return code of the service command (this worked on Mint 18.2)
- name: Check if Logstash service exist
shell: service logstash status
register: logstash_status
failed_when: not(logstash_status.rc == 3 or logstash_status.rc == 0)
- name: Check if Logstash service exist
service:
name: logstash
state: stopped
when: logstash_status.rc == 0
It would be nice if the "service" module could handle "unrecognized service" errors.
This is my approach, using the service command instead of checking for an init script:
- name: check for apache
shell: "service apache2 status"
register: _svc_apache
failed_when: >
_svc_apache.rc != 0 and ("unrecognized service" not in _svc_apache.stderr)
- name: disable apache
service: name=apache2 state=stopped enabled=no
when: "_svc_apache.rc == 0"
check the exit code of "service status" and accept the exit code 0 when the output contains "unrecognized service"
if the exit code was 0, that service is installed (stopped or running)
Another approach for systemd (from Jakuje):
- name: Check if cups-browsed service exists
command: systemctl cat cups-browsed
check_mode: no
register: cups_browsed_exists
changed_when: False
failed_when: cups_browsed_exists.rc not in [0, 1]
- name: Stop cups-browsed service
systemd:
name: cups-browsed
state: stopped
when: cups_browsed_exists.rc == 0
Building on #Maciej's answer for RedHat 8, and combining it with the comments made on it.
This is how I managed to stop Celery only if it has already been installed:
- name: Populate service facts
service_facts:
- debug:
msg: httpd installed!
when: ansible_facts.services['httpd.service'] is defined
- name: Stop celery.service
service:
name: celery.service
state: stopped
enabled: true
when: ansible_facts.services['celery.service'] is defined
You can drop the debug statement--it's there just to confirm that ansible_facts is working.
This way using only the service module has worked for us:
- name: Disable *service_name*
service:
name: *service_name*
enabled: no
state: stopped
register: service_command_output
failed_when: >
service_command_output|failed
and 'unrecognized service' not in service_command_output.msg
and 'Could not find the requested service' not in service_command_output.msg
My few cents. The same approach as above but for kubernetes
Check if kublete service is running
- name: "Obtain state of kublet service"
command: systemctl status kubelet.service
register: kubelet_status
failed_when: kubelet_status.rc > 3
Display debug message if kublet service is not running
- debug:
msg: "{{ kubelet_status.stdout }}"
when: "'running' not in kubelet_status.stdout"
You can use the service_facts module since Ansible 2.5. But you need to know that the output are the real name of the service like docker.service or somthing#.service. So you have different options like:
- name: Populate service facts
service_facts:
- debug:
msg: Docker installed!
when: "'docker.service' in services"
Or you can search for the string beginning with the service name; that is much more reliable, because the service names are different between the distributions:
- name: Populate service facts
service_facts:
- debug:
msg: Docker installed!
when: "services.keys()|list|select('search', '^docker')|length >0"

Resources