Claude
Skills
Sign in
Back

ansible-roles

Included with Lifetime
$97 forever

Use when structuring and reusing code with Ansible roles for modular, maintainable automation and configuration management.

General

What this skill does


# Ansible Roles

Structure and reuse automation code with Ansible roles for modular, maintainable infrastructure.

## Role Directory Structure

A well-organized Ansible role follows a standardized directory structure:

```
roles/
└── webserver/
    ├── README.md
    ├── defaults/
    │   └── main.yml
    ├── files/
    │   ├── nginx.conf
    │   └── ssl/
    │       ├── cert.pem
    │       └── key.pem
    ├── handlers/
    │   └── main.yml
    ├── meta/
    │   └── main.yml
    ├── tasks/
    │   ├── main.yml
    │   ├── install.yml
    │   ├── configure.yml
    │   └── security.yml
    ├── templates/
    │   ├── nginx.conf.j2
    │   └── site.conf.j2
    ├── tests/
    │   ├── inventory
    │   └── test.yml
    └── vars/
        └── main.yml
```

## Basic Role Example

### tasks/main.yml

```yaml
---
# Main task file for webserver role
- name: Include OS-specific variables
  include_vars: "{{ ansible_os_family }}.yml"

- name: Import installation tasks
  import_tasks: install.yml
  tags:
    - install
    - webserver

- name: Import configuration tasks
  import_tasks: configure.yml
  tags:
    - configure
    - webserver

- name: Import security tasks
  import_tasks: security.yml
  tags:
    - security
    - webserver

- name: Ensure nginx is running
  service:
    name: "{{ nginx_service_name }}"
    state: started
    enabled: yes
  tags:
    - service
    - webserver
```

### tasks/install.yml

```yaml
---
# Installation tasks for webserver role
- name: Install nginx and dependencies (Debian/Ubuntu)
  apt:
    name:
      - nginx
      - nginx-extras
      - python3-passlib
    state: present
    update_cache: yes
    cache_valid_time: 3600
  when: ansible_os_family == "Debian"

- name: Install nginx and dependencies (RedHat/CentOS)
  yum:
    name:
      - nginx
      - nginx-mod-stream
      - python3-passlib
    state: present
    update_cache: yes
  when: ansible_os_family == "RedHat"

- name: Create nginx directories
  file:
    path: "{{ item }}"
    state: directory
    owner: "{{ nginx_user }}"
    group: "{{ nginx_group }}"
    mode: '0755'
  loop:
    - "{{ nginx_conf_dir }}/sites-available"
    - "{{ nginx_conf_dir }}/sites-enabled"
    - "{{ nginx_log_dir }}"
    - "{{ nginx_cache_dir }}"
    - /var/www/html

- name: Install certbot for SSL
  apt:
    name: certbot
    state: present
  when:
    - nginx_ssl_enabled
    - ansible_os_family == "Debian"
```

### tasks/configure.yml

```yaml
---
# Configuration tasks for webserver role
- name: Deploy main nginx configuration
  template:
    src: nginx.conf.j2
    dest: "{{ nginx_conf_dir }}/nginx.conf"
    owner: root
    group: root
    mode: '0644'
    validate: 'nginx -t -c %s'
    backup: yes
  notify:
    - Reload nginx
  tags:
    - config

- name: Deploy site configurations
  template:
    src: site.conf.j2
    dest: "{{ nginx_conf_dir }}/sites-available/{{ item.name }}.conf"
    owner: root
    group: root
    mode: '0644'
    validate: 'nginx -t -c {{ nginx_conf_dir }}/nginx.conf'
  loop: "{{ nginx_sites }}"
  when: nginx_sites is defined
  notify:
    - Reload nginx

- name: Enable sites
  file:
    src: "{{ nginx_conf_dir }}/sites-available/{{ item.name }}.conf"
    dest: "{{ nginx_conf_dir }}/sites-enabled/{{ item.name }}.conf"
    state: link
  loop: "{{ nginx_sites }}"
  when:
    - nginx_sites is defined
    - item.enabled | default(true)
  notify:
    - Reload nginx

- name: Disable default site
  file:
    path: "{{ nginx_conf_dir }}/sites-enabled/default"
    state: absent
  when: nginx_disable_default_site
  notify:
    - Reload nginx

- name: Configure log rotation
  template:
    src: logrotate.j2
    dest: /etc/logrotate.d/nginx
    owner: root
    group: root
    mode: '0644'
```

### tasks/security.yml

```yaml
---
# Security tasks for webserver role
- name: Generate dhparam file
  command: openssl dhparam -out {{ nginx_conf_dir }}/dhparam.pem 2048
  args:
    creates: "{{ nginx_conf_dir }}/dhparam.pem"
  when: nginx_ssl_enabled

- name: Set secure permissions on dhparam
  file:
    path: "{{ nginx_conf_dir }}/dhparam.pem"
    owner: root
    group: root
    mode: '0600'
  when: nginx_ssl_enabled

- name: Configure firewall rules (ufw)
  ufw:
    rule: allow
    port: "{{ item }}"
    proto: tcp
  loop:
    - "80"
    - "443"
  when:
    - nginx_configure_firewall
    - ansible_os_family == "Debian"

- name: Configure firewall rules (firewalld)
  firewalld:
    service: "{{ item }}"
    permanent: yes
    state: enabled
    immediate: yes
  loop:
    - http
    - https
  when:
    - nginx_configure_firewall
    - ansible_os_family == "RedHat"

- name: Create basic auth file
  htpasswd:
    path: "{{ nginx_conf_dir }}/.htpasswd"
    name: "{{ item.username }}"
    password: "{{ item.password }}"
    owner: root
    group: "{{ nginx_group }}"
    mode: '0640'
  loop: "{{ nginx_basic_auth_users }}"
  when: nginx_basic_auth_users is defined
  no_log: yes
```

## Role Variables

### defaults/main.yml

```yaml
---
# Default variables for webserver role
# These can be overridden in playbooks or inventory

# Package and service names
nginx_package_name: nginx
nginx_service_name: nginx

# User and group
nginx_user: www-data
nginx_group: www-data

# Directories
nginx_conf_dir: /etc/nginx
nginx_log_dir: /var/log/nginx
nginx_cache_dir: /var/cache/nginx
nginx_pid_file: /var/run/nginx.pid

# Main configuration
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_keepalive_timeout: 65
nginx_client_max_body_size: 10m

# Performance tuning
nginx_sendfile: on
nginx_tcp_nopush: on
nginx_tcp_nodelay: on
nginx_gzip: on
nginx_gzip_types:
  - text/plain
  - text/css
  - application/json
  - application/javascript
  - text/xml
  - application/xml

# Security
nginx_ssl_enabled: no
nginx_ssl_protocols: "TLSv1.2 TLSv1.3"
nginx_ssl_ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256"
nginx_ssl_prefer_server_ciphers: on
nginx_disable_default_site: yes
nginx_configure_firewall: yes
nginx_server_tokens: off

# Sites configuration
nginx_sites: []
# Example:
# nginx_sites:
#   - name: example.com
#     server_name: example.com www.example.com
#     root: /var/www/example.com
#     enabled: yes
#     ssl: yes

# Basic authentication
# nginx_basic_auth_users:
#   - username: admin
#     password: secretpassword
```

### vars/main.yml

```yaml
---
# Variables that should not be overridden
nginx_conf_path: "{{ nginx_conf_dir }}/nginx.conf"
nginx_error_log: "{{ nginx_log_dir }}/error.log"
nginx_access_log: "{{ nginx_log_dir }}/access.log"

# OS-specific overrides loaded via include_vars
```

### vars/Debian.yml

```yaml
---
nginx_user: www-data
nginx_group: www-data
nginx_conf_dir: /etc/nginx
nginx_service_name: nginx
```

### vars/RedHat.yml

```yaml
---
nginx_user: nginx
nginx_group: nginx
nginx_conf_dir: /etc/nginx
nginx_service_name: nginx
```

## Role Handlers

### handlers/main.yml

```yaml
---
# Handlers for webserver role
- name: Reload nginx
  service:
    name: "{{ nginx_service_name }}"
    state: reloaded
  listen: "reload nginx"

- name: Restart nginx
  service:
    name: "{{ nginx_service_name }}"
    state: restarted
  listen: "restart nginx"

- name: Validate nginx config
  command: nginx -t
  changed_when: false
  listen: "validate nginx"

- name: Reload firewall
  service:
    name: ufw
    state: reloaded
  when: ansible_os_family == "Debian"
  listen: "reload firewall"
```

## Role Templates

### templates/nginx.conf.j2

```jinja2
# {{ ansible_managed }}
user {{ nginx_user }};
worker_processes {{ nginx_worker_processes }};
pid {{ nginx_pid_file }};

events {
    worker_connections {{ nginx_worker_connections }};
    use epoll;
    multi_accept on;
}

http {
    ##
    # Basic Settings
    ##
    sendfile {{ nginx_sendfile | ternary('on', 'off') }};
    tcp_nopush {{ nginx_tcp_nopush | ternary('on', 'off') }};
    tcp_nodelay {{ nginx_tcp_nodelay | ternary('on', 'off') }};
    keepalive_timeout {{ nginx_keepalive_timeout }};
    types_hash_max_size 20

Related in General