← News
/PLAYBOOK · 2026-08-17

Ansible Security Automation: Bulk Server Hardening Configuration Guide

Ansible Playbooks for bulk Linux security-baseline hardening: SSH lockdown, firewall rules, system updates, and password policy — automated configuration.

Use Cases

Ansible security automation fits: tens to hundreds of Linux servers that need a uniform security baseline (SSH, firewall, password policy); new hosts that must be compliant before handover; security teams that want hardening as code — auditable, reversible, repeatable.

Prerequisites

How It Works

Ansible is agentless. The control node SSHes to targets and runs modules. No client install on targets. Hardening is a Playbook: declarative desired state — SSH password login off, firewall allow-list, password expiry, etc. Idempotence means re-runs converge to the same state. `--check` previews diffs. Cuts blast radius on bulk change.

Procedure

Step 1: Install Ansible and write the inventory

pip install ansible
# Edit inventory /etc/ansible/hosts
[webservers]
web01 ansible_host=192.168.1.11
web02 ansible_host=192.168.1.12

# Test reachability
ansible webservers -m ping

Step 2: Write the hardening Playbook

# secure.yml
- hosts: webservers
  become: yes
  tasks:
    - name: Disable SSH root login
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: '^PermitRootLogin'
        line: 'PermitRootLogin no'
      notify: restart sshd

    - name: Firewall allow 22/80/443 only
      firewalld:
        port: "{{ item }}"
        permanent: yes
        state: enabled
        immediate: yes
      loop:
        - 22/tcp
        - 80/tcp
        - 443/tcp

    - name: Set password max age 90 days
      lineinfile:
        path: /etc/login.defs
        regexp: '^PASS_MAX_DAYS'
        line: 'PASS_MAX_DAYS 90'

  handlers:
    - name: restart sshd
      service:
        name: sshd
        state: restarted

Step 3: Check, then apply

# Dry-run: print planned changes only
ansible-playbook secure.yml --check
# Apply
ansible-playbook secure.yml

Verification

Re-run `ansible-playbook secure.yml`: all tasks `ok`, none `changed` — idempotent, desired state reached. Password SSH should be rejected. Root remote login fails. Firewall allows listed ports only; other ports time out.

FAQ

Q1: Hardening ran and I lost SSH. Now what?

Classic failure mode. Keep an existing session open first; that session stays up. Before changing SSH, test `ssh` from another window on the control node. Add `validate` on the sshd config task so a bad config rolls back.

Q2: Different hardening per environment?

Use `group_vars` and `host_vars`. Separate variable files per env (dev/test/prod). Prod forces `PermitRootLogin no` and a stricter password policy; dev can be looser. Playbook reads the vars.

Summary

Ansible turns repetitive manual hardening into reusable code. Write once, apply to the fleet. `--check` plus idempotence balances speed and safety. For multi-server estates, this is the step from manual ops to a standardized security baseline.