ansible-roles
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAnsible Roles
Ansible Roles
Structure and reuse automation code with Ansible roles for modular, maintainable infrastructure.
使用Ansible Roles构建并复用自动化代码,实现模块化、可维护的基础设施。
Role Directory Structure
Role目录结构
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一个组织良好的Ansible Role遵循标准化的目录结构:
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.ymlBasic Role Example
基础Role示例
tasks/main.yml
tasks/main.yml
yaml
---yaml
---Main task file for webserver role
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
undefined-
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
undefinedtasks/install.yml
tasks/install.yml
yaml
---yaml
---Installation tasks for webserver role
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"
undefined-
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"
undefinedtasks/configure.yml
tasks/configure.yml
yaml
---yaml
---Configuration tasks for webserver role
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'
undefined-
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'
undefinedtasks/security.yml
tasks/security.yml
yaml
---yaml
---Security tasks for webserver role
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
undefined-
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
undefinedRole Variables
Role变量
defaults/main.yml
defaults/main.yml
yaml
---yaml
---Default variables for webserver role
Default variables for webserver role
These can be overridden in playbooks or inventory
These can be overridden in playbooks or inventory
Package and service names
Package and service names
nginx_package_name: nginx
nginx_service_name: nginx
nginx_package_name: nginx
nginx_service_name: nginx
User and group
User and group
nginx_user: www-data
nginx_group: www-data
nginx_user: www-data
nginx_group: www-data
Directories
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
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
Main configuration
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_keepalive_timeout: 65
nginx_client_max_body_size: 10m
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_keepalive_timeout: 65
nginx_client_max_body_size: 10m
Performance tuning
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
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
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
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
Sites configuration
nginx_sites: []
nginx_sites: []
Example:
Example:
nginx_sites:
nginx_sites:
- name: example.com
- name: example.com
server_name: example.com www.example.com
server_name: example.com www.example.com
root: /var/www/example.com
root: /var/www/example.com
enabled: yes
enabled: yes
ssl: yes
ssl: yes
Basic authentication
Basic authentication
nginx_basic_auth_users:
nginx_basic_auth_users:
- username: admin
- username: admin
password: secretpassword
password: secretpassword
undefinedundefinedvars/main.yml
vars/main.yml
yaml
---yaml
---Variables that should not be overridden
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"
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
OS-specific overrides loaded via include_vars
undefinedundefinedvars/Debian.yml
vars/Debian.yml
yaml
---
nginx_user: www-data
nginx_group: www-data
nginx_conf_dir: /etc/nginx
nginx_service_name: nginxyaml
---
nginx_user: www-data
nginx_group: www-data
nginx_conf_dir: /etc/nginx
nginx_service_name: nginxvars/RedHat.yml
vars/RedHat.yml
yaml
---
nginx_user: nginx
nginx_group: nginx
nginx_conf_dir: /etc/nginx
nginx_service_name: nginxyaml
---
nginx_user: nginx
nginx_group: nginx
nginx_conf_dir: /etc/nginx
nginx_service_name: nginxRole Handlers
Role处理器
handlers/main.yml
handlers/main.yml
yaml
---yaml
---Handlers for webserver role
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"
undefined-
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"
undefinedRole Templates
Role模板
templates/nginx.conf.j2
templates/nginx.conf.j2
jinja2
undefinedjinja2
undefined{{ ansible_managed }}
{{ 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 2048;
server_tokens {{ nginx_server_tokens | ternary('on', 'off') }};
client_max_body_size {{ nginx_client_max_body_size }};
include {{ nginx_conf_dir }}/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##{% if nginx_ssl_enabled %}
ssl_protocols {{ nginx_ssl_protocols }};
ssl_ciphers {{ nginx_ssl_ciphers }};
ssl_prefer_server_ciphers {{ nginx_ssl_prefer_server_ciphers | ternary('on', 'off') }};
ssl_dhparam {{ nginx_conf_dir }}/dhparam.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
{% endif %}
##
# Logging Settings
##
access_log {{ nginx_access_log }};
error_log {{ nginx_error_log }};
##
# Gzip Settings
##
gzip {{ nginx_gzip | ternary('on', 'off') }};{% if nginx_gzip %}
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types {{ nginx_gzip_types | join(' ') }};
{% endif %}
##
# Virtual Host Configs
##
include {{ nginx_conf_dir }}/sites-enabled/*;}
undefineduser {{ 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 2048;
server_tokens {{ nginx_server_tokens | ternary('on', 'off') }};
client_max_body_size {{ nginx_client_max_body_size }};
include {{ nginx_conf_dir }}/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##{% if nginx_ssl_enabled %}
ssl_protocols {{ nginx_ssl_protocols }};
ssl_ciphers {{ nginx_ssl_ciphers }};
ssl_prefer_server_ciphers {{ nginx_ssl_prefer_server_ciphers | ternary('on', 'off') }};
ssl_dhparam {{ nginx_conf_dir }}/dhparam.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
{% endif %}
##
# Logging Settings
##
access_log {{ nginx_access_log }};
error_log {{ nginx_error_log }};
##
# Gzip Settings
##
gzip {{ nginx_gzip | ternary('on', 'off') }};{% if nginx_gzip %}
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types {{ nginx_gzip_types | join(' ') }};
{% endif %}
##
# Virtual Host Configs
##
include {{ nginx_conf_dir }}/sites-enabled/*;}
undefinedtemplates/site.conf.j2
templates/site.conf.j2
jinja2
undefinedjinja2
undefined{{ ansible_managed }}
{{ ansible_managed }}
Site: {{ item.name }}
Site: {{ item.name }}
{% if item.ssl | default(false) %}
{% if item.ssl | default(false) %}
Redirect HTTP to HTTPS
Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name {{ item.server_name }};
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ item.server_name }};
ssl_certificate {{ item.ssl_cert | default('/etc/letsencrypt/live/' + item.name + '/fullchain.pem') }};
ssl_certificate_key {{ item.ssl_key | default('/etc/letsencrypt/live/' + item.name + '/privkey.pem') }};{% else %}
server {
listen 80;
listen [::]:80;
server_name {{ item.server_name }};
{% endif %}
root {{ item.root | default('/var/www/' + item.name) }};
index {{ item.index | default('index.html index.htm') }};{% if item.access_log is defined %}
access_log {{ item.access_log }};
{% endif %}
{% if item.error_log is defined %}
error_log {{ item.error_log }};
{% endif %}
{% if item.basic_auth | default(false) %}
auth_basic "Restricted Access";
auth_basic_user_file {{ nginx_conf_dir }}/.htpasswd;
{% endif %}
location / {{% if item.proxy_pass is defined %}
proxy_pass {{ item.proxy_pass }};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
{% else %}
try_files $uri $uri/ =404;
{% endif %}
}
{% if item.locations is defined %}
{% for location in item.locations %}
location {{ location.path }} {
{% if location.proxy_pass is defined %}
proxy_pass {{ location.proxy_pass }};
{% endif %}
{% if location.alias is defined %}
alias {{ location.alias }};
{% endif %}
{% if location.return is defined %}
return {{ location.return }};
{% endif %}
}
{% endfor %}
{% endif %}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;}
undefinedserver {
listen 80;
listen [::]:80;
server_name {{ item.server_name }};
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ item.server_name }};
ssl_certificate {{ item.ssl_cert | default('/etc/letsencrypt/live/' + item.name + '/fullchain.pem') }};
ssl_certificate_key {{ item.ssl_key | default('/etc/letsencrypt/live/' + item.name + '/privkey.pem') }};{% else %}
server {
listen 80;
listen [::]:80;
server_name {{ item.server_name }};
{% endif %}
root {{ item.root | default('/var/www/' + item.name) }};
index {{ item.index | default('index.html index.htm') }};{% if item.access_log is defined %}
access_log {{ item.access_log }};
{% endif %}
{% if item.error_log is defined %}
error_log {{ item.error_log }};
{% endif %}
{% if item.basic_auth | default(false) %}
auth_basic "Restricted Access";
auth_basic_user_file {{ nginx_conf_dir }}/.htpasswd;
{% endif %}
location / {{% if item.proxy_pass is defined %}
proxy_pass {{ item.proxy_pass }};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
{% else %}
try_files $uri $uri/ =404;
{% endif %}
}
{% if item.locations is defined %}
{% for location in item.locations %}
location {{ location.path }} {
{% if location.proxy_pass is defined %}
proxy_pass {{ location.proxy_pass }};
{% endif %}
{% if location.alias is defined %}
alias {{ location.alias }};
{% endif %}
{% if location.return is defined %}
return {{ location.return }};
{% endif %}
}
{% endfor %}
{% endif %}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;}
undefinedRole Dependencies
Role依赖
meta/main.yml
meta/main.yml
yaml
---
galaxy_info:
role_name: webserver
author: Your Organization
description: Install and configure nginx web server
company: Your Company
license: MIT
min_ansible_version: 2.9
platforms:
- name: Ubuntu
versions:
- focal
- jammy
- name: Debian
versions:
- buster
- bullseye
- name: EL
versions:
- 7
- 8
- 9
galaxy_tags:
- web
- nginx
- webserver
- http
dependencies:
- role: common
vars:
common_packages:
- curl
- wget
- role: firewall
when: nginx_configure_firewall
allow_duplicates: noyaml
---
galaxy_info:
role_name: webserver
author: Your Organization
description: Install and configure nginx web server
company: Your Company
license: MIT
min_ansible_version: 2.9
platforms:
- name: Ubuntu
versions:
- focal
- jammy
- name: Debian
versions:
- buster
- bullseye
- name: EL
versions:
- 7
- 8
- 9
galaxy_tags:
- web
- nginx
- webserver
- http
dependencies:
- role: common
vars:
common_packages:
- curl
- wget
- role: firewall
when: nginx_configure_firewall
allow_duplicates: noUsing Roles in Playbooks
在Playbook中使用Role
Simple Role Usage
简单Role使用
yaml
---
- name: Configure web servers
hosts: webservers
become: yes
roles:
- webserveryaml
---
- name: Configure web servers
hosts: webservers
become: yes
roles:
- webserverRole with Variables
带变量的Role使用
yaml
---
- name: Configure web servers with custom settings
hosts: webservers
become: yes
roles:
- role: webserver
vars:
nginx_worker_processes: 4
nginx_ssl_enabled: yes
nginx_sites:
- name: example.com
server_name: example.com www.example.com
root: /var/www/example.com
ssl: yes
ssl_cert: /etc/ssl/certs/example.com.crt
ssl_key: /etc/ssl/private/example.com.keyyaml
---
- name: Configure web servers with custom settings
hosts: webservers
become: yes
roles:
- role: webserver
vars:
nginx_worker_processes: 4
nginx_ssl_enabled: yes
nginx_sites:
- name: example.com
server_name: example.com www.example.com
root: /var/www/example.com
ssl: yes
ssl_cert: /etc/ssl/certs/example.com.crt
ssl_key: /etc/ssl/private/example.com.keyRole with Tags
带标签的Role使用
yaml
---
- name: Configure infrastructure
hosts: all
become: yes
roles:
- role: webserver
tags:
- web
- nginx
- role: database
tags:
- db
- postgresyaml
---
- name: Configure infrastructure
hosts: all
become: yes
roles:
- role: webserver
tags:
- web
- nginx
- role: database
tags:
- db
- postgresPre and Post Tasks
前置与后置任务
yaml
---
- name: Deploy web application
hosts: webservers
become: yes
pre_tasks:
- name: Announce deployment
debug:
msg: "Starting deployment to {{ inventory_hostname }}"
- name: Check disk space
command: df -h /
register: disk_space
changed_when: false
roles:
- webserver
- monitoring
post_tasks:
- name: Verify nginx is responding
uri:
url: http://localhost
status_code: 200
retries: 3
delay: 5
- name: Notify completion
debug:
msg: "Deployment completed successfully"yaml
---
- name: Deploy web application
hosts: webservers
become: yes
pre_tasks:
- name: Announce deployment
debug:
msg: "Starting deployment to {{ inventory_hostname }}"
- name: Check disk space
command: df -h /
register: disk_space
changed_when: false
roles:
- webserver
- monitoring
post_tasks:
- name: Verify nginx is responding
uri:
url: http://localhost
status_code: 200
retries: 3
delay: 5
- name: Notify completion
debug:
msg: "Deployment completed successfully"Role Inclusion Methods
Role包含方式
Static Import
静态导入
yaml
---
- name: Configure servers
hosts: all
tasks:
- name: Import webserver role
import_role:
name: webserver
vars:
nginx_worker_processes: 2
tags:
- webserveryaml
---
- name: Configure servers
hosts: all
tasks:
- name: Import webserver role
import_role:
name: webserver
vars:
nginx_worker_processes: 2
tags:
- webserverDynamic Include
动态包含
yaml
---
- name: Configure servers based on conditions
hosts: all
tasks:
- name: Include webserver role for web servers
include_role:
name: webserver
when: "'webservers' in group_names"
- name: Include database role for db servers
include_role:
name: database
when: "'databases' in group_names"yaml
---
- name: Configure servers based on conditions
hosts: all
tasks:
- name: Include webserver role for web servers
include_role:
name: webserver
when: "'webservers' in group_names"
- name: Include database role for db servers
include_role:
name: database
when: "'databases' in group_names"Import with Task Files
与任务文件一起导入
yaml
---
- name: Custom installation workflow
hosts: webservers
tasks:
- name: Run pre-installation checks
import_role:
name: webserver
tasks_from: preflight
- name: Install nginx
import_role:
name: webserver
tasks_from: install
- name: Configure nginx
import_role:
name: webserver
tasks_from: configureyaml
---
- name: Custom installation workflow
hosts: webservers
tasks:
- name: Run pre-installation checks
import_role:
name: webserver
tasks_from: preflight
- name: Install nginx
import_role:
name: webserver
tasks_from: install
- name: Configure nginx
import_role:
name: webserver
tasks_from: configureCreating Roles with Ansible Galaxy
使用Ansible Galaxy创建Role
Initialize a New Role
初始化新Role
bash
undefinedbash
undefinedCreate role structure
Create role structure
ansible-galaxy init roles/myapp
ansible-galaxy init roles/myapp
Create role with custom template
Create role with custom template
ansible-galaxy init --init-path roles/ myapp
ansible-galaxy init --init-path roles/ myapp
List role files
List role files
tree roles/myapp
undefinedtree roles/myapp
undefinedInstall Roles from Galaxy
从Galaxy安装Role
bash
undefinedbash
undefinedInstall a role
Install a role
ansible-galaxy install geerlingguy.nginx
ansible-galaxy install geerlingguy.nginx
Install specific version
Install specific version
ansible-galaxy install geerlingguy.nginx,2.8.0
ansible-galaxy install geerlingguy.nginx,2.8.0
Install from requirements file
Install from requirements file
ansible-galaxy install -r requirements.yml
undefinedansible-galaxy install -r requirements.yml
undefinedrequirements.yml
requirements.yml
yaml
---yaml
---Install from Ansible Galaxy
Install from Ansible Galaxy
-
name: geerlingguy.nginx version: 2.8.0
-
name: geerlingguy.postgresql version: 3.4.0
-
name: geerlingguy.nginx version: 2.8.0
-
name: geerlingguy.postgresql version: 3.4.0
Install from Git repository
Install from Git repository
- name: custom-app src: https://github.com/yourorg/ansible-role-custom-app.git scm: git version: main
- name: custom-app src: https://github.com/yourorg/ansible-role-custom-app.git scm: git version: main
Install from local path
Install from local path
- name: internal-role src: /path/to/roles/internal-role
undefined- name: internal-role src: /path/to/roles/internal-role
undefinedAdvanced Role Patterns
高级Role模式
Role with Multiple Entry Points
多入口点Role
yaml
undefinedyaml
undefinedroles/webserver/tasks/main.yml
roles/webserver/tasks/main.yml
- name: Default task flow import_tasks: "{{ webserver_task_flow | default('standard') }}.yml"
```yaml- name: Default task flow import_tasks: "{{ webserver_task_flow | default('standard') }}.yml"
```yamlroles/webserver/tasks/standard.yml
roles/webserver/tasks/standard.yml
- import_tasks: install.yml
- import_tasks: configure.yml
- import_tasks: security.yml
```yaml- import_tasks: install.yml
- import_tasks: configure.yml
- import_tasks: security.yml
```yamlroles/webserver/tasks/minimal.yml
roles/webserver/tasks/minimal.yml
- import_tasks: install.yml
- import_tasks: configure.yml
undefined- import_tasks: install.yml
- import_tasks: configure.yml
undefinedConditional Role Execution
条件化Role执行
yaml
---
- name: Configure servers with conditional roles
hosts: all
become: yes
roles:
- role: webserver
when:
- ansible_os_family == "Debian"
- inventory_hostname in groups['webservers']
- role: webserver-nginx
when: webserver_type == "nginx"
- role: webserver-apache
when: webserver_type == "apache"yaml
---
- name: Configure servers with conditional roles
hosts: all
become: yes
roles:
- role: webserver
when:
- ansible_os_family == "Debian"
- inventory_hostname in groups['webservers']
- role: webserver-nginx
when: webserver_type == "nginx"
- role: webserver-apache
when: webserver_type == "apache"Nested Role Dependencies
嵌套Role依赖
yaml
undefinedyaml
undefinedroles/application/meta/main.yml
roles/application/meta/main.yml
dependencies:
-
role: webserver vars: nginx_sites: - name: "{{ app_name }}" server_name: "{{ app_domain }}" proxy_pass: "http://localhost:{{ app_port }}"
-
role: database vars: db_name: "{{ app_db_name }}" db_user: "{{ app_db_user }}"
-
role: monitoring vars: monitor_services: - nginx - "{{ app_name }}"
undefineddependencies:
-
role: webserver vars: nginx_sites: - name: "{{ app_name }}" server_name: "{{ app_domain }}" proxy_pass: "http://localhost:{{ app_port }}"
-
role: database vars: db_name: "{{ app_db_name }}" db_user: "{{ app_db_user }}"
-
role: monitoring vars: monitor_services: - nginx - "{{ app_name }}"
undefinedWhen to Use This Skill
何时使用该技能
Use the ansible-roles skill when you need to:
- Structure reusable automation code across multiple playbooks and projects
- Implement modular infrastructure as code with clear separation of concerns
- Share automation logic between teams or projects
- Create distributable automation packages for common infrastructure patterns
- Organize complex playbooks into manageable, testable components
- Implement role-based configuration management with variable precedence
- Build layered infrastructure with role dependencies
- Version control automation logic independently from playbooks
- Create standardized infrastructure components for consistency
- Implement security and compliance requirements through reusable roles
- Build internal automation libraries for your organization
- Contribute to or consume community automation from Ansible Galaxy
- Test infrastructure components in isolation before integration
- Implement different configurations for development, staging, and production
- Create self-documenting infrastructure through role metadata
当你需要以下场景时,使用ansible-roles技能:
- 在多个Playbook和项目中构建可复用的自动化代码
- 实现关注点分离的模块化基础设施即代码
- 在团队或项目间共享自动化逻辑
- 为常见基础设施模式创建可分发的自动化包
- 将复杂的Playbook组织为可管理、可测试的组件
- 实现基于Role的配置管理,支持变量优先级
- 通过Role依赖构建分层基础设施
- 独立于Playbook对自动化逻辑进行版本控制
- 创建标准化基础设施组件以确保一致性
- 通过可复用的Role实现安全与合规要求
- 为你的组织构建内部自动化库
- 贡献或使用Ansible Galaxy中的社区自动化内容
- 在集成前独立测试基础设施组件
- 为开发、 staging和生产环境实现不同配置
- 通过Role元数据创建自文档化的基础设施
Best Practices
最佳实践
- Follow standard directory structure - Use ansible-galaxy init to create roles with proper organization
- Use defaults wisely - Place overridable variables in defaults/main.yml, non-overridable in vars/main.yml
- Document thoroughly - Include comprehensive README.md with usage examples and variable documentation
- Keep roles focused - Each role should have a single, well-defined purpose
- Use role dependencies - Declare dependencies in meta/main.yml rather than in playbooks
- Tag appropriately - Apply meaningful tags to tasks for selective execution
- Implement idempotency - Ensure roles can be run multiple times safely
- Version your roles - Use semantic versioning for role releases
- Test roles independently - Include test playbooks in tests/ directory
- Use templates for configuration - Prefer Jinja2 templates over static files for flexibility
- Implement OS detection - Use ansible_os_family for cross-platform compatibility
- Secure sensitive data - Use ansible-vault for passwords and secrets in role variables
- Use handlers correctly - Only notify handlers when configuration changes
- Validate configurations - Use validate parameter in template/copy modules
- Name tasks clearly - Use descriptive names that explain what each task does
- 遵循标准目录结构 - 使用ansible-galaxy init创建具有合理组织的Role
- 明智使用默认变量 - 将可覆盖的变量放在defaults/main.yml中,不可覆盖的放在vars/main.yml中
- 全面文档化 - 包含详细的README.md,提供使用示例和变量说明
- 保持Role聚焦 - 每个Role应具有单一、明确的用途
- 使用Role依赖 - 在meta/main.yml中声明依赖,而非在Playbook中
- 合理添加标签 - 为任务应用有意义的标签以支持选择性执行
- 实现幂等性 - 确保Role可以安全地多次运行
- 为Role版本化 - 对Role发布使用语义化版本控制
- 独立测试Role - 在tests/目录中包含测试Playbook
- 使用模板进行配置 - 优先使用Jinja2模板而非静态文件以提升灵活性
- 实现操作系统检测 - 使用ansible_os_family实现跨平台兼容性
- 保护敏感数据 - 使用ansible-vault处理Role变量中的密码和机密信息
- 正确使用处理器 - 仅在配置变更时通知处理器
- 验证配置 - 在template/copy模块中使用validate参数
- 清晰命名任务 - 使用描述性名称说明每个任务的作用
Common Pitfalls
常见陷阱
- Overly complex roles - Trying to make one role do too many things
- Poor variable naming - Using generic names that conflict with other roles
- Missing role prefix - Not prefixing role variables with role name
- Ignoring variable precedence - Not understanding how Ansible resolves variable conflicts
- Hard-coded values - Embedding environment-specific values instead of using variables
- Missing dependencies - Not declaring role dependencies in meta/main.yml
- No validation - Deploying configurations without validation checks
- Skipping tests - Not including test playbooks or scenarios
- Poor handler design - Restarting services unnecessarily or not at all
- Missing OS support - Assuming all target systems are the same
- No backup strategy - Not backing up configurations before changes
- Ignoring idempotency - Using command/shell modules without proper guards
- Missing tags - Not tagging tasks for selective execution
- Poor template practices - Complex logic in templates instead of variables
- No version control - Not versioning roles or tracking changes
- 过于复杂的Role - 试图让一个Role处理过多事务
- 变量命名不佳 - 使用通用名称导致与其他Role冲突
- 缺少Role前缀 - 不为Role变量添加Role名称前缀
- 忽略变量优先级 - 不了解Ansible如何解决变量冲突
- 硬编码值 - 嵌入环境特定值而非使用变量
- 缺少依赖声明 - 未在meta/main.yml中声明Role依赖
- 未做验证 - 部署配置前未进行验证检查
- 跳过测试 - 未包含测试Playbook或场景
- 处理器设计不佳 - 不必要地重启服务或完全不重启
- 缺少操作系统支持 - 假设所有目标系统都相同
- 无备份策略 - 变更前未备份配置
- 忽略幂等性 - 未添加适当防护就使用command/shell模块
- 缺少标签 - 不为任务添加标签以支持选择性执行
- 模板实践不佳 - 在模板中使用复杂逻辑而非变量
- 未进行版本控制 - 未对Role进行版本控制或跟踪变更