Site logo
Tác giả
  • avatar Nguyễn Đức Xinh
    Name
    Nguyễn Đức Xinh
    Twitter
Ngày xuất bản
Ngày xuất bản

Ansible Roles: Hướng dẫn tạo và sử dụng Roles để tổ chức Automation Code

Giới Thiệu

Khi bạn viết nhiều playbook, bạn sẽ nhận ra rằng có nhiều đoạn code lặp đi lặp lại. Đây chính là lúc Roles phát huy tác dụng. Roles giúp bạn tổ chức code Ansible thành các thành phần có thể tái sử dụng, dễ bảo trì và chia sẻ.

Trong bài học này, chúng ta sẽ tìm hiểu:

  • Role là gì và tại sao cần sử dụng
  • Cấu trúc thư mục của một role
  • Cách tạo và sử dụng roles
  • Best practices khi làm việc với roles

Role Là Gì?

Role là một cách để nhóm các tasks, variables, files, templates và handlers liên quan vào một cấu trúc thư mục chuẩn. Thay vì viết tất cả trong một playbook dài, bạn chia nhỏ thành các roles độc lập.

Lợi Ích Của Roles

Tái sử dụng: Viết một lần, dùng nhiều playbook
Tổ chức tốt: Code được chia thành các phần logic rõ ràng
Dễ bảo trì: Mỗi role quản lý một chức năng cụ thể
Chia sẻ: Có thể share roles qua Ansible Galaxy
Testing: Dễ dàng test từng role riêng lẻ


Cấu Trúc Thư Mục Role

Một role tiêu chuẩn có cấu trúc như sau:

roles/
└── webserver/
    ├── tasks/
    │   └── main.yml          # Tasks chính của role
    ├── handlers/
    │   └── main.yml          # Handlers cho role
    ├── templates/
    │   └── nginx.conf.j2     # Jinja2 templates
    ├── files/
    │   └── index.html        # Static files
    ├── vars/
    │   └── main.yml          # Variables (priority cao)
    ├── defaults/
    │   └── main.yml          # Default variables (priority thấp)
    ├── meta/
    │   └── main.yml          # Role metadata và dependencies
    └── README.md             # Documentation

Giải Thích Từng Thư Mục

Thư mục Mục đích Bắt buộc?
tasks/ Chứa các tasks chính ✅ Có
handlers/ Chứa handlers ❌ Không
templates/ Chứa Jinja2 templates ❌ Không
files/ Chứa static files ❌ Không
vars/ Variables ưu tiên cao ❌ Không
defaults/ Default variables ❌ Không
meta/ Metadata và dependencies ❌ Không

Thực Hành: Tạo Role Đầu Tiên

Bước 1: Tạo Cấu Trúc Role

Sử dụng lệnh ansible-galaxy để tạo skeleton:

ansible-galaxy init webserver

Lệnh này sẽ tạo cấu trúc thư mục hoàn chỉnh.

Bước 2: Viết Tasks

Tạo file roles/webserver/tasks/main.yml:

---
# Tasks chính cho webserver role

- name: Cài đặt Nginx
  apt:
    name: nginx
    state: present
    update_cache: yes
  become: yes

- name: Copy file cấu hình Nginx
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
  become: yes
  notify: Restart nginx

- name: Copy trang index
  copy:
    src: index.html
    dest: /var/www/html/index.html
    owner: www-data
    group: www-data
    mode: '0644'
  become: yes

- name: Đảm bảo Nginx đang chạy
  service:
    name: nginx
    state: started
    enabled: yes
  become: yes

Bước 3: Tạo Handlers

Tạo file roles/webserver/handlers/main.yml:

---
- name: Restart nginx
  service:
    name: nginx
    state: restarted
  become: yes

Bước 4: Tạo Default Variables

Tạo file roles/webserver/defaults/main.yml:

---
nginx_port: 80
nginx_worker_processes: 2
nginx_worker_connections: 1024
server_name: localhost

Bước 5: Tạo Template

Tạo file roles/webserver/templates/nginx.conf.j2:

user www-data;
worker_processes {{ nginx_worker_processes }};

events {
    worker_connections {{ nginx_worker_connections }};
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    server {
        listen {{ nginx_port }};
        server_name {{ server_name }};

        location / {
            root /var/www/html;
            index index.html;
        }
    }
}

Bước 6: Thêm Static File

Tạo file roles/webserver/files/index.html:

<!DOCTYPE html>
<html>
<head>
    <title>Welcome</title>
</head>
<body>
    <h1>Nginx đã được cài đặt thành công!</h1>
    <p>Role: webserver</p>
</body>
</html>

Sử Dụng Role Trong Playbook

Sau khi tạo role, bạn sử dụng nó trong playbook:

Cách 1: Cú Pháp Đơn Giản

---
- name: Cài đặt web server
  hosts: webservers
  roles:
    - webserver

Cách 2: Override Variables

---
- name: Cài đặt web server với custom port
  hosts: webservers
  roles:
    - role: webserver
      vars:
        nginx_port: 8080
        server_name: example.com

Cách 3: Sử Dụng Tags

---
- name: Cài đặt web server
  hosts: webservers
  roles:
    - role: webserver
      tags: ['nginx', 'webserver']

Role Dependencies

Khi một role phụ thuộc vào role khác, bạn khai báo trong meta/main.yml:

---
# roles/webserver/meta/main.yml
dependencies:
  - role: common
    vars:
      some_variable: value
  - role: firewall

Ansible sẽ tự động chạy các role dependencies trước.


Thực Hành: Tạo Role Database

Hãy tạo thêm một role cho MySQL:

ansible-galaxy init database

File: roles/database/tasks/main.yml

---
- name: Cài đặt MySQL Server
  apt:
    name:
      - mysql-server
      - python3-pymysql
    state: present
    update_cache: yes
  become: yes

- name: Đảm bảo MySQL đang chạy
  service:
    name: mysql
    state: started
    enabled: yes
  become: yes

- name: Tạo database
  mysql_db:
    name: "{{ db_name }}"
    state: present
    login_unix_socket: /var/run/mysqld/mysqld.sock
  become: yes

File: roles/database/defaults/main.yml

---
db_name: myapp
db_user: appuser
db_password: changeme

Kết Hợp Nhiều Roles

Playbook có thể sử dụng nhiều roles:

---
- name: Setup LAMP stack
  hosts: appservers
  become: yes
  
  roles:
    - common           # Cài đặt các packages cơ bản
    - database         # Cài đặt MySQL
    - webserver        # Cài đặt Nginx
    - application      # Deploy application code

Best Practices

1. Đặt Tên Role Rõ Ràng

Không tốt: role1, my_role, stuff
Tốt: nginx, mysql-server, docker-engine

2. Sử Dụng Defaults Hợp Lý

Đặt giá trị mặc định an toàn trong defaults/main.yml:

# defaults/main.yml
nginx_port: 80
nginx_user: www-data
nginx_max_clients: 100

3. Document Role Của Bạn

Tạo README.md cho mỗi role:

# Webserver Role

## Mô tả
Role này cài đặt và cấu hình Nginx web server.

## Variables
- `nginx_port`: Port Nginx lắng nghe (default: 80)
- `server_name`: Server name (default: localhost)

## Dependencies
- common

## Ví dụ sử dụng
\```yaml
- role: webserver
  vars:
    nginx_port: 8080
\```

4. Tách Tasks Phức Tạp

Nếu tasks/main.yml quá dài, tách thành nhiều file:

# tasks/main.yml
---
- import_tasks: install.yml
- import_tasks: configure.yml
- import_tasks: security.yml

5. Sử Dụng Role Từ Ansible Galaxy

Không cần viết lại từ đầu, sử dụng roles có sẵn:

ansible-galaxy install geerlingguy.nginx

Sau đó sử dụng trong playbook:

roles:
  - geerlingguy.nginx

Kiểm Tra Role

Cú Pháp

ansible-playbook playbook.yml --syntax-check

Dry Run

ansible-playbook playbook.yml --check

List Tasks

ansible-playbook playbook.yml --list-tasks

Tổng Kết

Trong bài học này, bạn đã học:

  • Role là gì và tại sao nên sử dụng
  • Cấu trúc thư mục của một role
  • Cách tạo và sử dụng roles
  • Role dependencies
  • Best practices khi làm việc với roles

Bài Tập Thực Hành

  1. Tạo role firewall để cấu hình UFW:

    • Bật UFW
    • Cho phép SSH (port 22)
    • Cho phép HTTP (port 80)
    • Deny tất cả các kết nối khác
  2. Tạo role docker để cài đặt Docker:

    • Cài đặt Docker Engine
    • Thêm user vào docker group
    • Đảm bảo Docker service chạy
  3. Kết hợp các roles để triển khai một ứng dụng hoàn chỉnh


Resources