Module 01: Ansible Basics¶
๐ฏ Learning Objectives¶
By the end of this module, you will:
- Understand Ansible architecture and core concepts
- Install and configure Ansible on the control node
- Create and manage inventory files effectively
- Execute ad-hoc commands for system management
- Configure SSH authentication and privilege escalation
- Understand Ansible's connection methods and security model
๐ Why Ansible for Red Hat Automation¶
Ansible Philosophy¶
Agentless Architecture: No software installation required on managed nodes Idempotent Operations: Safe to run multiple times, only makes necessary changes Declarative Syntax: Describe desired state, not step-by-step procedures Human Readable: YAML syntax that's easy to read and maintain
Key Benefits for System Administrators¶
- Consistency: Eliminate configuration drift across systems
- Scalability: Manage hundreds of systems as easily as one
- Auditability: Track all changes through version control
- Reliability: Built-in error handling and rollback capabilities
๐๏ธ Ansible Architecture¶
Control Node Requirements¶
Supported Operating Systems:
- RHEL 8/9 (exam environment)
- CentOS Stream 8/9
- Fedora (recent versions)
- Ubuntu LTS versions
Python Requirements:
- Python 3.8 or newer
- pip for module installation
Software Requirements:
- SSH client
- ansible-core package
Managed Node Requirements¶
Minimal Requirements:
- SSH server running
- Python 3.6 or newer
- User account with appropriate privileges
No Agent Required: Ansible connects via SSH and executes tasks remotely
Communication Flow¶
โโโโโโโโโโโโโโโโโโโ SSH โโโโโโโโโโโโโโโโโโโ
โ Control Node โโโโโโโโโโโ โ Managed Node โ
โ (Ansible) โ โ (Target) โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ โ
โโโ Playbooks โโโ Python modules
โโโ Inventory โโโ Fact gathering
โโโ Configuration โโโ Task execution
โโโ Modules
๐ง Installation and Configuration¶
Installing Ansible on RHEL 9¶
# Enable required repositories
sudo subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
# Install ansible-core
sudo dnf install ansible-core
# Verify installation
ansible --version
ansible-config --version
# Install additional collections
ansible-galaxy collection install ansible.posix
ansible-galaxy collection install community.general
Alternative Installation Methods¶
# Install via pip (if needed)
pip3 install ansible-core
# Install from source (development)
git clone https://github.com/ansible/ansible.git
cd ansible
source ./hacking/env-setup
Ansible Configuration File¶
Configuration Hierarchy (highest to lowest precedence):
ANSIBLE_CONFIGenvironment variableansible.cfgin current directory~/.ansible.cfgin user home directory/etc/ansible/ansible.cfgsystem-wide
Essential Configuration (ansible.cfg):
[defaults]
# Inventory file location
inventory = inventory.ini
# Default user for connections
remote_user = ansible
# Disable host key checking for lab environments
host_key_checking = False
# Enable privilege escalation by default
become = True
become_method = sudo
# Role and collection paths
roles_path = ./roles
collections_paths = ./collections
# Connection settings
timeout = 30
forks = 5
# Logging
log_path = ./ansible.log
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
control_path_dir = /tmp/.ansible-cp
Validating Configuration¶
# List all configuration settings
ansible-config list
# View current configuration values
ansible-config view
# Dump all configuration (active settings)
ansible-config dump
๐ Inventory Management¶
Static Inventory Formats¶
INI Format (inventory.ini):
# Individual hosts
web01.example.com
web02.example.com ansible_host=192.168.1.10
# Groups
[webservers]
web01.example.com
web02.example.com
[databases]
db01.example.com
db02.example.com ansible_host=192.168.1.20
# Group of groups
[production:children]
webservers
databases
# Group variables
[webservers:vars]
http_port=80
max_clients=200
[databases:vars]
mysql_port=3306
mysql_datadir=/var/lib/mysql
# Global variables
[all:vars]
ansible_user=ansible
ansible_ssh_private_key_file=~/.ssh/id_rsa
YAML Format (inventory.yml):
all:
children:
production:
children:
webservers:
hosts:
web01.example.com:
web02.example.com:
ansible_host: 192.168.1.10
vars:
http_port: 80
max_clients: 200
databases:
hosts:
db01.example.com:
db02.example.com:
ansible_host: 192.168.1.20
vars:
mysql_port: 3306
mysql_datadir: /var/lib/mysql
vars:
ansible_user: ansible
ansible_ssh_private_key_file: ~/.ssh/id_rsa
Host Patterns¶
Basic Patterns:
# All hosts
ansible all -m ping
# Single host
ansible web01.example.com -m ping
# Group
ansible webservers -m ping
# Multiple groups
ansible webservers:databases -m ping
# Exclusions
ansible webservers:!web01.example.com -m ping
# Intersections
ansible webservers:&production -m ping
# Regular expressions
ansible ~web\d+ -m ping
Inventory Variables¶
Host Variables (host_vars/hostname.yml):
# host_vars/web01.example.com.yml
---
max_clients: 150
custom_config: true
ssl_enabled: yes
Group Variables (group_vars/groupname.yml):
# group_vars/webservers.yml
---
http_port: 80
document_root: /var/www/html
package_name: httpd
# group_vars/production.yml
---
environment: production
backup_enabled: true
monitoring_enabled: true
Inventory Validation¶
# List all hosts
ansible-inventory --list
# List hosts in YAML format
ansible-inventory --list --yaml
# Show specific host details
ansible-inventory --host web01.example.com
# Graphical representation
ansible-inventory --graph
# Validate inventory syntax
ansible-inventory --list > /dev/null
๐ SSH Configuration and Authentication¶
SSH Key Generation and Distribution¶
# Generate SSH key pair
ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa
# Copy public key to managed nodes
ssh-copy-id ansible@web01.example.com
ssh-copy-id ansible@web02.example.com
ssh-copy-id ansible@db01.example.com
# Alternative: Manual key copying
cat ~/.ssh/id_rsa.pub | ssh ansible@web01.example.com "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
SSH Client Configuration¶
SSH Config (~/.ssh/config):
Host web01.example.com
User ansible
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
Host 192.168.1.*
User ansible
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Testing Connectivity¶
# Test SSH connectivity manually
ssh ansible@web01.example.com "echo 'SSH connection successful'"
# Test Ansible connectivity
ansible all -m ping
# Test with specific user
ansible all -m ping -u ansible
# Test with different SSH key
ansible all -m ping --private-key ~/.ssh/alternate_key
Privilege Escalation Configuration¶
Sudo Configuration (on managed nodes):
# Add ansible user to sudoers
echo "ansible ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/ansible
# Validate sudoers configuration
sudo visudo -c
Ansible Configuration:
# Test privilege escalation
ansible all -m shell -a "whoami" --become
# Test without password prompt
ansible all -m shell -a "whoami" --become --ask-become-pass
โก Ad-hoc Commands¶
Command Structure¶
Basic Syntax:
ansible <pattern> -m <module> -a "<module_arguments>" [options]
Essential Ad-hoc Command Patterns¶
System Information:
# Basic connectivity test
ansible all -m ping
# Gather system facts
ansible all -m setup
# Get specific facts
ansible all -m setup -a "filter=ansible_distribution*"
# Check uptime
ansible all -m command -a "uptime"
# Check disk space
ansible all -m shell -a "df -h"
# View memory usage
ansible all -m shell -a "free -m"
Package Management:
# Install packages
ansible all -m dnf -a "name=httpd state=present" --become
# Install multiple packages
ansible all -m dnf -a "name=['httpd','mysql','php'] state=present" --become
# Update all packages
ansible all -m dnf -a "name='*' state=latest" --become
# Remove packages
ansible all -m dnf -a "name=httpd state=absent" --become
Service Management:
# Start services
ansible all -m systemd -a "name=httpd state=started" --become
# Enable and start services
ansible all -m systemd -a "name=httpd state=started enabled=yes" --become
# Restart services
ansible all -m systemd -a "name=httpd state=restarted" --become
# Check service status
ansible all -m systemd -a "name=httpd" --become
File Operations:
# Copy files to managed nodes
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts" --become
# Create directories
ansible all -m file -a "path=/tmp/testdir state=directory mode=0755" --become
# Change file permissions
ansible all -m file -a "path=/tmp/testfile mode=0644 owner=root group=root" --become
# Create symbolic links
ansible all -m file -a "src=/tmp/source dest=/tmp/link state=link" --become
# Remove files
ansible all -m file -a "path=/tmp/testfile state=absent" --become
User Management:
# Create users
ansible all -m user -a "name=testuser groups=wheel shell=/bin/bash" --become
# Set user passwords (with encrypted password)
ansible all -m user -a "name=testuser password=$6$rounds=..." --become
# Remove users
ansible all -m user -a "name=testuser state=absent remove=yes" --become
Command Options¶
Common Options:
--become (-b) # Enable privilege escalation
--become-user USER # Escalate to specific user
--become-method METHOD # Escalation method (sudo, su, etc.)
--ask-become-pass (-K) # Prompt for escalation password
--check (-C) # Dry run mode
--diff (-D) # Show file changes
--limit SUBSET # Limit to subset of hosts
--user (-u) USER # Connect as specific user
--private-key FILE # Use specific SSH private key
--ask-pass (-k) # Prompt for SSH password
--inventory (-i) FILE # Use specific inventory
--extra-vars (-e) VARS # Set additional variables
--verbose (-v) # Increase verbosity
Examples with Options:
# Dry run with diff output
ansible webservers -m copy -a "src=index.html dest=/var/www/html/" --check --diff --become
# Limit to specific hosts
ansible all -m shell -a "hostname" --limit "web01.example.com,web02.example.com"
# Use different user and key
ansible all -m ping -u root --private-key ~/.ssh/root_key
# Extra verbosity for debugging
ansible all -m setup --limit web01.example.com -vvv
๐ Understanding Ansible Modules¶
Module Categories¶
Core System Modules:
ansible.builtin.command- Execute commandsansible.builtin.shell- Execute shell commandsansible.builtin.script- Execute scriptsansible.builtin.raw- Execute raw SSH commands
Package Management:
ansible.builtin.dnf- DNF/YUM package manageransible.builtin.package- Generic package manageransible.builtin.rpm_key- RPM key management
Service Management:
ansible.builtin.systemd- Systemd service managementansible.builtin.service- Generic service management
File Operations:
ansible.builtin.copy- Copy filesansible.builtin.file- File/directory managementansible.builtin.template- Jinja2 templatingansible.builtin.lineinfile- Line-in-file editingansible.builtin.replace- File content replacement
Module Documentation¶
# List all available modules
ansible-doc -l
# Get module documentation
ansible-doc dnf
ansible-doc systemd
ansible-doc copy
# Get module syntax only
ansible-doc -s dnf
# Search modules
ansible-doc -l | grep firewall
# Get module examples
ansible-doc dnf | grep -A 20 EXAMPLES
Command vs Shell vs Raw Modules¶
command module (default, secure):
# Cannot use pipes, redirects, or shell variables
ansible all -m command -a "ls -l /tmp"
shell module (allows shell features):
# Can use pipes, redirects, and shell variables
ansible all -m shell -a "ps aux | grep httpd"
ansible all -m shell -a "echo $HOME"
raw module (minimal processing):
# Bypasses module system entirely
ansible all -m raw -a "uptime"
๐งช Practical Lab Exercises¶
Exercise 1: Control Node Setup¶
- Install Ansible on control node
- Create basic ansible.cfg configuration
- Test installation with version commands
Exercise 2: SSH Authentication Setup¶
- Generate SSH key pair
- Distribute keys to managed nodes
- Configure SSH client for automation
- Test password-less authentication
Exercise 3: Inventory Creation¶
- Create INI format inventory with groups
- Create YAML format inventory
- Add host and group variables
- Validate inventory structure
Exercise 4: Ad-hoc Command Practice¶
- Test connectivity with ping module
- Gather facts from all nodes
- Install and manage packages
- Control services across nodes
- Perform file operations
Exercise 5: Module Exploration¶
- Use ansible-doc to explore modules
- Test different command modules
- Practice with various module options
- Compare module behaviors
๐ฏ Key Takeaways¶
Architecture Understanding¶
- Agentless: No software required on managed nodes
- SSH-based: Secure communication using existing SSH infrastructure
- Python execution: Modules run Python code on managed nodes
- Idempotent: Safe to run repeatedly
Configuration Mastery¶
- ansible.cfg precedence: Know where Ansible looks for configuration
- Essential settings: remote_user, host_key_checking, become settings
- Inventory formats: Both INI and YAML, choose based on complexity
- Variable organization: Use host_vars and group_vars directories
Ad-hoc Command Proficiency¶
- Module selection: Choose appropriate modules for tasks
- Option usage: Master common options like --become, --check, --limit
- Pattern matching: Use flexible host patterns for targeting
- Documentation: Use ansible-doc for quick reference
Best Practices¶
- Start simple: Master basic concepts before advanced features
- Test first: Use ping and check mode to validate before execution
- Document decisions: Use clear naming and organization
- Security focus: Proper SSH key management and privilege escalation
๐ Next Steps¶
You now have the foundation for Ansible automation. Next, you'll learn to:
- Module 02: Playbooks & Tasks - Structure automation with playbooks
- Create repeatable automation with YAML playbooks
- Organize complex tasks with proper structure and error handling
- Scale beyond ad-hoc commands to comprehensive automation workflows
The fundamentals you've learned here will support everything else you do with Ansible!
Next Module: Module 02: Playbooks & Tasks โ