# Day 10 - Configuration Management with Ansible

### What is Ansible?

**Ansible** is an **open-source configuration management, deployment, and automation tool** developed by **Red Hat**.  
It helps system administrators automate repetitive tasks like software installation, updates, configuration, and orchestration across multiple servers — without needing to log in to each server manually.

---

## 🔧 Real-World Scenario

A system administrator manages **hundreds of servers** with different operating systems — Ubuntu, CentOS, and Windows.  
Common tasks include:

1. OS updates
    
2. Applying security patches
    
3. Installing software (e.g., Git, databases)
    

### ❌ Problem

* Doing this **manually** on each server is time-consuming.
    
* Scripts were used (e.g., PowerShell for Windows, Bash for Linux), but maintaining them across multiple OS types was difficult.
    
* With **cloud and microservices**, the number of servers grew drastically → scripts became inefficient.
    

### ✅ Solution — Configuration Management Tools

Tools like **Puppet**, **Chef**, and **Ansible** emerged to automate configuration tasks.  
Among these, **Ansible** became the most popular due to its **simplicity, agentless architecture, and YAML-based playbooks**.

---

## ⚖️ Why Ansible is Better than Puppet

| Feature | Puppet | Ansible |
| --- | --- | --- |
| **Mechanism** | Pull (agents pull config from master) | Push (controller pushes config) |
| **Architecture** | Master-Agent setup required | Agentless (uses SSH) |
| **Ease of Setup** | Complex (needs master/agent setup) | Simple (just IPs in inventory) |
| **Windows Support** | Limited | Better |
| **Language** | Puppet DSL | YAML (easier and readable) |
| **Dynamic Inventory** | Manual updates required | Auto-detects new hosts dynamically |

---

## ⚠️ Limitations of Ansible

1. **Windows support** is still not fully seamless
    
2. **Debugging** is not very intuitive
    
3. **Performance** may lag when managing thousands of servers
    

---

## ⚙️ Ansible Installation & Setup

To start using Ansible:

* You need **two servers**:
    
    * **Control Node** → where Ansible is installed
        
    * **Managed Node(s)** → target servers
        

### 🔑 Passwordless Authentication

1. On Ansible server:
    
    ```plaintext
    ssh-keygen
    cat ~/.ssh/id_rsa.pub
    ```
    
2. On Target server:
    
    * Add copied key to authorized\_keys
        
    
    ```plaintext
    vi ~/.ssh/authorized_keys
    ```
    

---

## 🗂️ Inventory File

The **inventory file** contains IP addresses or hostnames of target servers.

* **Default path:** `/etc/ansible/hosts`
    
* You can also use a custom file via `-i` flag.
    

**Example:**

```plaintext
[webservers]
192.168.10.10
192.168.10.11

[dbservers]
192.168.20.10
192.168.20.11
```

---

## ⚡ Ad-hoc Commands

Used for **quick, one-time tasks** (no need for a playbook).

**Syntax:**

```plaintext
ansible -i inventory_file <host/group> -m <module> -a "<command>"
```

**Examples:**

```plaintext
ansible all -m shell -a "uptime"
ansible webservers -m shell -a "nproc"
```

---

## 📘 Ansible Playbook

For **complex, multi-step tasks**, use **playbooks** written in YAML.

**Example: Installing and starting Nginx**

```plaintext
---
- name: Install and start Nginx
  hosts: all
  become: true
  
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present
    
    - name: Start Nginx service
      service:
        name: nginx
        state: started
```

**Run the playbook:**

```plaintext
ansible-playbook -i inventory_file playbook.yml
```

Use `-v` for verbose output.

---

## 🧩 Ansible Roles

Roles help **organize and structure** large playbooks into reusable components.

**Create a role:**

```plaintext
ansible-galaxy init kubernetes
```

**Structure created:**

```plaintext
kubernetes/
├── defaults/        # Default variables
├── files/           # Static files to copy
├── handlers/        # Handlers (e.g., restart service)
├── meta/            # Metadata about the role
├── tasks/           # Main tasks go here
├── templates/       # Jinja2 templates
├── tests/           # Test playbooks
└── vars/            # Variable definitions
```

Write your playbook logic in `tasks/main.yml`.

---

## 🔐 Ansible Vault

Used to **encrypt sensitive information** like passwords, API keys, or AWS credentials in playbooks.

**Scenario:**  
You have AWS credentials inside a playbook — you can’t push it to GitHub as plain text.

**Commands:**

1. **Create an encrypted file**
    
    ```plaintext
    ansible-vault create secrets.yml
    ```
    
2. **Edit an existing vault file**
    
    ```plaintext
    ansible-vault edit secrets.yml
    ```
    
3. **Encrypt an existing file**
    
    ```plaintext
    ansible-vault encrypt playbook.yml
    ```
    
4. **Decrypt a file**
    
    ```plaintext
    ansible-vault decrypt playbook.yml
    ```
    
5. **Run playbook with vault password**
    
    ```plaintext
    ansible-playbook playbook.yml --ask-vault-pass
    ```
    

## **Summary Table**

| Concept | Description |
| --- | --- |
| **Ansible** | Agentless configuration management tool (push model) |
| **Inventory** | List of managed nodes |
| **Ad-hoc Commands** | One-time actions on servers |
| **Playbook** | YAML file containing tasks |
| **Roles** | Reusable and modular playbook structure |
| **Vault** | Encrypt sensitive data |
| **Dynamic Inventory** | Auto-detect infrastructure (e.g., AWS EC2) |
