Understanding Ansible Roles for Security

April 17, 2024
ansible

When managing large-scale systems, security configurations can become complex and error-prone if handled manually. Ansible roles provide a structured way to organize, reuse, and maintain security automation tasks. Let’s explore how to leverage roles effectively for security automation.

What Are Ansible Roles?

Roles in Ansible are units of reusable automation that include variables, tasks, files, templates, and handlers. They help you:

  • Organize related security tasks logically
  • Share security configurations across projects
  • Maintain consistent security baselines
  • Scale security implementations efficiently

Role Structure

A typical security role follows this structure:

security_baseline/
├── defaults/       # Default variables
│   └── main.yml
├── files/         # Static files
│   └── banner.txt
├── handlers/      # Service handlers
│   └── main.yml
├── meta/          # Dependencies
│   └── main.yml
├── tasks/         # Security tasks
│   ├── main.yml
│   ├── firewall.yml
│   └── ssh.yml
├── templates/     # Configuration templates
│   └── sshd_config.j2
└── vars/          # Role variables
    └── main.yml

Directory Purposes

defaults/

Stores default variables that users can override:

# defaults/main.yml
---
security_ssh_port: 22
security_allowed_users: []
security_password_max_days: 90

files/

Contains static files like security banners or policies:

# files/banner.txt
WARNING: Unauthorized access is prohibited.
All activities are logged and monitored.

handlers/

Defines service restart handlers:

# handlers/main.yml
---
- name: restart sshd
  service:
    name: sshd
    state: restarted

- name: reload firewall
  service:
    name: ufw
    state: reloaded

tasks/

Implements security configurations:

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

- name: Apply common security configurations
  include_tasks: common.yml

templates/

Stores configuration templates:

# templates/sshd_config.j2
Port {{ security_ssh_port }}
PermitRootLogin no
PasswordAuthentication {{ security_allow_password_auth | default('no') }}

Creating Security Roles

Basic Example

Here’s a simple security baseline role:

# tasks/main.yml
---
- name: Update system packages
  apt:
    update_cache: yes
    upgrade: yes
  when: ansible_os_family == "Debian"

- name: Install security packages
  apt:
    name:
      - ufw
      - fail2ban
      - aide
    state: present
  when: ansible_os_family == "Debian"

- name: Configure SSH
  template:
    src: sshd_config.j2
    dest: /etc/ssh/sshd_config
    validate: /usr/sbin/sshd -t -f %s
  notify: restart sshd

Role Variables

Define customizable security settings:

# defaults/main.yml
---
# SSH Configuration
security_ssh_port: 22
security_allow_users: []
security_max_auth_tries: 3

# Firewall Settings
security_allowed_ports:
  - "{{ security_ssh_port }}"
  - 80
  - 443

# Password Policy
security_password_min_length: 12
security_password_max_days: 90

Role Dependencies

Specify required roles:

# meta/main.yml
---
dependencies:
  - role: firewall
  - role: ssh_hardening

Using Security Roles

In Playbooks

Apply security roles to hosts:

---
- hosts: all
  become: yes
  roles:
    - security_baseline
  vars:
    security_ssh_port: 2222
    security_allowed_users:
      - admin
      - deployer

Role Tags

Use tags for selective execution:

# tasks/main.yml
---
- name: Configure firewall
  include_tasks: firewall.yml
  tags: [security, firewall]

- name: Harden SSH
  include_tasks: ssh.yml
  tags: [security, ssh]

Run specific security tasks:

ansible-playbook site.yml --tags "firewall"

Best Practices

1. Keep Roles Focused

  • One role should handle one security aspect
  • Split complex security tasks into separate roles
  • Maintain clear boundaries between different security concerns

2. Use Version Control

  • Store roles in a Git repository
  • Track changes to security configurations
  • Document role modifications

3. Test Thoroughly

  • Verify role functionality in staging
  • Test idempotency
  • Validate security configurations

4. Document Everything

  • Explain role variables
  • Describe security implications
  • Provide usage examples

Conclusion

Ansible roles provide a powerful way to standardize security configurations across your infrastructure. By following these guidelines, you can create maintainable, reusable security automation that scales with your needs.

Remember to:

  • Start with focused, well-structured roles
  • Use variables for flexibility
  • Test thoroughly before production
  • Keep security configurations under version control
  • Document your roles comprehensively