Skip to content

Ansible Fundamentals - Complete Guide

Overview

Ansible is an open-source automation tool for configuration management, application deployment, and task automation. It uses a simple, agentless architecture and human-readable YAML syntax.

Table of Contents

  1. What is Ansible
  2. Why Use Ansible
  3. Ansible Architecture
  4. Installation
  5. IDE Setup

What is Ansible?

Ansible is an IT automation tool that automates: - Configuration management - Application deployment - Cloud provisioning - Orchestration - Continuous delivery

Key Characteristics

  • Agentless: No need to install agents on managed nodes
  • Simple: Uses YAML for playbooks (human-readable)
  • Powerful: Can manage complex deployments
  • Idempotent: Safe to run multiple times
  • Extensible: Large collection of modules

Ansible Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│                    Ansible Architecture                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Control Node (Ansible Installed)                               │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │                                                           │  │
│  │  ┌─────────────────────────────────────────────────────┐ │  │
│  │  │  Ansible Core                                        │ │  │
│  │  │  - Playbooks (YAML)                                  │ │  │
│  │  │  - Inventory (hosts)                                 │ │  │
│  │  │  - Modules (tasks)                                   │ │  │
│  │  │  - Plugins                                           │ │  │
│  │  └─────────────────────────────────────────────────────┘ │  │
│  │                           │                              │  │
│  │                           │ SSH/WinRM                    │  │
│  │                           ▼                              │  │
│  └──────────────────────────────────────────────────────────┘  │
│                              │                                  │
│              ┌───────────────┼───────────────┐                 │
│              │               │               │                 │
│              ▼               ▼               ▼                 │
│  ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│  │  Managed Node 1 │ │  Managed Node 2 │ │  Managed Node 3 │ │
│  │  (Linux/Unix)   │ │  (Linux/Unix)   │ │  (Windows)      │ │
│  │                 │ │                 │ │                 │ │
│  │  - No Agent     │ │  - No Agent     │ │  - WinRM        │ │
│  │  - SSH Access   │ │  - SSH Access   │ │  - PowerShell   │ │
│  │  - Python       │ │  - Python       │ │                 │ │
│  └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│                                                                  │
│  Key Points:                                                    │
│  - Control node connects via SSH (Linux) or WinRM (Windows)    │
│  - No agents required on managed nodes                         │
│  - Python required on managed nodes (Linux)                    │
│  - Executes tasks and returns results                          │
└─────────────────────────────────────────────────────────────────┘

Why Use Ansible?

Advantages Over Traditional Methods

1. Ansible vs Shell Scripts

┌─────────────────────────────────────────────────────────────────┐
│              Ansible vs Shell Scripts                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Shell Scripts                                                   │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  #!/bin/bash                                              │  │
│  │  for server in server1 server2 server3; do               │  │
│  │    ssh $server "apt-get update"                          │  │
│  │    ssh $server "apt-get install -y nginx"                │  │
│  │    ssh $server "systemctl start nginx"                   │  │
│  │  done                                                     │  │
│  │                                                           │  │
│  │  ❌ Complex error handling                               │  │
│  │  ❌ No idempotency                                       │  │
│  │  ❌ Hard to maintain                                     │  │
│  │  ❌ Platform-specific                                    │  │
│  └──────────────────────────────────────────────────────────┘  │
│                                                                  │
│  Ansible Playbook                                               │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  ---                                                      │  │
│  │  - hosts: webservers                                      │  │
│  │    tasks:                                                 │  │
│  │      - name: Update apt cache                            │  │
│  │        apt:                                               │  │
│  │          update_cache: yes                               │  │
│  │                                                           │  │
│  │      - name: Install nginx                               │  │
│  │        apt:                                               │  │
│  │          name: nginx                                     │  │
│  │          state: present                                  │  │
│  │                                                           │  │
│  │      - name: Start nginx                                 │  │
│  │        service:                                          │  │
│  │          name: nginx                                     │  │
│  │          state: started                                  │  │
│  │                                                           │  │
│  │  ✅ Built-in error handling                             │  │
│  │  ✅ Idempotent by default                               │  │
│  │  ✅ Easy to read and maintain                           │  │
│  │  ✅ Cross-platform                                      │  │
│  └──────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

2. Ansible vs Python Scripts

Feature Python Scripts Ansible
Learning Curve Requires programming knowledge Simple YAML syntax
Idempotency Must implement manually Built-in
Error Handling Manual implementation Automatic
Parallel Execution Complex (threading/multiprocessing) Built-in
Inventory Management Custom implementation Built-in
Module Library Need to write or find libraries 3000+ modules included
Readability Code-based Declarative YAML

Key Benefits

  1. Agentless Architecture
  2. No software to install on managed nodes
  3. Uses SSH (Linux) or WinRM (Windows)
  4. Reduces maintenance overhead

  5. Idempotency

  6. Safe to run multiple times
  7. Only makes necessary changes
  8. Predictable outcomes

  9. Simple Syntax

  10. YAML-based playbooks
  11. Human-readable
  12. Easy to learn

  13. Powerful Modules

  14. 3000+ built-in modules
  15. Cloud providers (AWS, Azure, GCP)
  16. Databases, networking, containers
  17. Custom modules support

  18. Scalability

  19. Manage thousands of nodes
  20. Parallel execution
  21. Efficient resource usage

  22. Community & Ecosystem

  23. Large community
  24. Ansible Galaxy (shared roles)
  25. Extensive documentation

Ansible Architecture

Core Components

┌─────────────────────────────────────────────────────────────────┐
│                  Ansible Core Components                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  1. Inventory                                                    │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  [webservers]                                             │  │
│  │  web1.example.com                                         │  │
│  │  web2.example.com                                         │  │
│  │                                                           │  │
│  │  [databases]                                              │  │
│  │  db1.example.com                                          │  │
│  │  db2.example.com                                          │  │
│  └──────────────────────────────────────────────────────────┘  │
│                           ▼                                      │
│  2. Playbooks                                                    │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  ---                                                      │  │
│  │  - name: Configure web servers                           │  │
│  │    hosts: webservers                                      │  │
│  │    tasks:                                                 │  │
│  │      - name: Install nginx                               │  │
│  │        apt: name=nginx state=present                     │  │
│  └──────────────────────────────────────────────────────────┘  │
│                           ▼                                      │
│  3. Modules                                                      │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  - apt/yum (package management)                          │  │
│  │  - service (service management)                          │  │
│  │  - copy/template (file operations)                       │  │
│  │  - user/group (user management)                          │  │
│  │  - shell/command (execute commands)                      │  │
│  └──────────────────────────────────────────────────────────┘  │
│                           ▼                                      │
│  4. Plugins                                                      │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  - Connection plugins (SSH, WinRM)                       │  │
│  │  - Callback plugins (output formatting)                  │  │
│  │  - Lookup plugins (data retrieval)                       │  │
│  │  - Filter plugins (data transformation)                  │  │
│  └──────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Execution Flow

┌─────────────────────────────────────────────────────────────────┐
│                  Ansible Execution Flow                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Step 1: Read Inventory                                          │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  ansible-playbook -i inventory.ini playbook.yml          │  │
│  │  Reads: inventory.ini                                     │  │
│  │  Identifies: Target hosts                                │  │
│  └──────────────────┬───────────────────────────────────────┘  │
│                     │                                            │
│                     ▼                                            │
│  Step 2: Parse Playbook                                          │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Reads: playbook.yml                                      │  │
│  │  Validates: YAML syntax                                   │  │
│  │  Identifies: Plays and tasks                             │  │
│  └──────────────────┬───────────────────────────────────────┘  │
│                     │                                            │
│                     ▼                                            │
│  Step 3: Gather Facts                                            │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Connects to: Each host via SSH                          │  │
│  │  Collects: System information                            │  │
│  │  Stores: ansible_facts                                   │  │
│  └──────────────────┬───────────────────────────────────────┘  │
│                     │                                            │
│                     ▼                                            │
│  Step 4: Execute Tasks                                           │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  For each task:                                           │  │
│  │  1. Generate Python module                               │  │
│  │  2. Copy to remote host                                  │  │
│  │  3. Execute module                                       │  │
│  │  4. Collect results                                      │  │
│  │  5. Delete temporary files                               │  │
│  └──────────────────┬───────────────────────────────────────┘  │
│                     │                                            │
│                     ▼                                            │
│  Step 5: Report Results                                          │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Display: Task status (ok, changed, failed)              │  │
│  │  Summary: Play recap                                     │  │
│  │  Exit: With appropriate code                             │  │
│  └──────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Installation

Prerequisites

  • Control Node: Linux/Unix/macOS (Windows via WSL)
  • Managed Nodes: Linux/Unix (SSH), Windows (WinRM)
  • Python: 3.8+ on control node, 2.7+ or 3.5+ on managed nodes

Installation Methods

1. Ubuntu/Debian

# Update package index
sudo apt update

# Install software-properties-common
sudo apt install software-properties-common

# Add Ansible PPA
sudo add-apt-repository --yes --update ppa:ansible/ansible

# Install Ansible
sudo apt install ansible

# Verify installation
ansible --version

2. CentOS/RHEL

# Install EPEL repository
sudo yum install epel-release

# Install Ansible
sudo yum install ansible

# Verify installation
ansible --version

3. macOS

# Using Homebrew
brew install ansible

# Verify installation
ansible --version

4. Using pip (All Platforms)

# Install pip if not available
sudo apt install python3-pip  # Ubuntu/Debian
sudo yum install python3-pip  # CentOS/RHEL

# Install Ansible
pip3 install ansible

# Verify installation
ansible --version
# Create virtual environment
python3 -m venv ansible-venv

# Activate virtual environment
source ansible-venv/bin/activate

# Install Ansible
pip install ansible

# Verify installation
ansible --version

Post-Installation Configuration

1. Create Ansible Configuration File

# Create ansible.cfg in your project directory
cat > ansible.cfg << EOF
[defaults]
inventory = ./inventory.ini
host_key_checking = False
retry_files_enabled = False
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 86400

[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
EOF

2. Create Basic Inventory File

# Create inventory.ini
cat > inventory.ini << EOF
[local]
localhost ansible_connection=local

[webservers]
web1.example.com
web2.example.com

[databases]
db1.example.com

[all:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/id_rsa
EOF

3. Test Connection

# Test connection to localhost
ansible localhost -m ping

# Test connection to all hosts
ansible all -m ping

# Test connection to specific group
ansible webservers -m ping

IDE Setup

Visual Studio Code Setup

1. Install VS Code

# Ubuntu/Debian
sudo snap install code --classic

# Or download from https://code.visualstudio.com/

2. Install Ansible Extension

Recommended Extensions:

  1. Ansible by Red Hat
  2. Syntax highlighting
  3. Auto-completion
  4. Linting
  5. Snippets

  6. YAML by Red Hat

  7. YAML syntax support
  8. Validation
  9. Formatting

  10. Ansible Lint (Optional)

  11. Real-time linting
  12. Best practices enforcement

Installation Steps:

# Open VS Code
code .

# Install extensions via command palette (Ctrl+Shift+P)
# Or install via terminal
code --install-extension redhat.ansible
code --install-extension redhat.vscode-yaml

3. Configure VS Code Settings

Create .vscode/settings.json:

{
  "ansible.python.interpreterPath": "/usr/bin/python3",
  "ansible.validation.enabled": true,
  "ansible.validation.lint.enabled": true,
  "ansible.validation.lint.path": "ansible-lint",
  "yaml.schemas": {
    "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible.json": "playbooks/*.yml"
  },
  "yaml.customTags": [
    "!vault"
  ],
  "files.associations": {
    "*.yml": "ansible",
    "*.yaml": "ansible"
  },
  "editor.tabSize": 2,
  "editor.insertSpaces": true
}

4. Install Ansible Lint

# Install ansible-lint
pip install ansible-lint

# Verify installation
ansible-lint --version

5. Create Workspace Structure

# Create project structure
mkdir -p ansible-project/{playbooks,roles,inventory,group_vars,host_vars}

# Create .vscode directory
mkdir -p ansible-project/.vscode

# Open in VS Code
cd ansible-project
code .

VS Code Shortcuts for Ansible

Shortcut Action
Ctrl+Space Auto-completion
F12 Go to definition
Shift+F12 Find references
Ctrl+Shift+P Command palette
Ctrl+K Ctrl+F Format document
Ctrl+/ Toggle comment

Useful VS Code Snippets

Create .vscode/ansible.code-snippets:

{
  "Ansible Playbook": {
    "prefix": "playbook",
    "body": [
      "---",
      "- name: ${1:Playbook name}",
      "  hosts: ${2:all}",
      "  become: ${3:yes}",
      "  tasks:",
      "    - name: ${4:Task name}",
      "      ${5:module}:",
      "        ${6:parameter}: ${7:value}",
      "$0"
    ],
    "description": "Create Ansible playbook"
  },
  "Ansible Task": {
    "prefix": "task",
    "body": [
      "- name: ${1:Task name}",
      "  ${2:module}:",
      "    ${3:parameter}: ${4:value}",
      "$0"
    ],
    "description": "Create Ansible task"
  }
}

Directory Structure

ansible-project/
├── ansible.cfg                 # Ansible configuration
├── inventory/
│   ├── production/
│   │   ├── hosts.ini          # Production inventory
│   │   └── group_vars/
│   │       └── all.yml
│   └── staging/
│       ├── hosts.ini          # Staging inventory
│       └── group_vars/
│           └── all.yml
├── playbooks/
│   ├── site.yml               # Main playbook
│   ├── webservers.yml
│   └── databases.yml
├── roles/
│   ├── common/
│   ├── webserver/
│   └── database/
├── group_vars/
│   ├── all.yml                # Variables for all hosts
│   ├── webservers.yml
│   └── databases.yml
├── host_vars/
│   └── web1.example.com.yml
├── files/                     # Static files
├── templates/                 # Jinja2 templates
├── vars/                      # Additional variables
└── README.md

Best Practices

1. Version Control

# Initialize git repository
git init

# Create .gitignore
cat > .gitignore << EOF
*.retry
*.pyc
__pycache__/
.vault_pass
.vscode/
*.log
EOF

# Commit initial structure
git add .
git commit -m "Initial Ansible project structure"

2. Use Ansible Vault for Secrets

# Create encrypted file
ansible-vault create secrets.yml

# Edit encrypted file
ansible-vault edit secrets.yml

# Encrypt existing file
ansible-vault encrypt vars/passwords.yml

3. Test Before Production

# Check syntax
ansible-playbook playbook.yml --syntax-check

# Dry run
ansible-playbook playbook.yml --check

# Run on staging first
ansible-playbook -i inventory/staging playbook.yml

4. Use Roles for Reusability

# Create role structure
ansible-galaxy init roles/webserver

# Use role in playbook
# playbook.yml
---
- hosts: webservers
  roles:
    - webserver

Summary

  • Ansible is an agentless automation tool using YAML
  • Advantages: Simple, powerful, idempotent, scalable
  • Architecture: Control node manages nodes via SSH/WinRM
  • Installation: Multiple methods (apt, yum, pip, brew)
  • IDE Setup: VS Code with Ansible extensions recommended
  • Best Practices: Version control, vault for secrets, testing

Ansible simplifies infrastructure automation with its declarative approach and extensive module library, making it ideal for configuration management and deployment automation.