Getting Started With Ansible
A Linux Engineer’s Guide to Ansible
Ansible is:
- An Open-source automation tool
- Agentless, no need for software on target machines
- Uses declarative YAML language for configurations
- Playbooks define automation tasks
- Modules execute specific tasks on managed hosts.
- Inventory file lists managed by hosts
- Idempotent operations for consistent results
- Integrates with cloud providers and infrastructure components
- Uses SSH for secure communication
- Strong community support and extensive documentation
- Efficient for configuration management
What is needed to start with Ansible
To start with Ansible, you will need:
- Installation: You must install Ansible on your local machine (or a server).
- Control Machine: You may prefer to use Control Machine for centralized management. This is not a requirement, but I find it easier to manage ansible from a central location or via CI/CD pipelines.
- Inventory File: Create an inventory file listing the target hosts or servers Ansible will manage. This file typically includes IP addresses or domain names.
- SSH Access: Ensure your control machine can SSH into the managed hosts. Ansible uses SSH to communicate with remote machines, so SSH access must be set up and configured.
- YAML Playbooks: Write simple YAML playbooks that define the tasks you want to automate. Playbooks are the core of Ansible automation. YAML is easy to pick up.
- Understanding Modules: Ansible modules perform tasks on remote hosts. Learn the modules available for different operations.
- Basic Command Structure: Familiarize yourself with basic Ansible commands. For example, running a playbook using
ansible-playbook
and checking the inventory withansible-inventory
. - Optional: Roles and Galaxy: As you advance, consider organizing your playbooks into roles for better structure. Ansible Galaxy is a platform for finding and sharing roles created by the community.
- Documentation: Ansible has extensive documentation available. Refer to it for in-depth information and troubleshooting.
- Practice Environment: Set up a test environment to practice your Ansible playbooks without affecting production systems.
Step-by-Step Guide to Getting Started with Ansible
Step 1 – How to Install Ansible
We are going to assume you already have Ansible Installed. If not, you will find a complete guide to Installing Ansible on Linux systems here.
Step 2 – Configure The Ansible Host file
The host file, or inventory file in Ansible, is a key config document listing hosts and groups. It includes IP addresses, DNS names, and network info. Categorize hosts by roles or locations for playbook efficiency. Default location: /etc/ansible/hosts. Use entries and groups for server management:
ansible all --list-hosts
This is what an example ansible host file looks like. If you don’t have any servers to play with, you can always just use the localhost.
# Ansible Hosts File
[web-servers]
web1 ansible_host=192.168.1.181
[database-servers]
db1 ansible_host=192.168.1.178
[production]
prod1 ansible_host=192.168.1.179
Step 3 – Ansible Playbooks and Ad-Hoc Commands
Ansible offers two main ways to interact with your managed nodes:
1. Ansible Playbooks (ansible-playbook):
- Purpose: Playbooks are the heart of Ansible automation. They are YAML files that define a series of tasks to be executed on your target hosts. Playbooks enable complex, repeatable configurations and deployments.
- Structure:
hosts:
Specifies which hosts (or groups of hosts) to target.tasks:
Lists the actions to be performed using Ansible modules.variables:
(Optional) Stores values to be used in your tasks.
- Example Playbook (my_playbook.yml):
---
- name: Update and Install Apache on Web Servers
hosts: webserver # Target the 'webservers' group from your inventory
tasks:
- name: Update package lists
apt:
update_cache: yes
- name: Install Apache
apt:
name: apache2
state: present # Ensure Apache is installed
- name: Ensure Apache is running
service:
name: apache2
state: started
- Execution:
ansible-playbook my_playbook.yml
2. Ad-Hoc Commands (ansible):
- Purpose: Ideal for quick, one-off tasks. You use Ansible modules directly on the command line.
- Example:
ansible all -m ping # Test connectivity to all hosts
ansible webservers -m shell -a 'df -h' # Check disk space on web servers
Step 4 – Discovering the ansible.cfg file
- Purpose: ansible.cfg configures Ansible’s command-line tool.
- Location: Found in various places, prioritized in the current directory, user’s home, and system-wide config directory.
- Settings:
- Inventory file location
- Default user for remote connections
- SSH private key file location
- Default timeout for network operations
- Default verbosity level for output
- Customization: Tailor Ansible to your preferences by adjusting ansible.cfg.
- Impact: Crucial for defining Ansible’s behavior during playbook runs or ad-hoc commands.
Here is a basic ansible.cfg file with a brief explanation what each configuration is responsible for:
# Ansible Configuration File
[defaults]
# Location of the inventory file. Default is /etc/ansible/hosts
inventory = /path/to/your/inventory/file
# Specify the default user to use when connecting to remote hosts
remote_user = ansible_user
# Location of the private key file for SSH authentication
private_key_file = /path/to/your/private/key
# Default timeout value for network operations (in seconds)
timeout = 30
# Default verbosity level for output. 0 is least verbose, 4 is most verbose.
verbosity = 2
# Uncomment the following line to enable host key checking. Set to False to disable.
# host_key_checking = True
# Control the number of parallel processes to use. Set to 0 for unlimited.
# forks = 5
# Specify the default callback plugin for displaying results.
# stdout_callback = yaml
# Specify additional directories to search for roles.
# roles_path = /path/to/your/roles
Step 5 – Try these Basic Ansible Commands
Ping all hosts
ansible all -m ping
The Ansible command “ansible all -m ping” sends a ping message to all hosts specified in the inventory, checking if they are reachable and responsive.
List packages installed
ansible all -s -m shell -a 'apt list --installed | grep python' –ask-become-pass
This Ansible command, when executed, uses the “shell” module to run the ‘apt list –installed | grep python’ command on all hosts (“-s” for sudo, “–ask-become-pass” to prompt for privilege escalation), checking for installed Python packages and providing the results.
Install software on all ansible nodes
ansible all -s -m shell -a 'apt-get install telnet' --ask-become-pass
This Ansible command executes a shell module with elevated privileges to install the Telnet package using the ‘apt-get’ package manager, prompting for sudo password with the ‘–ask-become-pass’ option.
Install Lynx web browser
ansible all -s -m shell -a 'apt-get install lynx -y' --ask-become-pass
This Ansible command executes the shell module with elevated privileges on all hosts, installing the Lynx text-based web browser using the apt-get package manager and providing the required password for privilege escalation.
Check disk space on all servers
ansible -m shell -a 'df -h' all
92.168.1.178 | SUCCESS | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
udev 926M 0 926M 0% /dev
tmpfs 191M 5.9M 185M 4% /run
/dev/mapper/ansible--webserver--vg-root 18G 2.1G 15G 13% /
tmpfs 953M 0 953M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 953M 0 953M 0% /sys/fs/cgroup
tmpfs 191M 0 191M 0% /run/user/1000
192.168.1.179 | SUCCESS | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
udev 926M 0 926M 0% /dev
tmpfs 191M 5.9M 185M 4% /run
/dev/mapper/ansible--appserver--vg-root 18G 2.1G 15G 13% /
tmpfs 953M 0 953M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 953M 0 953M 0% /sys/fs/cgroup
tmpfs 191M 0 191M 0% /run/user/1000
192.168.1.181 | SUCCESS | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
udev 1.9G 0 1.9G 0% /dev
tmpfs 393M 11M 382M 3% /run
/dev/mapper/ansible--dbserver--vg-root 16G 2.1G 13G 14% /
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
tmpfs 393M 0 393M 0% /run/user/1000
This Ansible command utilizes the shell module to execute the ‘df -h’ command across all hosts, providing information about disk usage in a human-readable format.
Using the whoami command
When running commands ansible uses my credentials Richard
ansible -m shell -a 'whoami' all
192.168.1.178 | SUCCESS | rc=0 >>
richard
192.168.1.179 | SUCCESS | rc=0 >>
richard
192.168.1.181 | SUCCESS | rc=0 >>
Richard
This Ansible command executes the “whoami” shell command across all hosts (“-a ‘whoami’ all”), providing information about the current user on each host.
How to create users on all servers
ansible -b -K -m user -a 'name=testuser' all
SUDO password:
192.168.1.178 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1001,
"home": "/home/testuser",
"name": "testuser",
"shell": "",
"state": "present",
"system": false,
"uid": 1001
192.168.1.179 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1001,
"home": "/home/testuser",
"name": "testuser",
"shell": "",
"state": "present",
"system": false,
"uid": 1001
192.168.1.181 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 1001,
"home": "/home/testuser",
"name": "testuser",
"shell": "",
"state": "present",
"system": false,
"uid": 1001
}
This Ansible command, executed with elevated privileges (“-b”), prompting for the sudo password (“-K”), uses the “user” module to create a user with the name “testuser” across all specified hosts (“all”).
ansible -m shell -a 'getent passwd | grep testuser' all
192.168.1.179 | SUCCESS | rc=0 >>
testuser:x:1001:1001::/home/testuser:
192.168.1.178 | SUCCESS | rc=0 >>
testuser:x:1001:1001::/home/testuser:
192.168.1.181 | SUCCESS | rc=0 >>
testuser:x:1001:1001::/home/testuser:
This Ansible command employs the “shell” module to execute the ‘getent passwd | grep testuser’ command on all specified hosts, retrieving information about the “testuser” from the system’s passwd file.
ansible -b -K -m user -a 'name=testuser state=absent' all
SUDO password:
192.168.1.178 | SUCCESS => {
"changed": true,
"force": false,
"name": "testuser",
"remove": false,
"state": "absent"
}
192.168.1.179 | SUCCESS => {
"changed": true,
"force": false,
"name": "testuser",
"remove": false,
"state": "absent"
}
192.168.1.181 | SUCCESS => {
"changed": true,
"force": false,
"name": "testuser",
"remove": false,
"state": "absent"
}
This Bash command, utilizing Ansible, runs with elevated privileges (-b), prompts for the sudo password (-K), and employs the Ansible module “user” to ensure the absence of a user named “testuser” on all specified hosts.
ansible -m shell -a 'getent passwd | grep testuser' all
192.168.1.179 | FAILED | rc=1 >>
non-zero return code
192.168.1.178 | FAILED | rc=1 >>
non-zero return code
192.168.1.181 | FAILED | rc=1 >>
non-zero return code
This Ansible command utilizes the shell module to execute the ‘getent passwd | grep testuser’ command on all hosts, searching for information related to the ‘testuser’ in the passwd database.
Step 6 – Use Ansible to discover facts
The Ansible Setup module is a powerful tool used to gather system facts and information from remote hosts. It provides a comprehensive overview of the target system’s configuration, enabling users to make informed decisions in their playbooks.
- Gather All Setup details about your local machine
ansible localhost -m setup
The Ansible command “ansible localhost -m setup” gathers and displays detailed facts about the local host’s system, providing comprehensive information for use in automation and configuration management tasks.
- You can write output to tmp
ansible localhost -m setup --tree /tmp/facts
The Ansible command “ansible localhost -m setup –tree /tmp/facts” gathers system facts on the localhost and stores the output in JSON format under the specified directory “/tmp/facts.”
- you can filter it for information
ansible localhost -m setup -a 'filter=*ipv4*'
This Ansible command gathers information about the local machine using the “setup” module, filtering the output to include only details related to IPv4 addresses.
NB – if you grep it will grep blank info
ansible apacheweb -m setup -a "filter=ansible_architecture"
ansible all -m setup -a "filter=ansible_fqdn"
ansible all -m setup -a "filter=ansible_kernel"
ansible all -m setup -a "filter=ansible_memtotal_mb"
ansible all -m setup -a "filter=ansible_proc*"
ansible all -m setup -a "filter=ansible_vir*"
These Ansible commands collect system information for specific filters, such as architecture, fully qualified domain name, kernel version, total memory, processes, and virtualization details, across different hosts.
Step 7 – Start Experimenting
In Ansible, various commands serve different purposes. We have already covered the adhoc ansible command, and mentioned ansible-playbook.
Here are some other essential types of Ansible commands:
ansible-galaxy:
Manages Ansible roles from Ansible Galaxy, a platform for sharing and finding roles.
Example:
ansible-galaxy install username.role_name
ansible-vault:
Encrypts sensitive data within Ansible playbooks or files.
Example:
ansible-vault encrypt my_file.yml
ansible-doc:
Provides documentation for Ansible modules.
Example:
ansible-doc copy
ansible-config
Displays Ansible configuration settings.
Example:
ansible-config view
ansible-pull:
Pulls Ansible playbooks from a version control system to the local machine and runs them.
Example:
ansible-pull -U repository_url
ansible-inventory:
Displays the inventory hosts defined for Ansible.
Example:
ansible-inventory --list
These commands cover a range of tasks, from running playbooks to managing roles, encrypting data, and exploring documentation. Depending on your needs, you can choose the appropriate command for the task at hand.
We have just scratched the surface of Ansible. It is a powerful declarative configuration tool which i use almost everyday. Once you grasp the basics, you will no doubt start to realize its potential at scale.
Recent Comments