Skip to main content

Ansible Security Automation

Introduction

Security automation is becoming increasingly critical as organizations manage complex infrastructures with numerous endpoints, applications, and network devices. Ansible Security Automation provides a powerful framework that enables security teams to implement consistent, repeatable security practices across diverse environments.

In this guide, we'll explore how Ansible can be leveraged to automate security tasks, from simple compliance checks to complex incident response workflows. By the end of this tutorial, you'll understand how to use Ansible to strengthen your organization's security posture while reducing manual overhead.

What is Ansible Security Automation?

Ansible Security Automation applies Ansible's infrastructure as code principles to security operations. It allows security teams to:

  • Define security configurations as code
  • Apply security policies consistently across environments
  • Automate security responses to detected threats
  • Integrate with existing security tools via modules
  • Create reproducible security workflows

Prerequisites

Before diving into security automation with Ansible, you should have:

  • Basic understanding of Ansible concepts (playbooks, roles, inventory)
  • Ansible installed (version 2.9 or higher recommended)
  • Basic familiarity with security concepts
  • Target systems to manage (can be virtual machines for practice)

Setting Up Your Environment

Let's start by creating a directory structure for your security automation projects:

bash
mkdir -p ansible-security/playbooks
mkdir -p ansible-security/roles
mkdir -p ansible-security/inventory
cd ansible-security

Create a basic inventory file (inventory/hosts.ini):

ini
[web_servers]
webserver1.example.com
webserver2.example.com

[database_servers]
db1.example.com
db2.example.com

[security_scanners]
scanner.example.com

Basic Security Hardening with Ansible

Let's create a simple playbook for basic server hardening. This is a foundational security automation task.

Create a file named playbooks/basic_hardening.yml:

yaml
---
- name: Basic Server Security Hardening
hosts: web_servers
become: yes

tasks:
- name: Ensure strong 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' }
notify: Restart SSH

- name: Update all packages
package:
name: "*"
state: latest
register: package_update_result

- name: Install security tools
package:
name:
- fail2ban
- ufw
state: present

- name: Enable and configure firewall
ufw:
state: enabled
policy: deny

- name: Allow SSH connections
ufw:
rule: allow
port: 22
proto: tcp

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

To run this playbook:

bash
ansible-playbook -i inventory/hosts.ini playbooks/basic_hardening.yml

Security Compliance Scanning

Ansible can automate security compliance checks. Let's create a playbook that performs compliance scanning using OpenSCAP:

yaml
---
- name: Run Security Compliance Scan
hosts: web_servers
become: yes

tasks:
- name: Ensure OpenSCAP is installed
package:
name:
- openscap-scanner
- scap-security-guide
state: present

- name: Run DISA STIG scan
command: >
oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_stig
--results /tmp/stig-results.xml
--report /tmp/stig-report.html
/usr/share/xml/scap/ssg/content/ssg-rhel7-ds.xml
args:
creates: /tmp/stig-results.xml
when: ansible_distribution == 'RedHat' and ansible_distribution_major_version == '7'
ignore_errors: yes

- name: Fetch compliance reports
fetch:
src: /tmp/stig-report.html
dest: reports/{{ inventory_hostname }}-stig-report.html
flat: yes

Automated Security Incident Response

One of the most powerful uses of Ansible for security is automating incident response. Let's create a playbook that responds to a potential intrusion:

yaml
---
- name: Security Incident Response
hosts: compromised_servers
become: yes

tasks:
- name: Collect system information
block:
- name: Get running processes
command: ps aux
register: running_processes

- name: Get network connections
command: netstat -tulpn
register: network_connections

- name: Get last logins
command: last
register: last_logins

- name: Save forensic information
copy:
content: |
=== PROCESSES ===
{{ running_processes.stdout }}

=== NETWORK CONNECTIONS ===
{{ network_connections.stdout }}

=== LAST LOGINS ===
{{ last_logins.stdout }}
dest: /tmp/forensic-{{ ansible_date_time.iso8601 }}.txt

- name: Fetch forensic data
fetch:
src: /tmp/forensic-{{ ansible_date_time.iso8601 }}.txt
dest: forensics/
flat: no

- name: Isolate system by updating firewall
ufw:
state: enabled
policy: deny

- name: Allow only security team access
ufw:
rule: allow
port: 22
proto: tcp
src: "{{ security_team_ip_range }}"

To use this playbook:

bash
# Define the compromised servers in an ad-hoc group
ansible-playbook -i inventory/hosts.ini playbooks/incident_response.yml -e "compromised_servers=webserver1.example.com security_team_ip_range=10.0.0.0/24"

Creating a Security Role

For reusable security automation, create an Ansible role. Here's how to set up a basic security role:

bash
ansible-galaxy init roles/security_baseline

Edit roles/security_baseline/tasks/main.yml:

yaml
---
# Security baseline tasks

- name: Include OS-specific variables
include_vars: "{{ ansible_os_family }}.yml"

- name: Include OS-specific tasks
include_tasks: "{{ ansible_os_family }}.yml"

- name: Ensure critical security packages are installed
package:
name: "{{ security_packages }}"
state: present

- name: Configure system-wide security settings
sysctl:
name: "{{ item.key }}"
value: "{{ item.value }}"
state: present
reload: yes
loop: "{{ sysctl_security_settings | dict2items }}"

- name: Set secure file permissions
file:
path: "{{ item.path }}"
mode: "{{ item.mode }}"
owner: "{{ item.owner | default('root') }}"
group: "{{ item.group | default('root') }}"
loop: "{{ secure_files }}"

Create roles/security_baseline/vars/RedHat.yml:

yaml
---
security_packages:
- aide
- fail2ban
- libselinux-python
- policycoreutils-python

sysctl_security_settings:
net.ipv4.conf.all.accept_redirects: 0
net.ipv4.conf.all.send_redirects: 0
net.ipv4.conf.all.accept_source_route: 0
net.ipv4.conf.all.log_martians: 1

secure_files:
- path: /etc/shadow
mode: '0000'
- path: /etc/gshadow
mode: '0000'
- path: /etc/passwd
mode: '0644'

Create a playbook to use this role (playbooks/apply_security_baseline.yml):

yaml
---
- name: Apply Security Baseline
hosts: all
become: yes

roles:
- security_baseline

Integrating with Security Tools

Ansible can integrate with popular security tools. Here's a playbook that integrates with Nessus for vulnerability scanning:

yaml
---
- name: Vulnerability Scanning with Nessus
hosts: localhost
gather_facts: no

vars:
nessus_server: "https://nessus.example.com:8834"
nessus_api_token: "{{ lookup('env', 'NESSUS_API_TOKEN') }}"
scan_targets: "192.168.1.0/24"
scan_name: "Weekly Infrastructure Scan"

tasks:
- name: Create new scan
uri:
url: "{{ nessus_server }}/scans"
method: POST
headers:
X-ApiKeys: "accessKey={{ nessus_api_token }}"
Content-Type: "application/json"
body_format: json
body:
uuid: "ad629e16-03b6-8c1d-cef6-ef8c9dd3c658d24bd260ef5f9e66" # Basic network scan template
settings:
name: "{{ scan_name }}"
text_targets: "{{ scan_targets }}"
launch_now: true
status_code: 200
validate_certs: no
register: scan_result

- name: Wait for scan to complete
uri:
url: "{{ nessus_server }}/scans/{{ scan_result.json.scan.id }}"
method: GET
headers:
X-ApiKeys: "accessKey={{ nessus_api_token }}"
status_code: 200
validate_certs: no
register: scan_status
until: scan_status.json.info.status == 'completed'
retries: 60
delay: 30

- name: Export scan results
uri:
url: "{{ nessus_server }}/scans/{{ scan_result.json.scan.id }}/export"
method: POST
headers:
X-ApiKeys: "accessKey={{ nessus_api_token }}"
Content-Type: "application/json"
body_format: json
body:
format: "pdf"
status_code: 200
validate_certs: no
register: export_result

- name: Download scan report
uri:
url: "{{ nessus_server }}/scans/{{ scan_result.json.scan.id }}/export/{{ export_result.json.file }}/download"
method: GET
headers:
X-ApiKeys: "accessKey={{ nessus_api_token }}"
dest: "./reports/vulnerability_scan_{{ ansible_date_time.iso8601_basic_short }}.pdf"
validate_certs: no

Creating a Security Automation Workflow

Let's tie everything together into a comprehensive security workflow:

Create a master playbook (playbooks/security_workflow.yml):

yaml
---
- name: Complete Security Automation Workflow
hosts: all
become: yes

tasks:
- name: Apply security baseline
include_role:
name: security_baseline
tags: [baseline]

- name: Run compliance checks
include_tasks: tasks/compliance_check.yml
tags: [compliance]

- name: Apply compliance remediation if needed
include_tasks: tasks/compliance_remediation.yml
when: compliance_status is defined and compliance_status == 'failed'
tags: [compliance]

- name: Run vulnerability scan
include_tasks: tasks/vulnerability_scan.yml
tags: [vulnerability]

- name: Apply security patches if needed
include_tasks: tasks/patch_systems.yml
when: vulnerabilities_found is defined and vulnerabilities_found|bool
tags: [vulnerability, patching]

- name: Generate security reports
include_tasks: tasks/generate_reports.yml
tags: [reporting]

Scheduling Regular Security Automation

To ensure regular security checks, you can use cron to schedule your Ansible security playbooks:

bash
# Add to root's crontab
0 2 * * 0 ansible-playbook -i /path/to/inventory/hosts.ini /path/to/playbooks/security_workflow.yml >> /var/log/ansible-security.log 2>&1

This will run the security workflow every Sunday at 2 AM.

Monitoring Ansible Security Automation

To monitor your security automation, you can add callback plugins to notify your team about playbook results:

Create ansible.cfg in your project directory:

ini
[defaults]
callback_whitelist = slack, mail

[callback_slack]
webhook_url = https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
channel = #security-automation
username = Ansible Security Bot

[callback_mail]
smtphost = smtp.example.com
sender = [email protected]
recipient = [email protected]

Real-World Example: Automated Firewall Management

Let's look at a practical example of using Ansible to manage firewall rules across different platforms:

yaml
---
- name: Unified Firewall Management
hosts: all
become: yes

tasks:
- name: Gather firewall type
setup:
gather_subset:
- "!all"
- "!min"
- "network"

- name: Configure UFW (Ubuntu/Debian)
block:
- name: Ensure UFW is installed
apt:
name: ufw
state: present

- name: Reset UFW
ufw:
state: reset

- name: Set default policies
ufw:
direction: "{{ item.direction }}"
policy: "{{ item.policy }}"
loop:
- { direction: incoming, policy: deny }
- { direction: outgoing, policy: allow }

- name: Configure firewall rules
ufw:
rule: "{{ item.rule }}"
port: "{{ item.port }}"
proto: "{{ item.proto }}"
loop: "{{ firewall_rules }}"

- name: Enable UFW
ufw:
state: enabled
when: ansible_os_family == "Debian"

- name: Configure firewalld (CentOS/RHEL)
block:
- name: Ensure firewalld is installed
yum:
name: firewalld
state: present

- name: Start and enable firewalld
service:
name: firewalld
state: started
enabled: yes

- name: Configure firewall rules
firewalld:
port: "{{ item.port }}/{{ item.proto }}"
permanent: yes
state: "{{ 'enabled' if item.rule == 'allow' else 'disabled' }}"
loop: "{{ firewall_rules }}"

- name: Reload firewalld
command: firewall-cmd --reload
when: ansible_os_family == "RedHat"

vars:
firewall_rules:
- { rule: allow, port: 22, proto: tcp } # SSH
- { rule: allow, port: 80, proto: tcp } # HTTP
- { rule: allow, port: 443, proto: tcp } # HTTPS

Summary

In this guide, we've covered how to use Ansible for security automation, including:

  • Basic server hardening
  • Compliance scanning
  • Incident response
  • Creating reusable security roles
  • Integration with security tools
  • Building security workflows
  • Scheduling regular security checks
  • Monitoring automation results
  • Real-world firewall management

By leveraging Ansible for security automation, you can ensure consistent security practices across your infrastructure, respond to threats more quickly, and reduce the manual overhead of security operations.

Additional Resources

Exercises

  1. Create a playbook that performs automated log analysis to detect suspicious activities.
  2. Extend the security baseline role to include different configurations for various operating systems.
  3. Design a playbook that integrates with your organization's SIEM system to pull security alerts and automate responses.
  4. Create a compliance report template that converts OpenSCAP results into a human-readable format.
  5. Build a workflow that automatically tests and applies security patches to non-production environments, then generates a report for approval before applying to production.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)