Ansible Study Notes - 01
What is Ansible?
Ansible is an open-source automation tool designed to simplify IT infrastructure management, application deployment, and task automation.
Before diving into Ansible, let's familiarize ourselves with some core concepts:
Control node
: A machine where Ansible is installed and commands are executed. From the control node, we can manage and operate multiple machines.Managed node
: The remote machine or target being managed. These are the servers or devices you wish to operate on.Inventory
: A way to group managed machines for easier management.Playbook
: A blueprint for automation, defining and orchestrating the tasks to be performed.
Getting Started
Let’s write a simple Ansible script to experience the basics of Ansible.
Prerequisites
- A machine (Linux/Windows/macOS), either a PC or a server
- A Linux or Windows server
Installing Ansible
First, we need to install Ansible on the control node.
Check Python Version
Run one of the following commands:
python3 -V
or
python -V
Sample output:
Python 3.9.18
Ansible requires Python 3.
On Rocky Linux 9, the default version is Python 3.9.x
.
Verify pip Installation
Run:
python3 -m pip -V
If pip is installed, you’ll see its version:
pip 21.2.3 from /usr/local/lib/python3.9/site-packages/pip (python 3.9)
If not, you'll see an error:
/bin/python3: No module named pip
To install pip:
python3 -m ensurepip --default-pip
Example output:
Successfully installed pip-21.2.3
Install Ansible
Run the following command:
python3 -m pip install --user ansible
Install the pywinrm Module
If you plan to manage Windows servers with Ansible, install the pywinrm
module:
python3 -m pip install pywinrm
Creating an Inventory
What Is an Inventory File?
An inventory file in Ansible defines the hosts to manage and their connection details. It is typically written in YAML or INI format and specifies the machines Ansible will manage and how to connect to them.
Inventory files include:
- Host groups: Categories like
windows
orlinux
. - Hosts: Specific machines or servers, including connection details.
Create an inventory.yaml
file as follows:
windows:
hosts:
win01:
ansible_host: 1.1.1.2
ansible_user: username
ansible_password: password
ansible_connection: winrm
ansible_winrm_transport: basic
ansible_winrm_server_cert_validation: ignore
win02:
ansible_host: 1.1.1.3
ansible_user: username
ansible_password: password
ansible_connection: winrm
ansible_winrm_transport: basic
ansible_winrm_server_cert_validation: ignore
linux:
hosts:
linux01:
ansible_host: 1.1.1.5
ansible_user: username
Key details:
windows
andlinux
are group names.win01
,win02
, andlinux01
are hostnames.- Ansible keywords:
ansible_user
: The username for connection.ansible_password
: The password for connection.ansible_connection
: Connection type (e.g., SSH or WinRM).
Linux hosts don’t require ansible_password
if you use SSH keys. If SSH keys are not set up, you can provide a password instead.
Verify Inventory Syntax
Run:
ansible-inventory -i inventory.yaml --list
You should see output like this:
{
"all": {
"children": ["ungrouped", "windows", "linux"]
},
"windows": {
"hosts": ["win01", "win02"]
},
"linux": {
"hosts": ["linux01"]
}
}
all
and ungrouped
are default Ansible groups. Hosts without explicit groups are assigned to ungrouped
.
Test Connectivity
Run:
ansible windows -m win_ping -i inventory.yaml
ansible linux -m ping -i inventory.yaml
Sample output:
win01 | SUCCESS => { "ping": "pong" }
linux01 | SUCCESS => { "ping": "pong" }
Writing a Playbook
A playbook is a collection of instructions and logic for tasks to execute on servers.
Here’s an example playbook.yaml
:
- name: Upload file to Windows servers
hosts: windows
tasks:
- name: Check if file exists
ansible.builtin.win_stat:
path: "C:\\Users\\test\\file.txt"
register: file_stat
- name: Upload file if not present
ansible.builtin.win_copy:
src: "file.txt"
dest: "C:\\Users\\test\\file.txt"
when: not file_stat.stat.exists
- name: Upload file to Linux servers
hosts: linux
tasks:
- name: Check if file exists
ansible.builtin.stat:
path: "/home/test/file.txt"
register: file_stat
- name: Upload file if not present
ansible.builtin.copy:
src: "file.txt"
dest: "/home/test/file.txt"
when: not file_stat.stat.exists
Explanation
-
Windows Section:
- Checks if the file exists using
win_stat
and registers the result. - Uploads the file only if it doesn’t exist (
when: not file_stat.stat.exists
).
- Checks if the file exists using
-
Linux Section:
- Uses the
stat
module to check the file status. - Copies the file conditionally if it’s missing.
- Uses the
Run the Playbook
Place a file.txt
in the same directory and execute:
ansible-playbook playbook.yaml -i inventory.yaml
Output:
PLAY [Upload file to Windows servers] ...
TASK [Upload file if not present] ...
changed: [win01]
PLAY [Upload file to Linux servers] ...
TASK [Upload file if not present] ...
changed: [linux01]
You’ve now successfully executed a basic Ansible script!
Happy Coding! 🎉