Ansible
Chapter 48: Ansible for Linux Administration - Deep Dive
Section titled “Chapter 48: Ansible for Linux Administration - Deep Dive”Mastering Configuration Management with Ansible
Section titled “Mastering Configuration Management with Ansible”48.1 Understanding Ansible
Section titled “48.1 Understanding Ansible”What is Ansible?
Section titled “What is Ansible?”Ansible is an open-source automation tool that automates configuration management, application deployment, and IT orchestration. It uses a simple, declarative language (YAML) called “playbooks” to describe desired system states.
Ansible Architecture+------------------------------------------------------------------+| || Control Node || +-------------------------------------------------------------+ || | | || | +---------------+ +---------------+ | || | | Ansible | | Ansible | | || | | Engine | | Galaxy | | || | | (CLI/Config) | | (Roles) | | || | +---------------+ +---------------+ | || | | | | || | v v | || | +---------------------------------------------------+ | || | | Inventory & Variables | | || | +---------------------------------------------------+ | || | | || +-------------------------------------------------------------+ || | || | SSH/Connection || v || +-------------------------------------------------------------+ || | Managed Nodes | || | | || | +------------+ +------------+ +------------+ | || | | Server 1 | | Server 2 | | Server N | | || | | (Linux) | | (Linux) | | (Windows) | | || | +------------+ +------------+ +------------+ | || | | || +-------------------------------------------------------------+ || |+------------------------------------------------------------------+How Ansible Works
Section titled “How Ansible Works” Ansible Execution Flow+------------------------------------------------------------------+| || 1. User executes ansible-playbook || | || v || 2. Parse Inventory || +----------------------------------------------------------+ || | - Read hosts/groups from inventory file | || | - Load variable files | || +----------------------------------------------------------+ || | || v || 3. Parse Playbook || +----------------------------------------------------------+ || | - Read plays and tasks | || | - Resolve variables | || | - Load handlers | || +----------------------------------------------------------+ || | || v || 4. Build Execution Plan || +----------------------------------------------------------+ || | - Generate task list | || | - Apply filtering (limit, tags) | || | - Determine host order | || +----------------------------------------------------------+ || | || v || 5. Connect to Hosts || +----------------------------------------------------------+ || | - Establish SSH connection | || | - Gather facts (if enabled) | || +----------------------------------------------------------+ || | || v || 6. Execute Tasks || +----------------------------------------------------------+ || | - Run each task on each host | || | - Execute modules | || | - Collect results | || | - Execute handlers (if notified) | || +----------------------------------------------------------+ || | || v || 7. Report Results || +----------------------------------------------------------+ || | - Display output | || | - Generate reports | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+48.2 Inventory Management
Section titled “48.2 Inventory Management”Inventory File Structure
Section titled “Inventory File Structure”# /etc/ansible/hosts or custom inventory file
# Simple host listserver1.example.comserver2.example.com192.168.1.100
# Groups[webservers]web1.example.comweb2.example.comweb3.example.com
[dbservers]db1.example.comdb2.example.com
[loadbalancers]lb1.example.com
# Group of groups[production:children]webserversdbserversloadbalancers
# Variables for groups[webservers]web1.example.com ansible_port=22web2.example.com
[webservers:vars]ansible_user=adminansible_python_interpreter=/usr/bin/python3
# Variables for hosts[webservers]web1.example.com nginx_port=80web2.example.com nginx_port=8080Inventory Patterns
Section titled “Inventory Patterns”# All hostsall*
# Groupswebserversproduction:staging
# Multiple groupswebservers:dbservers
# Exclude group!webservers
# Intersection (in both)webservers:&production
# Wildcards*.example.comserver*.example.com
# Rangeserver[1:10].example.comdb[01:05].example.com48.3 Playbook Structure
Section titled “48.3 Playbook Structure”Basic Playbook
Section titled “Basic Playbook”---- name: Configure Web Servers hosts: webservers become: yes # sudo vars: nginx_version: "1.24" http_port: 80
tasks: - name: Install nginx package: name: nginx state: present
- name: Configure nginx template: src: templates/nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: Restart nginx
- name: Ensure nginx is running service: name: nginx state: started enabled: yes
handlers: - name: Restart nginx service: name: nginx state: restartedPlaybook Directives
Section titled “Playbook Directives” Playbook Keywords+------------------------------------------------------------------+| || Play Level: || +----------------------------------------------------------+ || | name - Play description | || | hosts - Target hosts/groups | || | become - Enable privilege escalation | || | become_user - User to become | || | connection - Connection type (ssh/local/winrm) | || | gather_facts - Gather system facts | || | vars - Variables for play | || | vars_files - Variable files to include | || | roles - Roles to include | || | tasks - List of tasks | || | handlers - Handler definitions | || | pre_tasks - Tasks before roles | || | post_tasks - Tasks after roles | || +----------------------------------------------------------+ || || Task Level: || +----------------------------------------------------------+ || | name - Task description | || | action - Module to execute (deprecated) | || | module - Module to execute | || | args - Module arguments (explicit) | || | notify - Handler to notify | || | register - Register output to variable | || | until - Retry until condition | || | retries - Number of retries | || | delay - Delay between retries | || | when - Conditional execution | || | changed_when - Override changed status | || | failed_when - Override failed status | || | tags - Tags for selective execution | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+48.4 Modules
Section titled “48.4 Modules”Common Modules
Section titled “Common Modules” Essential Ansible Modules+------------------------------------------------------------------+| || Package Management: || +----------------------------------------------------------+ || | package - Generic package manager | || | yum/apt/dnf - Distribution-specific | || | pacman - Arch Linux | || +----------------------------------------------------------+ || || Service Management: || +----------------------------------------------------------+ || | service - Generic service manager | || | systemd - systemd-specific | || +----------------------------------------------------------+ || || File Management: || +----------------------------------------------------------+ || | copy - Copy files | || | template - Jinja2 templated files | || | file - File attributes | || | lineinfile - Edit lines in files | || | blockinfile - Edit blocks in files | || +----------------------------------------------------------+ || || System: || | user - User management | || | group - Group management | || | cron - Cron job management | || | mount - /etc/fstab entries | || | selinux - SELinux management | || +----------------------------------------------------------+ || || Commands: || | command - Execute commands | || | shell - Execute shell commands | || | script - Execute local script | || | expect - Execute with expect | || +----------------------------------------------------------+ || || Networking: || | get_url - Download files | || | uri - HTTP requests | || | nmcli - NetworkManager CLI | || +----------------------------------------------------------+ || || Cloud: || | ec2 - AWS EC2 | || | azure_rm - Azure | || | gce - Google Cloud | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+Module Examples
Section titled “Module Examples”# Package- name: Install nginx package: name: nginx state: present
# Service- name: Start nginx service: name: nginx state: started enabled: yes
# Copy- name: Copy config copy: src: files/nginx.conf dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644'
# Template- name: Render config template: src: templates/app.conf.j2 dest: /etc/app.conf mode: '0600' vars: app_port: 8080
# File- name: Create directory file: path: /var/log/app state: directory owner: app group: app mode: '0755'
# Line in file- name: Add line to file lineinfile: path: /etc/sysctl.conf line: 'net.ipv4.ip_forward = 1' regexp: '^net.ipv4.ip_forward' create: yes
# User- name: Create deploy user user: name: deploy comment: "Deploy User" shell: /bin/bash groups: [sudo, www-data] append: yes
# Command- name: Run custom command command: /opt/app/init.sh args: chdir: /opt/app creates: /var/run/app.pid
# Shell- name: Execute shell script shell: | echo "Hello from $(hostname)" register: shell_output
# Debug- name: Show output debug: msg: "{{ shell_output.stdout }}"48.5 Variables
Section titled “48.5 Variables”Variable Precedence
Section titled “Variable Precedence” Variable Precedence (Highest to Lowest)+------------------------------------------------------------------+| || 1. extra vars ( -e ) (highest) || || 2. task vars (register) || || 3. block vars (block:) || || 4. role vars (role/vars/main.yml) || || 5. handler vars (in handler) || || 6. include vars (include) || || 7. set_facts (inline) || || 8. registered vars || || 9. host vars (inventory) || || 10. group_vars (group_vars/) || || 11. playbook vars (vars:) || || 12. playbook vars_files (vars_files:) || || 13. role defaults (role/defaults/main.yml) (lowest) || |+------------------------------------------------------------------+Variable Files
Section titled “Variable Files”---nginx_version: "1.24"nginx_workers: 4http_port: 80https_port: 443
# host_vars/web1.example.com.yml---nginx_port: 8080Using Variables
Section titled “Using Variables”- name: Use variables template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf vars: worker_processes: "{{ nginx_workers }}" listen_port: "{{ nginx_port }}"48.6 Roles
Section titled “48.6 Roles”Role Structure
Section titled “Role Structure” Ansible Role Directory Structure+------------------------------------------------------------------+| || roles/ || └── rolename/ || ├── defaults/ # Default variables || │ └── main.yml || ├── vars/ # Role variables || │ └── main.yml │| ├── tasks/ # Role tasks │| │ └── main.yml │| ├── handlers/ # Handlers │| │ └── main.yml │| ├── templates/ # Jinja2 templates │| │ └── *.j2 │| ├── files/ # Static files || │ └── * │| ├── meta/ # Role dependencies │| │ └── main.yml │| └── README.md # Documentation || |+------------------------------------------------------------------+Role Example
Section titled “Role Example”---- name: Install nginx package: name: nginx state: present
- name: Configure nginx template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf notify: Restart nginx
- name: Ensure nginx is running service: name: nginx state: started enabled: yes
# roles/nginx/handlers/main.yml---- name: Restart nginx service: name: nginx state: restarted
# roles/nginx/defaults/main.yml---nginx_port: 80nginx_workers: 4
# roles/nginx/templates/nginx.conf.j2worker_processes {{ nginx_workers }};events { worker_connections 1024;}http { server { listen {{ nginx_port }}; }}48.7 Vault
Section titled “48.7 Vault”Managing Secrets
Section titled “Managing Secrets”# Create encrypted fileansible-vault create secrets.yml
# Edit encrypted fileansible-vault edit secrets.yml
# View encrypted fileansible-vault view secrets.yml
# Encrypt existing fileansible-vault encrypt plain.yml
# Decrypt fileansible-vault decrypt secrets.yml
# Change passwordansible-vault rekey secrets.yml
# Encrypt string (for inline secrets)ansible-vault encrypt_string --stdin-name 'db_password'Using Vault in Playbooks
Section titled “Using Vault in Playbooks”- name: Deploy app hosts: all vars_files: - secrets.yml # encrypted
tasks: - name: Set database password set_fact: db_pass: "{{ db_password }}"48.8 Conditionals and Loops
Section titled “48.8 Conditionals and Loops”Conditionals
Section titled “Conditionals”- name: Install on Debian apt: name: nginx state: present when: ansible_os_family == "Debian"
- name: Install on RedHat yum: name: nginx state: present when: ansible_os_family == "RedHat"
- name: Install nginx on supported OS package: name: nginx state: present when: ansible_distribution in ['Ubuntu', 'Debian', 'CentOS', 'RedHat']# Loop over list- name: Install packages package: name: "{{ item }}" state: present loop: - nginx - mysql - postgresql
# Loop with index- name: Create users user: name: "{{ item.name }}" shell: "{{ item.shell }}" loop: - { name: 'alice', shell: '/bin/bash' } - { name: 'bob', shell: '/bin/sh' }
# Loop over dictionary- name: Set firewall rules firewalld: service: "{{ item.key }}" permanent: yes state: "{{ item.value }}" loop: { 'http': 'yes', 'https': 'yes', 'ssh': 'no' }
# With lookup- name: Read file lines debug: msg: "{{ item }}" loop: "{{ query('file', '/path/to/file.txt') }}"48.9 Best Practices
Section titled “48.9 Best Practices”Project Structure
Section titled “Project Structure” Recommended Project Structure+------------------------------------------------------------------+| || project/ || ├── inventory/ || │ ├── production/ │| │ │ ├── hosts │| │ │ └── group_vars/ │| │ └── staging/ │| │ ├── hosts │| │ └── group_vars/ │| ├── playbooks/ │| │ ├── site.yml │| │ ├── webservers.yml │| │ └── dbservers.yml │| ├── roles/ │| │ ├── common/ │| │ ├── nginx/ │| │ └── postgresql/ │| ├── vars/ ││ │ └── common.yml │| ├── files/ ││ │ └── templates/ ││ ├── library/ │| ├── module_utils/ │| ├── ansible.cfg │| └── README.md || |+------------------------------------------------------------------+ansible.cfg Best Practices
Section titled “ansible.cfg Best Practices”[defaults]inventory = inventory/production/hostsroles_path = roleshost_key_checking = Falseretry_files_enabled = Falsegathering = smartfact_caching = jsonfilefact_caching_connection = /tmp/ansible_factsstdout_callback = yamlbin_ansible_callbacks = True
[privilege_escalation]become = Truebecome_method = sudobecome_user = rootbecome_ask_pass = False
[ssh_connection]ssh_args = -o ControlMaster=auto -o ControlPersist=60spipelining = True48.10 Exam Tips
Section titled “48.10 Exam Tips”- Inventory: Use groups and patterns effectively
- Playbooks: YAML format, remember indentation
- Modules: Know common modules (package, service, copy, template)
- Variables: Understand precedence order
- Roles: Organize reusable playbooks
- Vault: Encrypt sensitive data
- Conditionals: Use
whenfor conditional execution - Loops: Use
loopinstead ofwith_items - Handlers: Use
notifyto trigger - Idempotency: Ansible should be idempotent
Summary
Section titled “Summary”In this chapter, you learned:
- ✅ Ansible architecture and how it works
- ✅ Inventory management and patterns
- ✅ Playbook structure and syntax
- ✅ Common modules
- ✅ Variables and precedence
- ✅ Roles organization
- ✅ Vault for secrets
- ✅ Conditionals and loops
- ✅ Best practices and project structure
Next Chapter
Section titled “Next Chapter”Chapter 49: Configuration Management with Puppet/Chef
Last Updated: February 2026