see also Ansible Community Documentation
Multiple Groups sorted by OS and task
# OS - Parents with Childrens
[RPM:children]
controller
targets
rpmdesktops
rpmservers
[debian:children]
nameserver
services
picluster
[arch:children]
archdesktops
# Groups - Childrens with their respective members
# CentOS Stream 9
[controller]
ansiblecontroller ansible_host=192.168.68.158 ansible_user=root ansible_connection=local
[targets]
target1 ansible_host=192.168.68.159 ansible_user=root ansible_connection=ssh
target2 ansible_host=192.168.68.160 ansible_user=root ansible_connection=ssh
[rpmdesktops]
opensuse ansible_host=192.168.68.173 ansible_user=root ansible_connection=ssh
redhat-centos ansible_host=192.168.68.183 ansible_user=root ansible_connection=ssh
[rpmservers]
rh-nginx-proxy ansible_host=192.168.68.155 ansible_user=root ansible_connection=ssh
centos-template ansible_host=192.168.68.156 ansible_user=root ansible_connection=ssh
# Ubuntu
[nameserver]
ns1mac ansible_host=192.168.68.10 ansible_user=root ansible_connection=ssh
ns2pi ansible_host=192.168.68.11 ansible_user=root ansible_connection=ssh
ns3hp ansible_host=192.168.68.12 ansible_user=root ansible_connection=ssh
[services]
meshcentral ansible_host=192.168.68.16 ansible_user=root ansible_connection=ssh
gameserver ansible_host=192.168.68.77 ansible_user=root ansible_connection=ssh
stablediffusion ansible_host=192.168.68.23 ansible_user=root ansible_connection=ssh
[picluster]
pi-cluster-1 ansible_host=192.168.68.101 ansible_user=root ansible_connection=ssh
pi-cluster-2 ansible_host=192.168.68.102 ansible_user=root ansible_connection=ssh
pi-cluster-3 ansible_host=192.168.68.103 ansible_user=root ansible_connection=ssh
pi-cluster-4 ansible_host=192.168.68.104 ansible_user=root ansible_connection=ssh
pi-cluster-5 ansible_host=192.168.68.105 ansible_user=root ansible_connection=ssh
[archdesktops]
manjaro ansible_host=192.168.68.153 ansible_user=root ansible_connection=ssh
Ping all Hosts from the hosts.ini File - you have to be in the same directory as the .ini file.
ansible all -m ping -i hosts.ini
Execute a Playbook - here the update-allos.yml file; targets are choosen in the .yml file and defined in the hosts.ini file.
ansible-playbook update-allos.yml -i hosts.ini
Update all servers with different OS (see hosts.ini above) verbosely - Recap example:
What does it do?
update-allos.yml:
---
- name: Update and upgrade packages on multiple OS with verbosity
hosts: all
become: yes
tasks:
- name: Gather facts
ansible.builtin.setup:
- name: Update and upgrade packages on Ubuntu/Debian
block:
- name: Update the package cache
ansible.builtin.apt:
update_cache: yes
- name: List available package updates
ansible.builtin.command:
cmd: apt list --upgradable
register: update_output
ignore_errors: yes
- name: Show available package updates
ansible.builtin.debug:
msg: "{{ update_output.stdout_lines }}"
- name: Upgrade all packages to the latest version
ansible.builtin.apt:
name: '*'
state: latest
update_cache: yes
when: ansible_facts['os_family'] == "Debian"
- name: Update and upgrade packages on Manjaro/Arch Linux
block:
- name: Update the package cache and list available updates
ansible.builtin.command:
cmd: pacman -Syu --noconfirm
register: update_output
ignore_errors: yes
- name: Show available package updates
ansible.builtin.debug:
msg: "{{ update_output.stdout_lines }}"
when: ansible_facts['os_family'] == "Archlinux"
- name: Update and upgrade packages on openSUSE Leap
block:
- name: Update the package cache
ansible.builtin.command:
cmd: zypper refresh
register: refresh_output
ignore_errors: yes
- name: List available package updates
ansible.builtin.command:
cmd: zypper list-updates
register: update_output
ignore_errors: yes
- name: Show available package updates
ansible.builtin.debug:
msg: "{{ update_output.stdout_lines }}"
- name: Upgrade all packages to the latest version
ansible.builtin.command:
cmd: zypper update -y
when: ansible_facts['os_family'] == "Suse"
- name: Update and upgrade packages on CentOS/RHEL
block:
- name: Update the package cache
ansible.builtin.dnf:
update_cache: yes
- name: List available package updates
ansible.builtin.command:
cmd: dnf check-update
register: update_output
ignore_errors: yes
- name: Show available package updates
ansible.builtin.debug:
msg: "{{ update_output.stdout_lines }}"
- name: Upgrade all packages to the latest version
ansible.builtin.dnf:
name: '*'
state: latest
update_cache: yes
when: ansible_facts['os_family'] == "RedHat"
In this example we are installing Golang on the picluster group and additionally the individual server target1. The picluster servers are arm64 based and the target1 server is x86-64 based.
Just change the hosts on line 3, if you want to target specific groups/individual machines before executing the ansible-playbook command.
What does it do?
golang-setup-multi.yml:
---
- name: Go Setup
hosts: picluster, target1
vars:
version: 1.22.6
become: yes
tasks:
- name: Ensure wget is installed on Ubuntu/Debian
apt:
name: wget
state: present
when: ansible_facts['os_family'] == "Debian"
- name: Ensure wget is installed on CentOS/RHEL
dnf:
name: wget
state: present
when: ansible_facts['os_family'] == "RedHat"
- name: Ensure wget is installed on Manjaro/Arch Linux
pacman:
name: wget
state: present
when: ansible_facts['os_family'] == "Archlinux"
- name: Ensure wget is installed on openSUSE Leap
zypper:
name: wget
state: present
when: ansible_facts['os_family'] == "Suse"
- name: Determine Go tar URL for arm64
set_fact:
go_tar_url: "https://go.dev/dl/go{{version}}.linux-arm64.tar.gz"
go_tar_name: "go{{version}}.linux-arm64.tar.gz"
when: ansible_facts['architecture'] == 'aarch64'
- name: Determine Go tar URL for x86_64
set_fact:
go_tar_url: "https://go.dev/dl/go{{version}}.linux-amd64.tar.gz"
go_tar_name: "go{{version}}.linux-amd64.tar.gz"
when: ansible_facts['architecture'] == 'x86_64'
- name: Download Go tar file
command: wget -O /tmp/{{ go_tar_name }} {{ go_tar_url }}
register: download_result
retries: 3
delay: 5
until: download_result.rc == 0
- name: Check if Go tar file was downloaded
stat:
path: "/tmp/{{ go_tar_name }}"
register: go_tar_file
- name: Fail if Go tar file was not found
fail:
msg: "Go tar file was not downloaded successfully."
when: not go_tar_file.stat.exists
- name: Delete previous Go installation
command: rm -rf /usr/local/go
become: true
- name: Extract and move new Go folder to /usr/local
command: tar -C /usr/local -xzf /tmp/{{ go_tar_name }}
become: true
- name: Delete downloaded tar file
command: rm -rf /tmp/{{ go_tar_name }}
- name: Add Go binary path to system-wide profile
lineinfile:
path: /etc/profile.d/go.sh
line: 'export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin'
create: true
state: present
become: true
- name: Reload system-wide profile
shell: . /etc/profile.d/go.sh
- name: Test Go installation on Ubuntu/Debian
command: /usr/local/go/bin/go version
register: go_version_output_debian
failed_when: go_version_output_debian.rc != 0
when: ansible_facts['os_family'] == "Debian"
- name: Test Go installation on CentOS/RHEL
command: /usr/local/go/bin/go version
register: go_version_output_redhat
failed_when: go_version_output_redhat.rc != 0
when: ansible_facts['os_family'] == "RedHat"
- name: Test Go installation on Manjaro/Arch Linux
command: /usr/local/go/bin/go version
register: go_version_output_arch
failed_when: go_version_output_arch.rc != 0
when: ansible_facts['os_family'] == "Archlinux"
- name: Test Go installation on openSUSE Leap
command: /usr/local/go/bin/go version
register: go_version_output_suse
failed_when: go_version_output_suse.rc != 0
when: ansible_facts['os_family'] == "Suse"
- name: Display Go version on Ubuntu/Debian
debug:
msg: "{{ go_version_output_debian.stdout }}"
when: ansible_facts['os_family'] == "Debian"
- name: Display Go version on CentOS/RHEL
debug:
msg: "{{ go_version_output_redhat.stdout }}"
when: ansible_facts['os_family'] == "RedHat"
- name: Display Go version on Manjaro/Arch Linux
debug:
msg: "{{ go_version_output_arch.stdout }}"
when: ansible_facts['os_family'] == "Archlinux"
- name: Display Go version on openSUSE Leap
debug:
msg: "{{ go_version_output_suse.stdout }}"
when: ansible_facts['os_family'] == "Suse"