Quản lý tập tin cấu hình là một phần cốt lõi của tự động hóa cơ sở hạ tầng. Ansible cung cấp các công cụ mạnh mẽ cho cả việc triển khai tệp tĩnh và tạo cấu hình động. Bạn sẽ học cách sử dụng các mẫu thích ứng với các môi trường khác nhau, quản lý quyền và quyền sở hữu tệp cũng như sắp xếp các tệp cấu hình để có thể bảo trì.
Hiểu quản lý tệp trong Ansible
Ansible cung cấp một số mô-đun cho hoạt động của tệp, mỗi mô-đun phù hợp với các tình huống khác nhau:
- copy: Triển khai các tệp tĩnh không thay đổi
- template: Tạo tệp từ các mẫu Jinja2 với sự thay thế có thể thay đổi
- file: Quản lý thuộc tính tệp, thư mục và liên kết
- lineinfile: Sửa đổi từng dòng trong tệp hiện có
- blockinfile: Quản lý khối văn bản trong tệp
Làm việc với các tệp tĩnh
Triển khai tệp cơ bản
Mô-đun copy xử lý việc triển khai tệp đơn giản:
---
- name: Deploy static configuration files
hosts: webservers
become: yes
tasks:
- name: Copy SSL certificate
copy:
src: files/ssl/server.crt
dest: /etc/ssl/certs/server.crt
owner: root
group: root
mode: '0644'
backup: yes
- name: Copy SSL private key
copy:
src: files/ssl/server.key
dest: /etc/ssl/private/server.key
owner: root
group: ssl-cert
mode: '0640'
backup: yes
notify: restart nginx
- name: Deploy application scripts
copy:
src: files/scripts/
dest: /opt/myapp/scripts/
owner: myapp
group: myapp
mode: '0755'
directory_mode: '0755'
Các tính năng chính của mô-đun sao chép:
backup: yestạo bản sao lưu trước khi ghi đèdirectory_modeđặt quyền cho thư mục khi sao chép toàn bộ thư mục- Đường dẫn
srckết thúc bằng/sao chép nội dung thư mục chứ không phải chính thư mục đó
Quản lý nội dung tập tin
Tạo tệp có nội dung cụ thể trực tiếp trong playbook của bạn:
tasks:
- name: Create maintenance page
copy:
content: |
<!DOCTYPE html>
<html>
<head>
<title>Maintenance Mode</title>
</head>
<body>
<h1>Site Under Maintenance</h1>
<p>We'll be back shortly. Estimated downtime: {{ maintenance_duration | default('30 minutes') }}</p>
</body>
</html>
dest: /var/www/html/maintenance.html
owner: www-data
group: www-data
mode: '0644'
Tạo mẫu động
Các mẫu sử dụng công cụ tạo khuôn mẫu Jinja2 để tạo các tệp cấu hình với các thay thế, điều kiện và vòng lặp có thể thay đổi.
Cấu trúc mẫu cơ bản
Tạo tệp mẫu templates/nginx.conf.j2:
# nginx configuration generated by Ansible
# Last updated: {{ ansible_date_time.iso8601 }}
user {{ nginx_user | default('www-data') }};
worker_processes {{ nginx_worker_processes | default(ansible_processor_vcpus) }};
pid /run/nginx.pid;
events {
worker_connections {{ nginx_worker_connections | default(1024) }};
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log {{ nginx_access_log | default('/var/log/nginx/access.log') }} main;
error_log {{ nginx_error_log | default('/var/log/nginx/error.log') }} warn;
# Performance settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout {{ nginx_keepalive_timeout | default(65) }};
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length {{ nginx_gzip_min_length | default(1024) }};
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/xml+rss
application/json;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Triển khai mẫu:
tasks:
- name: Generate nginx main configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
backup: yes
notify: restart nginx
Mẫu có điều kiện
Sử dụng các điều kiện Jinja2 để điều chỉnh cấu hình dựa trên các biến:
# SSL configuration - templates/site.conf.j2
server {
{% if ssl_enabled | default(false) %}
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate {{ ssl_cert_path | default('/etc/ssl/certs/server.crt') }};
ssl_certificate_key {{ ssl_key_path | default('/etc/ssl/private/server.key') }};
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
{% else %}
listen 80;
listen [::]:80;
{% endif %}
server_name {{ server_name | default(ansible_fqdn) }};
root {{ document_root | default('/var/www/html') }};
index index.html index.php;
{% if environment == 'development' %}
# Development-specific settings
error_log /var/log/nginx/{{ server_name }}-error.log debug;
access_log /var/log/nginx/{{ server_name }}-access.log combined;
{% else %}
# Production settings
error_log /var/log/nginx/{{ server_name }}-error.log warn;
access_log /var/log/nginx/{{ server_name }}-access.log main;
{% endif %}
location / {
try_files $uri $uri/ =404;
}
{% if php_enabled | default(false) %}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php{{ php_version | default('7.4') }}-fpm.sock;
}
{% endif %}
}
{% if ssl_enabled | default(false) %}
# HTTP to HTTPS redirect
server {
listen 80;
listen [::]:80;
server_name {{ server_name | default(ansible_fqdn) }};
return 301 https://$server_name$request_uri;
}
{% endif %}
Mẫu có vòng lặp
Tạo cấu hình lặp đi lặp lại bằng cách sử dụng các vòng lặp:
# Load balancer configuration - templates/upstream.conf.j2
{% for service in load_balanced_services %}
upstream {{ service.name }}_backend {
least_conn;
{% for server in service.servers %}
server {{ server.host }}:{{ server.port }} weight={{ server.weight | default(1) }}{% if server.backup | default(false) %} backup{% endif %};
{% endfor %}
# Health check
keepalive {{ service.keepalive | default(32) }};
}
server {
listen {{ service.port | default(80) }};
server_name {{ service.domain }};
location / {
proxy_pass http://{{ service.name }}_backend;
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;
# Timeouts
proxy_connect_timeout {{ service.connect_timeout | default('5s') }};
proxy_send_timeout {{ service.send_timeout | default('60s') }};
proxy_read_timeout {{ service.read_timeout | default('60s') }};
}
}
{% endfor %}
Sử dụng nó với các biến tương ứng:
vars:
load_balanced_services:
- name: api
domain: api.example.com
port: 80
servers:
- host: 192.168.1.10
port: 8080
weight: 2
- host: 192.168.1.11
port: 8080
weight: 1
- host: 192.168.1.12
port: 8080
backup: true
keepalive: 64
- name: admin
domain: admin.example.com
port: 80
servers:
- host: 192.168.1.15
port: 9000
Kỹ thuật mẫu nâng cao
Sử dụng Bộ lọc trong Mẫu
Bộ lọc Jinja2 chuyển đổi dữ liệu trong các mẫu:
# Database configuration - templates/database.conf.j2
[database]
host = {{ db_host | default('localhost') }}
port = {{ db_port | default(5432) }}
name = {{ db_name | upper }}
user = {{ db_user | lower }}
# Convert memory setting to MB
shared_buffers = {{ (total_memory_mb * 0.25) | int }}MB
effective_cache_size = {{ (total_memory_mb * 0.75) | int }}MB
# Generate secure random password if not provided
{% if db_password is not defined %}
password = {{ ansible_date_time.epoch | hash('sha256') | truncate(16, true, '') }}
{% else %}
password = {{ db_password }}
{% endif %}
# Conditional features based on environment
{% set features = environment_features | default([]) %}
enable_logging = {{ 'logging' in features | lower }}
enable_replication = {{ 'replication' in features | lower }}
enable_ssl = {{ 'ssl' in features | lower }}
# Generate comma-separated list of allowed hosts
allowed_hosts = {{ allowed_host_list | join(', ') }}
# Format timestamp
last_updated = {{ ansible_date_time.iso8601 | strftime('%Y-%m-%d %H:%M:%S') }}
Mẫu bao gồm
Chia các mẫu lớn thành các phần có thể quản lý được:
# Main template - templates/nginx-site.conf.j2
server {
{% include 'nginx/listen.j2' %}
{% include 'nginx/server-name.j2' %}
{% include 'nginx/ssl.j2' %}
{% include 'nginx/locations.j2' %}
}
Tạo một phần mẫu:
# templates/nginx/listen.j2
{% if ssl_enabled %}
listen 443 ssl http2;
listen [::]:443 ssl http2;
{% else %}
listen 80;
listen [::]:80;
{% endif %}
# templates/nginx/ssl.j2
{% if ssl_enabled %}
ssl_certificate {{ ssl_certificate }};
ssl_certificate_key {{ ssl_certificate_key }};
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
{% endif %}
Gỡ lỗi mẫu
Thêm thông tin gỡ lỗi vào mẫu trong quá trình phát triển:
{% if debug_mode | default(false) %}
<!-- Debug Information -->
<!-- Generated on: {{ ansible_date_time.iso8601 }} -->
<!-- Target host: {{ inventory_hostname }} -->
<!-- Environment: {{ environment | default('unknown') }} -->
<!-- Variables:
- ssl_enabled: {{ ssl_enabled | default('not set') }}
- server_name: {{ server_name | default('not set') }}
- document_root: {{ document_root | default('not set') }}
-->
{% endif %}
Kỹ thuật sửa đổi tập tin
Sửa đổi từng dòng
Sử dụng lineinfile để thay đổi cấu hình chính xác:
tasks:
- name: Configure SSH settings
lineinfile:
path: /etc/ssh/sshd_config
regexp: '{{ item.regexp }}'
line: '{{ item.line }}'
backup: yes
loop:
- { regexp: '^#?PermitRootLogin', line: 'PermitRootLogin no' }
- { regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication no' }
- { regexp: '^#?Port', line: 'Port {{ ssh_port | default(22) }}' }
notify: restart sshd
- name: Add custom SSH configuration
lineinfile:
path: /etc/ssh/sshd_config
line: '{{ item }}'
insertafter: EOF
loop:
- '# Custom configuration'
- 'ClientAliveInterval 300'
- 'ClientAliveCountMax 2'
notify: restart sshd
Khối sửa đổi
Sử dụng blockinfile để quản lý các phần cấu hình:
tasks:
- name: Configure application settings block
blockinfile:
path: /etc/myapp/config.ini
block: |
# Application settings managed by Ansible
[performance]
max_workers = {{ max_workers | default(ansible_processor_vcpus) }}
memory_limit = {{ memory_limit | default('512M') }}
cache_enabled = {{ cache_enabled | default(true) | lower }}
[database]
host = {{ db_host }}
port = {{ db_port | default(5432) }}
pool_size = {{ db_pool_size | default(10) }}
[logging]
level = {{ log_level | default('INFO') }}
file = {{ log_file | default('/var/log/myapp/app.log') }}
marker: '# {mark} ANSIBLE MANAGED BLOCK - APPLICATION CONFIG'
backup: yes
notify: restart application
Sắp xếp mẫu và tập tin
Cấu trúc thư mục
Sắp xếp các mẫu và tệp của bạn một cách hợp lý:
ansible-project/
├── templates/
│ ├── nginx/
│ │ ├── nginx.conf.j2
│ │ ├── site.conf.j2
│ │ └── upstream.conf.j2
│ ├── database/
│ │ ├── postgresql.conf.j2
│ │ └── pg_hba.conf.j2
│ └── application/
│ ├── app.conf.j2
│ └── systemd.service.j2
├── files/
│ ├── ssl/
│ │ ├── server.crt
│ │ └── server.key
│ ├── scripts/
│ │ ├── backup.sh
│ │ └── maintenance.sh
│ └── static/
│ └── maintenance.html
Tổ chức biến mẫu
Tạo các tệp biến tương ứng với mẫu của bạn:
# group_vars/webservers.yml
nginx_config:
user: www-data
worker_processes: '{{ ansible_processor_vcpus }}'
worker_connections: 1024
keepalive_timeout: 65
gzip_enabled: true
ssl_enabled: true
site_config:
server_name: www.example.com
document_root: /var/www/html
php_enabled: true
php_version: '8.1'
Ví dụ hoàn chỉnh: Cấu hình đa dịch vụ
Dưới đây là ví dụ toàn diện minh họa các mẫu, tệp và handler hoạt động cùng nhau:
---
- name: Configure web application stack
hosts: webservers
become: yes
vars:
app_name: ecommerce
app_version: '2.1.0'
ssl_enabled: true
php_enabled: true
cache_enabled: true
tasks:
- name: Create application directories
file:
path: '{{ item }}'
state: directory
owner: www-data
group: www-data
mode: '0755'
loop:
- /var/www/{{ app_name }}
- /var/www/{{ app_name }}/logs
- /var/www/{{ app_name }}/cache
- name: Deploy SSL certificates
copy:
src: 'files/ssl/{{ item }}'
dest: '/etc/ssl/{{ item }}'
owner: root
group: ssl-cert
mode: "{{ '0640' if 'key' in item else '0644' }}"
loop:
- certs/{{ app_name }}.crt
- private/{{ app_name }}.key
notify: restart nginx
- name: Generate nginx main configuration
template:
src: nginx/nginx.conf.j2
dest: /etc/nginx/nginx.conf
backup: yes
notify: restart nginx
- name: Generate site configuration
template:
src: nginx/site.conf.j2
dest: '/etc/nginx/sites-available/{{ app_name }}'
backup: yes
notify: restart nginx
- name: Enable site
file:
src: '/etc/nginx/sites-available/{{ app_name }}'
dest: '/etc/nginx/sites-enabled/{{ app_name }}'
state: link
notify: restart nginx
- name: Configure PHP-FPM pool
template:
src: php/pool.conf.j2
dest: '/etc/php/{{ php_version }}/fpm/pool.d/{{ app_name }}.conf'
backup: yes
notify: restart php-fpm
when: php_enabled
- name: Generate application configuration
template:
src: application/config.php.j2
dest: '/var/www/{{ app_name }}/config.php'
owner: www-data
group: www-data
mode: '0640'
- name: Deploy maintenance scripts
copy:
src: files/scripts/
dest: /opt/{{ app_name }}/scripts/
owner: root
group: root
mode: '0755'
directory_mode: '0755'
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
- name: restart php-fpm
service:
name: 'php{{ php_version }}-fpm'
state: restarted
Các bước tiếp theo
Quản lý mẫu và tệp là xương sống của tự động hóa cấu hình. Bạn đã học cách tạo các tệp cấu hình động, triển khai các tài nguyên tĩnh và sắp xếp quá trình tự động hóa của mình để có thể bảo trì.
Trong phần tiếp theo, chúng ta sẽ khám phá các vai trò - Cách tổ chức tự động hóa của Ansible thành các thành phần có thể chia sẻ, tái sử dụng, có thể kết hợp để tạo ra tự động hóa cơ sở hạ tầng phức tạp.
Các kỹ thuật quản lý tệp và mẫu mà bạn đã học ở đây cung cấp nền tảng để tạo tính năng quản lý cấu hình linh hoạt, phù hợp với môi trường, phù hợp với nhu cầu cơ sở hạ tầng của bạn.