Getting Started with Ansible for Linux System Administration

System administration can be tedious and time-consuming, especially when managing multiple remote servers. Ansible provides a powerful solution for automating these tasks, making server management more efficient and less error-prone. Here’s how to set up Ansible and create your first playbooks for managing Linux servers.

Key Concepts

Ansible: An automation tool that uses YAML for defining configurations, making it human-readable and easy to manage. It operates over SSH, requiring no agents on remote systems.

Inventory: A list of managed nodes (servers) grouped by roles or environments. This file tells Ansible which servers to target.

Playbooks: YAML files that define automation tasks. They describe the desired state of your systems.

Modules: Pre-written scripts that Ansible uses to perform tasks. Ansible has modules for package management, file manipulation, user management, etc.

Roles: A way to organize your playbooks and related files to make them reusable and modular.

Setting Up the Inventory

Create your inventory file in YAML format:

all:
  children:
    webservers:
      hosts:
        web1:
          ansible_host: 192.168.1.101
        web2:
          ansible_host: 192.168.1.102
    dbservers:
      hosts:
        db1:
          ansible_host: 192.168.1.103
  vars:
    ansible_user: admin
    ansible_ssh_private_key_file: ~/.ssh/id_rsa

This inventory includes groups for webservers and dbservers, with variables for SSH access.

Configuring SSH Access

  1. Generate SSH keys:
ssh-keygen -t rsa -b 4096
  1. Copy your SSH key to each remote server:
ssh-copy-id admin@192.168.1.101
ssh-copy-id admin@192.168.1.102
ssh-copy-id admin@192.168.1.103

Creating Your First Playbook

Here’s a playbook to update and upgrade all servers:

---
- name: Update and upgrade all servers
  hosts: all
  become: true
  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes
      when: ansible_os_family == "Debian"

    - name: Upgrade all packages
      apt:
        upgrade: dist
      when: ansible_os_family == "Debian"

    - name: Update dnf cache
      dnf:
        update_cache: yes
      when: ansible_os_family == "RedHat" or ansible_distribution == "EndeavourOS" or ansible_distribution == "Arch"

    - name: Upgrade all packages
      dnf:
        name: "*"
        state: latest
      when: ansible_os_family == "RedHat" or ansible_distribution == "EndeavourOS" or ansible_distribution == "Arch"

    - name: Check if reboot is required
      register: reboot_required_file
      stat:
        path: /var/run/reboot-required
      when: ansible_os_family == "Debian"

    - name: Reboot if required
      reboot:
        msg: "Reboot required to complete system updates"
      when: 
        - ansible_os_family == "Debian"
        - reboot_required_file.stat.exists

Basic Server Hardening Playbook

Here’s a playbook for basic server hardening:

---
- name: Basic server hardening
  hosts: all
  become: true
  tasks:
    - name: Install fail2ban
      package:
        name: fail2ban
        state: present

    - name: Enable and start fail2ban
      service:
        name: fail2ban
        state: started
        enabled: yes

    - name: Configure UFW
      ufw:
        state: enabled
        policy: deny
        logging: on

    - name: Allow SSH through UFW
      ufw:
        rule: allow
        port: ssh
        proto: tcp

    - name: Set SSH configuration
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: "{{ item.regexp }}"
        line: "{{ item.line }}"
        state: present
      loop:
        - { regexp: '^PermitRootLogin', line: 'PermitRootLogin no' }
        - { regexp: '^PasswordAuthentication', line: 'PasswordAuthentication no' }
        - { regexp: '^X11Forwarding', line: 'X11Forwarding no' }

    - name: Restart SSH service
      service:
        name: sshd
        state: restarted

Running Your Playbooks

To execute your playbooks:

# Test connectivity to all servers
ansible all -m ping

# Run the system update playbook
ansible-playbook system_update.yml

# Run the server hardening playbook
ansible-playbook server_hardening.yml

Best Practices

  • Version Control: Use Git to manage your Ansible configurations.
  • Use Vault: Encrypt sensitive data with Ansible Vault.
  • Test First: Use --check mode to test playbooks before applying changes.
  • Use Tags: Tag tasks for selective execution.

Conclusion

Ansible simplifies system administration by automating repetitive tasks. This guide has introduced you to setting up Ansible, creating inventories, and writing playbooks for basic server management. As you advance, explore roles, collections, and more complex configurations to further enhance your automation capabilities.

Next Steps

  • Dive into Ansible roles and collections for more structured playbooks.
  • Explore Ansible Galaxy for community roles.
  • Implement continuous deployment with Ansible.
  • Master Ansible variables and templates for dynamic configurations.