The repo contains both code for production use and training material for workshops with RRA
You find it in ansible/production
Description: This exercise introduces the basics of running ad-hoc commands on remote servers using Ansible. You'll learn how to execute simple commands without writing a playbook.
Task:
- Run the
uptimecommand on all test servers - Check the disk usage with
df -h - View system information with
uname -a
Step-by-step:
-
Navigate to the workshop directory:
cd ansible/workshop -
Run a simple command on all test servers:
ansible --ask-pass -i inventories/test/hosts.ini test -m command -a "uptime"
If you've never connected to these servers before, you may need to prefix the command with ANSIBLE_HOST_KEY_CHECKING=False the first time you connect.
-
Check disk usage:
ansible --ask-pass -i inventories/test/hosts.ini test -m command -a "df -h"
-
Get system information:
ansible --ask-pass -i inventories/test/hosts.ini test -m shell -a "uname -a"
Key concepts:
--ask-passprompts for the SSH password-ispecifies the inventory file-mspecifies the module to use (command, shell, etc.)-aprovides arguments to the module
Description: This exercise teaches you how to set up passwordless SSH authentication using SSH keys. This is a best practice for automation and eliminates the need to use --ask-pass in every command. You'll generate an SSH key pair (if you don't have one) and copy your public key to the remote servers.
Task:
- Generate an SSH key pair on your local machine (if you don't have one)
- Copy your public SSH key to all test servers
- Test passwordless authentication
Step-by-step:
-
Check if you already have an SSH key:
ls -la ~/.ssh/id_rsa*
If you see
id_rsaandid_rsa.pub, you already have a key pair and can skip to step 3. -
Generate a new SSH key pair (if needed):
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"Press Enter to accept the default file location and optionally set a passphrase.
-
Use Ansible to copy your SSH public key to all test servers:
cd ansible/workshop ansible --ask-pass -i inventories/test/hosts.ini test -m authorized_key -a "user=YOUR_USERNAME key='{{ lookup('file', '~/.ssh/id_rsa.pub') }}' state=present" -b
Replace
YOUR_USERNAMEwith your actual username on the remote servers.You'll be prompted for the SSH password one last time.
-
Test passwordless authentication (no
--ask-passneeded):ansible -i inventories/test/hosts.ini test -m ping -
Run a command without password prompt:
ansible -i inventories/test/hosts.ini test -m command -a "whoami"
This should return your username (on the remote servers) without asking for a password.
Alternative method using ssh-copy-id:
If you prefer a more traditional approach, you can use ssh-copy-id for each server:
# For each server in your inventory
ssh-copy-id username@servernameThen verify with Ansible:
ansible -i inventories/test/hosts.ini test -m pingKey concepts:
- SSH keys provide secure, passwordless authentication
- authorized_key module manages SSH public keys on remote servers
- lookup() function reads files on the Ansible control node
- Once configured, you no longer need
--ask-passfor subsequent commands - This is essential for automation and scheduled tasks
Troubleshooting:
- If you get "Permission denied", ensure the SSH key was copied correctly
- Check that
~/.ssh/authorized_keysexists on the remote server with correct permissions (600) - Verify your private key has correct permissions:
chmod 600 ~/.ssh/id_rsa
Description: Learn how to create and manage files on remote servers using Ansible playbooks. This exercise covers basic file operations and introduces playbook structure.
Task:
- Create a file called
/tmp/ansible-test.txtwith specific content - Set appropriate permissions and ownership
- Verify the file was created successfully
Step-by-step:
-
Navigate to the workshop directory (if not already there):
cd ansible/workshop -
Create a playbook file called
playbooks/create_file.yml:--- - name: Create a test file hosts: test become: yes tasks: - name: Create file with content copy: content: "This file was created by Ansible\n" dest: /tmp/ansible-test.txt owner: root group: root mode: '0644' - name: Verify file exists stat: path: /tmp/ansible-test.txt register: file_status - name: Display file status debug: msg: "File exists: {{ file_status.stat.exists }}"
-
Run the playbook:
ansible-playbook -i inventories/test/hosts.ini playbooks/create_file.yml
-
Verify the file was created:
ansible -i inventories/test/hosts.ini test -m command -a "cat /tmp/ansible-test.txt"
Key concepts:
- Playbook structure with hosts, tasks, and modules
- Using
copymodule to create files with content - Using
statmodule to check file status - Using
become: yesfor privilege escalation
Description: This exercise teaches safe, production-grade operating system patching on RHEL servers using Ansible. The goal is to ensure that updates are applied in a controlled manner, avoiding service disruption and alert noise. Participants learn how to limit blast radius, detect when a reboot is actually required, and rely on automation rather than manual intervention.
Task:
- Run patching only against test servers
- Patch only one server at a time
- Reboot the server only if required
Step-by-step:
-
Navigate to the workshop directory (if not already there):
cd ansible/workshop -
Review or create the playbook file
playbooks/patch.yml:--- - name: Safe patching with controlled reboot hosts: test serial: 1 become: yes tasks: - name: Update all packages dnf: name: "*" state: latest register: dnf_output - name: Check if reboot is required command: needs-restarting -r register: reboot_required failed_when: false changed_when: reboot_required.rc == 1 - name: Reboot if required reboot: msg: "Rebooting after patching" reboot_timeout: 600 when: reboot_required.rc == 1 - name: Wait for system to be available wait_for_connection: delay: 30 timeout: 300 when: reboot_required.rc == 1
-
Run the patching playbook:
ansible-playbook -i inventories/test/hosts.ini playbooks/patch.yml --limit test -
To run against a single server:
ansible-playbook -i inventories/test/hosts.ini playbooks/patch.yml --limit testserver01
Key concepts:
serial: 1ensures only one server is patched at a time (limits blast radius)dnfmodule updates packages safelyneeds-restarting -rdetects if reboot is required (exit code 1 means reboot needed)- Conditional reboot only when necessary (avoids unnecessary downtime)
wait_for_connectionensures server is back online before continuing
Answer:
- Use
serial: 1to patch one server at a time - Use the
dnfmodule for package updates - Use
needs-restarting -rto detect reboot requirement
Command:
ansible-playbook -i inventories/test/hosts.ini playbooks/patch.yml --limit testDescription: This exercise demonstrates how to use Ansible roles to deploy and configure the Zabbix monitoring agent on remote servers. You'll learn about role structure, variables, templates, and handlers to create reusable automation.
Task:
- Install the Zabbix agent package on test servers
- Configure the agent with the correct Zabbix server address
- Deploy a configuration file using Jinja2 templates
- Ensure the service is enabled and running
Step-by-step:
-
Navigate to the workshop directory (if not already there):
cd ansible/workshop -
Review the role structure in
roles/zabbix_agent/:defaults/main.yml- Default variablestasks/main.yml- Main installation and configuration taskstemplates/zabbix_agentd.conf.j2- Configuration templatehandlers/main.yml- Service restart handler
-
Set variables in
roles/zabbix_agent/defaults/main.yml:--- zabbix_server: "10.0.0.100" zabbix_server_active: "10.0.0.100" zabbix_agent_hostname: "{{ ansible_hostname }}"
-
Create a playbook called
playbooks/deploy_zabbix.yml:--- - name: Deploy Zabbix Agent hosts: test become: yes roles: - zabbix_agent
-
Run the playbook:
ansible-playbook -i inventories/test/hosts.ini playbooks/deploy_zabbix.yml
-
Verify the Zabbix agent is running:
ansible -i inventories/test/hosts.ini test -m command -a "systemctl status zabbix-agent"
-
Override variables for specific environments:
ansible-playbook -i inventories/test/hosts.ini playbooks/deploy_zabbix.yml -e "zabbix_server=10.0.1.50"
Key concepts:
- Roles provide reusable, structured automation (tasks, variables, templates, handlers)
- Templates use Jinja2 to dynamically generate configuration files
- Handlers ensure services are restarted only when configuration changes
- Variables can be defined in defaults and overridden at runtime
- Role structure follows Ansible best practices for maintainability
This is the documentation for setting up inventory from VMware automatically https://github.com/ansible-collections/vmware.vmware