1840 lines
40 KiB
Markdown
1840 lines
40 KiB
Markdown
# Ansible 实战指南
|
||
|
||
## 目录
|
||
|
||
1. [运维自动化发展历程及技术应用](#1-运维自动化发展历程及技术应用)
|
||
2. [Ansible 架构和相关命令使用](#2-ansible-架构和相关命令使用)
|
||
3. [Ansible 常用模块详解](#3-ansible-常用模块详解)
|
||
4. [Ansible Playbook 基础](#4-ansible-playbook-基础)
|
||
5. [Playbook 变量、Tags、Handlers 使用](#5-playbook-变量tagshandlers使用)
|
||
6. [Playbook 模板 Templates](#6-playbook-模板-templates)
|
||
7. [Playbook 条件判断 When](#7-playbook-条件判断-when)
|
||
8. [Playbook 字典 with_items](#8-playbook-字典-with_items)
|
||
9. [Ansible Roles](#9-ansible-roles)
|
||
|
||
---
|
||
|
||
## 1. 运维自动化发展历程及技术应用
|
||
|
||
### 1.1 运维自动化发展历程
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ 运维自动化发展历程 │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ 1. 手动时代 │
|
||
│ ├── 人工登录服务器 │
|
||
│ ├── 逐台执行命令 │
|
||
│ └── 效率低下,易出错 │
|
||
│ │
|
||
│ 2. 脚本时代 │
|
||
│ ├── Shell/Python 脚本 │
|
||
│ ├── 批量执行脚本 │
|
||
│ └── 脚本难以维护,无标准化 │
|
||
│ │
|
||
│ 3. 工具时代 │
|
||
│ ├── Puppet、SaltStack、Chef │
|
||
│ ├── 配置管理工具 │
|
||
│ └── 解决一致性,但复杂 │
|
||
│ │
|
||
│ 4. 自动化时代 │
|
||
│ ├── Ansible、Terraform │
|
||
│ ├── 简单易用,Agentless │
|
||
│ └── 编排 + 自动化 │
|
||
│ │
|
||
│ 5. DevOps 时代 │
|
||
│ ├── CI/CD + 自动化运维 │
|
||
│ ├── Kubernetes + 容器 │
|
||
│ └── GitOps 理念 │
|
||
│ │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 1.2 常见运维自动化工具对比
|
||
|
||
| 工具 | 类型 | 架构 | 优点 | 缺点 |
|
||
|------|------|------|------|------|
|
||
| **Ansible** | 配置管理/编排 | Agentless | 简单易学、YAML 语法、无 Agent | 执行速度稍慢 |
|
||
| **Puppet** | 配置管理 | C/S (Agent) | 功能强大、成熟 | 学习曲线陡峭 |
|
||
| **SaltStack** | 配置管理/执行 | C/S (Agent) | 高性能、可远程执行 | 语法复杂 |
|
||
| **Chef** | 配置管理 | C/S (Agent) | Ruby 语法、社区活跃 | 需要编写 Ruby 代码 |
|
||
| **Terraform** | 基础设施代码 | Agentless | 基础设施即代码、云原生 | 专注于基础设施 |
|
||
|
||
### 1.3 Ansible 应用场景
|
||
|
||
| 场景 | 说明 |
|
||
|------|------|
|
||
| **配置管理** | 统一配置服务器、操作系统、应用软件 |
|
||
| **应用部署** | 自动化部署应用程序、容器 |
|
||
| **批量操作** | 批量执行命令、批量修改配置 |
|
||
| ** orchestration** | 多节点编排、任务编排 |
|
||
| **持续交付** | CI/CD 流水线集成 |
|
||
| **基础设施** | 云资源管理、容器编排 |
|
||
|
||
### 1.4 Ansible 在企业中的应用
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Ansible 企业应用架构 │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────┐ │
|
||
│ │ Ansible Control Node │ │
|
||
│ │ (Ansible Server) │ │
|
||
│ └────────────────────┬────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌─────────────┼─────────────┐ │
|
||
│ │ │ │ │
|
||
│ ▼ ▼ ▼ │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │ Web │ │ App │ │ Database │ │
|
||
│ │ Servers │ │ Servers │ │ Servers │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ │
|
||
│ │
|
||
│ 场景: │
|
||
│ - 批量部署/配置服务器 │
|
||
│ - 应用发布和回滚 │
|
||
│ - 监控和日志收集 │
|
||
│ - 安全合规检查 │
|
||
│ │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Ansible 架构和相关命令使用
|
||
|
||
### 2.1 Ansible 架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Ansible 架构 │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────────────────────────────────┐ │
|
||
│ │ Ansible Engine │ │
|
||
│ │ │ │
|
||
│ │ Inventory ──→ Playbooks │ │
|
||
│ │ │ │ │ │
|
||
│ │ ▼ ▼ │ │
|
||
│ │ Plugins ──→ Modules │ │
|
||
│ │ │ │ │ │
|
||
│ │ │ │ │ │
|
||
│ │ └──────────────┘ │ │
|
||
│ │ │ │ │
|
||
│ └───────────┼────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────┐ │
|
||
│ │ Managed Nodes │ │
|
||
│ │ (无 Agent) │ │
|
||
│ │ │ │
|
||
│ │ SSH Connection ──→ Execute Modules │ │
|
||
│ │ │ │
|
||
│ └─────────────────────────────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 2.2 Ansible 核心组件
|
||
|
||
| 组件 | 说明 |
|
||
|------|------|
|
||
| **Inventory** | 主机清单,定义管理的主机 |
|
||
| **Playbook** | 任务剧本,YAML 格式的任务定义 |
|
||
| **Module** | 模块,Ansible 执行的具体任务单元 |
|
||
| **Plugin** | 插件,扩展 Ansible 功能 |
|
||
| **API** | 编程接口,供二次开发使用 |
|
||
|
||
### 2.3 Ansible 安装
|
||
|
||
```bash
|
||
# 使用 pip 安装
|
||
pip install ansible
|
||
|
||
# Ubuntu/Debian
|
||
apt install ansible
|
||
|
||
# CentOS/RHEL
|
||
yum install epel-release
|
||
yum install ansible
|
||
|
||
# macOS
|
||
brew install ansible
|
||
|
||
# 验证安装
|
||
ansible --version
|
||
```
|
||
|
||
### 2.4 Inventory 主机清单
|
||
|
||
#### 2.4.1 静态 Inventory
|
||
|
||
```ini
|
||
# /etc/ansible/hosts 或 -i 指定文件
|
||
|
||
# 单主机
|
||
192.168.1.10
|
||
|
||
# 主机组
|
||
[web]
|
||
192.168.1.10
|
||
192.168.1.11
|
||
192.168.1.12
|
||
|
||
[db]
|
||
192.168.1.20
|
||
192.168.1.21
|
||
|
||
# 嵌套组
|
||
[production:children]
|
||
web
|
||
db
|
||
|
||
# 主机变量
|
||
[web]
|
||
192.168.1.10 ansible_user=admin ansible_ssh_pass=pass123
|
||
192.168.1.11 ansible_user=admin ansible_ssh_pass=pass123
|
||
|
||
# 组变量
|
||
[web:vars]
|
||
ansible_user=admin
|
||
ansible_ssh_pass=pass123
|
||
http_port=80
|
||
```
|
||
|
||
#### 2.4.2 动态 Inventory
|
||
|
||
```bash
|
||
# 使用脚本获取主机列表
|
||
ansible-playbook -i inventory.py playbook.yml
|
||
|
||
# AWS EC2 动态 Inventory
|
||
ansible-playbook -i ec2.py playbook.yml
|
||
```
|
||
|
||
### 2.5 Ansible 配置文件
|
||
|
||
```ini
|
||
# ansible.cfg
|
||
|
||
[defaults]
|
||
inventory = /etc/ansible/hosts
|
||
host_key_checking = False
|
||
retry_files_enabled = False
|
||
gathering = explicit
|
||
# 加速配置
|
||
pipelining = True
|
||
# 并行数
|
||
forks = 50
|
||
|
||
[privilege_escalation]
|
||
become = True
|
||
become_method = sudo
|
||
become_user = root
|
||
become_ask_pass = False
|
||
|
||
[ssh_connection]
|
||
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
|
||
pipelining = True
|
||
```
|
||
|
||
### 2.6 常用命令
|
||
|
||
```bash
|
||
# 帮助
|
||
ansible-doc -h
|
||
ansible-doc <module_name>
|
||
ansible-doc -l # 列出所有模块
|
||
|
||
# 测试连通性
|
||
ansible all -m ping
|
||
|
||
# 执行临时命令
|
||
ansible all -m command -a "uptime"
|
||
ansible all -m shell -a "df -h"
|
||
ansible all -m setup # 获取主机信息
|
||
|
||
# 文件传输
|
||
ansible all -m copy -a "src=/tmp/file dest=/tmp/"
|
||
|
||
# 用户管理
|
||
ansible all -m user -a "name=test state=present"
|
||
|
||
# 包管理
|
||
ansible all -m yum -a "name=httpd state=present"
|
||
|
||
# 服务管理
|
||
ansible all -m service -a "name=httpd state=started"
|
||
|
||
# 查看配置
|
||
ansible-config dump
|
||
|
||
# 查看清单
|
||
ansible-inventory --list
|
||
```
|
||
|
||
### 2.7 Playbook 命令
|
||
|
||
```bash
|
||
# 执行 playbook
|
||
ansible-playbook playbook.yml
|
||
|
||
# 检查模式(不执行)
|
||
ansible-playbook --check playbook.yml
|
||
|
||
# 差异化执行(检查变更)
|
||
ansible-playbook --diff playbook.yml
|
||
|
||
# 指定主机
|
||
ansible-playbook -i inventory.ini playbook.yml
|
||
|
||
# 指定标签
|
||
ansible-playbook --tags "web" playbook.yml
|
||
|
||
# 跳过标签
|
||
ansible-playbook --skip-tags "debug" playbook.yml
|
||
|
||
# 启动步骤
|
||
ansible-playbook --start-at-task "Install Apache" playbook.yml
|
||
|
||
# 步骤执行
|
||
ansible-playbook --step playbook.yml
|
||
|
||
# 详细输出
|
||
ansible-playbook -v playbook.yml
|
||
ansible-playbook -vv playbook.yml
|
||
ansible-playbook -vvv playbook.yml # 详细调试
|
||
|
||
# 清缓存
|
||
ansible-playbook --flush-cache playbook.yml
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Ansible 常用模块详解
|
||
|
||
### 3.1 模块分类
|
||
|
||
| 分类 | 说明 | 常见模块 |
|
||
|------|------|----------|
|
||
| **命令执行** | 执行远程命令 | command, shell, script, raw |
|
||
| **文件操作** | 文件管理 | copy, file, template, synchronize |
|
||
| **包管理** | 软件包管理 | yum, apt, package |
|
||
| **服务管理** | 服务管理 | service, systemd |
|
||
| **用户管理** | 用户管理 | user, group |
|
||
| **数据库** | 数据库操作 | mysql_db, postgresql_db |
|
||
| **云资源** | 云资源管理 | ec2, azure_rm, gce |
|
||
| **容器** | 容器管理 | docker, k8s |
|
||
| **通知** | 通知模块 | email, slack |
|
||
|
||
### 3.2 命令执行模块
|
||
|
||
#### 3.2.1 command 模块
|
||
|
||
```yaml
|
||
- name: Execute command
|
||
command: uptime
|
||
|
||
- name: Execute with args
|
||
command: systemctl start nginx
|
||
|
||
- name: Check file exists
|
||
command: test -f /etc/nginx/nginx.conf
|
||
register: result
|
||
|
||
- name: Create directory
|
||
command: mkdir -p /tmp/test
|
||
creates: /tmp/test # 存在则跳过
|
||
```
|
||
|
||
#### 3.2.2 shell 模块
|
||
|
||
```yaml
|
||
- name: Execute shell
|
||
shell: echo $PATH
|
||
|
||
- name: Execute with pipe
|
||
shell: cat /etc/passwd | grep root
|
||
|
||
- name: Execute script
|
||
shell: |
|
||
#!/bin/bash
|
||
echo "Hello"
|
||
```
|
||
|
||
#### 3.2.3 script 模块
|
||
|
||
```yaml
|
||
- name: Run local script
|
||
script: /tmp/script.sh
|
||
|
||
- name: Run with args
|
||
script: /tmp/script.sh --arg1 value1
|
||
|
||
- name: Run on remote
|
||
script: /tmp/script.sh
|
||
args:
|
||
creates: /tmp/result
|
||
```
|
||
|
||
### 3.3 文件操作模块
|
||
|
||
#### 3.3.1 copy 模块
|
||
|
||
```yaml
|
||
- name: Copy file
|
||
copy:
|
||
src: /tmp/source.conf
|
||
dest: /etc/nginx/nginx.conf
|
||
owner: root
|
||
group: root
|
||
mode: '0644'
|
||
|
||
- name: Copy with backup
|
||
copy:
|
||
src: /tmp/source.conf
|
||
dest: /etc/nginx/nginx.conf
|
||
backup: yes
|
||
|
||
- name: Copy content
|
||
copy:
|
||
dest: /tmp/test.txt
|
||
content: "Hello World"
|
||
```
|
||
|
||
#### 3.3.2 file 模块
|
||
|
||
```yaml
|
||
- name: Create directory
|
||
file:
|
||
path: /tmp/dir
|
||
state: directory
|
||
mode: '0755'
|
||
|
||
- name: Create file
|
||
file:
|
||
path: /tmp/file
|
||
state: touch
|
||
|
||
- name: Create symlink
|
||
file:
|
||
src: /tmp/source
|
||
dest: /tmp/link
|
||
state: link
|
||
|
||
- name: Delete file
|
||
file:
|
||
path: /tmp/file
|
||
state: absent
|
||
```
|
||
|
||
#### 3.3.3 template 模块
|
||
|
||
```yaml
|
||
- name: Template file
|
||
template:
|
||
src: nginx.conf.j2
|
||
dest: /etc/nginx/nginx.conf
|
||
owner: root
|
||
group: root
|
||
mode: '0644'
|
||
validate: 'nginx -t -c %s'
|
||
```
|
||
|
||
#### 3.3.4 synchronize 模块
|
||
|
||
```yaml
|
||
- name: Sync directory
|
||
synchronize:
|
||
src: /tmp/local/
|
||
dest: /tmp/remote/
|
||
delete: yes
|
||
rsync_opts:
|
||
- "--exclude=.git"
|
||
```
|
||
|
||
### 3.4 包管理模块
|
||
|
||
#### 3.4.1 yum 模块
|
||
|
||
```yaml
|
||
- name: Install package
|
||
yum:
|
||
name: nginx
|
||
state: present
|
||
|
||
- name: Install latest
|
||
yum:
|
||
name: '*'
|
||
state: latest
|
||
|
||
- name: Install multiple
|
||
yum:
|
||
name:
|
||
- nginx
|
||
- php-fpm
|
||
state: present
|
||
|
||
- name: Remove package
|
||
yum:
|
||
name: nginx
|
||
state: absent
|
||
|
||
- name: Install from repo
|
||
yum:
|
||
name: epel-release
|
||
enablerepo: epel
|
||
```
|
||
|
||
#### 3.4.2 apt 模块
|
||
|
||
```yaml
|
||
- name: Install package
|
||
apt:
|
||
name: nginx
|
||
state: present
|
||
update_cache: yes
|
||
|
||
- name: Install without update
|
||
apt:
|
||
name: nginx
|
||
state: present
|
||
update_cache: no
|
||
|
||
- name: Install from deb
|
||
apt:
|
||
deb: /tmp/package.deb
|
||
state: present
|
||
```
|
||
|
||
### 3.5 服务管理模块
|
||
|
||
#### 3.5.1 service 模块
|
||
|
||
```yaml
|
||
- name: Start service
|
||
service:
|
||
name: nginx
|
||
state: started
|
||
enabled: yes
|
||
|
||
- name: Stop service
|
||
service:
|
||
name: nginx
|
||
state: stopped
|
||
|
||
- name: Restart service
|
||
service:
|
||
name: nginx
|
||
state: restarted
|
||
|
||
- name: Reload service
|
||
service:
|
||
name: nginx
|
||
state: reloaded
|
||
```
|
||
|
||
#### 3.5.2 systemd 模块
|
||
|
||
```yaml
|
||
- name: Enable and start service
|
||
systemd:
|
||
name: nginx
|
||
state: started
|
||
enabled: yes
|
||
daemon_reload: yes
|
||
```
|
||
|
||
### 3.6 用户管理模块
|
||
|
||
#### 3.6.1 user 模块
|
||
|
||
```yaml
|
||
- name: Create user
|
||
user:
|
||
name: appuser
|
||
comment: "Application User"
|
||
shell: /bin/bash
|
||
home: /home/appuser
|
||
create_home: yes
|
||
|
||
- name: Create with password
|
||
user:
|
||
name: admin
|
||
password: "{{ 'password' | password_hash('sha512') }}"
|
||
|
||
- name: Add to group
|
||
user:
|
||
name: appuser
|
||
groups:
|
||
- wheel
|
||
- docker
|
||
append: yes
|
||
|
||
- name: Remove user
|
||
user:
|
||
name: appuser
|
||
state: absent
|
||
remove: yes
|
||
```
|
||
|
||
#### 3.6.2 group 模块
|
||
|
||
```yaml
|
||
- name: Create group
|
||
group:
|
||
name: mygroup
|
||
state: present
|
||
gid: 1000
|
||
```
|
||
|
||
### 3.7 其他常用模块
|
||
|
||
#### 3.7.1 get_url 模块
|
||
|
||
```yaml
|
||
- name: Download file
|
||
get_url:
|
||
url: http://example.com/file.tar.gz
|
||
dest: /tmp/file.tar.gz
|
||
mode: '0644'
|
||
```
|
||
|
||
#### 3.7.2 unarchive 模块
|
||
|
||
```yaml
|
||
- name: Unarchive file
|
||
unarchive:
|
||
src: /tmp/file.tar.gz
|
||
dest: /tmp/
|
||
remote_src: no
|
||
```
|
||
|
||
#### 3.7.3 lineinfile 模块
|
||
|
||
```yaml
|
||
- name: Add line
|
||
lineinfile:
|
||
path: /etc/selinux/config
|
||
regexp: '^SELINUX='
|
||
line: SELINUX=enforcing
|
||
|
||
- name: Remove line
|
||
lineinfile:
|
||
path: /etc/selinux/config
|
||
regexp: '^SELINUX='
|
||
state: absent
|
||
```
|
||
|
||
#### 3.7.4 find 模块
|
||
|
||
```yaml
|
||
- name: Find files
|
||
find:
|
||
paths: /var/log
|
||
patterns: "*.log"
|
||
age: 7d
|
||
register: log_files
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Ansible Playbook 基础
|
||
|
||
### 4.1 Playbook 概述
|
||
|
||
Playbook 是 Ansible 的任务配置文件,使用 YAML 格式编写,定义了一组有序的任务。
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Playbook 结构 │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Playbook (剧本) │
|
||
│ ├── Play 1 │
|
||
│ │ ├── Hosts (主机) │
|
||
│ │ ├── Vars (变量) │
|
||
│ │ └── Tasks (任务) │
|
||
│ │ ├── Task 1 (Module) │
|
||
│ │ └── Task 2 (Module) │
|
||
│ │ │
|
||
│ └── Play 2 │
|
||
│ ├── Hosts │
|
||
│ ├── Vars │
|
||
│ └── Tasks │
|
||
│ │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 4.2 基础 Playbook 示例
|
||
|
||
```yaml
|
||
# playbook.yml
|
||
---
|
||
- name: Configure Web Server
|
||
hosts: web
|
||
become: yes
|
||
|
||
vars:
|
||
http_port: 80
|
||
|
||
tasks:
|
||
- name: Install Apache
|
||
yum:
|
||
name: httpd
|
||
state: present
|
||
|
||
- name: Ensure Apache is running
|
||
service:
|
||
name: httpd
|
||
state: started
|
||
enabled: yes
|
||
|
||
- name: Copy configuration
|
||
copy:
|
||
src: files/httpd.conf
|
||
dest: /etc/httpd/conf/httpd.conf
|
||
notify: Restart Apache
|
||
|
||
- name: Copy index page
|
||
template:
|
||
src: templates/index.html.j2
|
||
dest: /var/www/html/index.html
|
||
|
||
handlers:
|
||
- name: Restart Apache
|
||
service:
|
||
name: httpd
|
||
state: restarted
|
||
```
|
||
|
||
### 4.3 多个 Play
|
||
|
||
```yaml
|
||
---
|
||
- name: Configure Web Servers
|
||
hosts: web
|
||
become: yes
|
||
|
||
tasks:
|
||
- name: Install Apache
|
||
yum:
|
||
name: httpd
|
||
state: present
|
||
|
||
- name: Start Apache
|
||
service:
|
||
name: httpd
|
||
state: started
|
||
|
||
- name: Configure Database Servers
|
||
hosts: db
|
||
become: yes
|
||
|
||
tasks:
|
||
- name: Install MySQL
|
||
yum:
|
||
name: mysql-server
|
||
state: present
|
||
|
||
- name: Start MySQL
|
||
service:
|
||
name: mysqld
|
||
state: started
|
||
```
|
||
|
||
### 4.4 Play 常用参数
|
||
|
||
| 参数 | 说明 |
|
||
|------|------|
|
||
| `name` | Play 名称 |
|
||
| `hosts` | 目标主机 |
|
||
| `become` | 是否提权 |
|
||
| `become_method` | 提权方式(sudo/su) |
|
||
| `become_user` | 提权用户 |
|
||
| `gather_facts` | 是否收集主机信息 |
|
||
| `vars` | 变量 |
|
||
| `tasks` | 任务列表 |
|
||
| `handlers` | 处理器 |
|
||
| `roles` | 角色 |
|
||
|
||
### 4.5 Task 常用参数
|
||
|
||
| 参数 | 说明 |
|
||
|------|------|
|
||
| `name` | 任务名称 |
|
||
| `module` | 使用的模块 |
|
||
| `args` | 模块参数 |
|
||
| `when` | 条件判断 |
|
||
| `register` | 注册变量 |
|
||
| `changed_when` | 改变判断条件 |
|
||
| `failed_when` | 失败判断条件 |
|
||
| `loop` | 循环 |
|
||
| `until` | 循环直到 |
|
||
| `retries` | 重试次数 |
|
||
| `delay` | 重试延迟 |
|
||
|
||
### 4.6 任务控制
|
||
|
||
```yaml
|
||
# 顺序执行
|
||
- name: Task 1
|
||
yum:
|
||
name: httpd
|
||
state: present
|
||
|
||
- name: Task 2
|
||
service:
|
||
name: httpd
|
||
state: started
|
||
|
||
# 忽略错误
|
||
- name: Ignore error
|
||
command: /some/command
|
||
ignore_errors: yes
|
||
|
||
# 强制失败
|
||
- name: Force fail
|
||
command: /some/command
|
||
failed_when: "'FAILED' in result.stderr"
|
||
|
||
# 标签
|
||
- name: Install packages
|
||
yum:
|
||
name: "{{ item }}"
|
||
tags:
|
||
- packages
|
||
- web
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Playbook 变量、Tags、Handlers 使用
|
||
|
||
### 5.1 变量
|
||
|
||
#### 5.1.1 变量定义
|
||
|
||
```yaml
|
||
# 方式 1:Play 变量
|
||
- hosts: web
|
||
vars:
|
||
http_port: 80
|
||
server_name: example.com
|
||
|
||
tasks:
|
||
- name: Use variable
|
||
debug:
|
||
msg: "Port is {{ http_port }}"
|
||
|
||
# 方式 2:Task 变量
|
||
- name: Task variable
|
||
debug:
|
||
msg: "{{ task_var }}"
|
||
vars:
|
||
task_var: "Hello"
|
||
```
|
||
|
||
#### 5.1.2 主机变量
|
||
|
||
```ini
|
||
# inventory
|
||
[web]
|
||
192.168.1.10 http_port=8080
|
||
192.168.1.11 http_port=8090
|
||
```
|
||
|
||
#### 5.1.3 组变量
|
||
|
||
```yaml
|
||
# group_vars/all.yml
|
||
---
|
||
ansible_user: admin
|
||
ansible_ssh_pass: password
|
||
|
||
# group_vars/web.yml
|
||
---
|
||
http_port: 80
|
||
```
|
||
|
||
#### 5.1.4 变量引用
|
||
|
||
```yaml
|
||
- name: Reference variables
|
||
debug:
|
||
msg: "{{ variable_name }}"
|
||
|
||
- name: Complex reference
|
||
debug:
|
||
msg: "{{ hostvars[groups['web'][0]]['ansible_host'] }}"
|
||
```
|
||
|
||
#### 5.1.5 Facts 变量
|
||
|
||
```yaml
|
||
# 获取 facts
|
||
- name: Get facts
|
||
setup:
|
||
filter: ansible_*
|
||
|
||
- name: Show facts
|
||
debug:
|
||
msg: "{{ ansible_hostname }}"
|
||
|
||
# 常用 facts
|
||
# ansible_hostname - 主机名
|
||
# ansible_default_ipv4.address - IP 地址
|
||
# ansible_distribution - 发行版
|
||
# ansible_distribution_version - 版本
|
||
# ansible_memory_mb.real.total - 内存
|
||
# ansible_processor_vcpus - CPU 核心数
|
||
```
|
||
|
||
### 5.2 Tags
|
||
|
||
#### 5.2.1 Tag 定义
|
||
|
||
```yaml
|
||
- name: Install Apache
|
||
yum:
|
||
name: httpd
|
||
state: present
|
||
tags:
|
||
- web
|
||
- httpd
|
||
|
||
- name: Configure Apache
|
||
template:
|
||
src: httpd.conf.j2
|
||
dest: /etc/httpd/conf/httpd.conf
|
||
tags:
|
||
- config
|
||
- httpd
|
||
```
|
||
|
||
#### 5.2.2 Tag 使用
|
||
|
||
```bash
|
||
# 只执行带 tag 的任务
|
||
ansible-playbook --tags "web" playbook.yml
|
||
|
||
# 跳过 tag
|
||
ansible-playbook --skip-tags "debug" playbook.yml
|
||
|
||
# 多个 tag
|
||
ansible-playbook --tags "web,mysql" playbook.yml
|
||
```
|
||
|
||
### 5.3 Handlers
|
||
|
||
#### 5.3.1 Handler 定义
|
||
|
||
```yaml
|
||
- name: Configure Apache
|
||
template:
|
||
src: httpd.conf.j2
|
||
dest: /etc/httpd/conf/httpd.conf
|
||
notify:
|
||
- Restart Apache
|
||
|
||
handlers:
|
||
- name: Restart Apache
|
||
service:
|
||
name: httpd
|
||
state: restarted
|
||
```
|
||
|
||
#### 5.3.2 多个 Handlers
|
||
|
||
```yaml
|
||
- name: Configure Apache
|
||
template:
|
||
src: httpd.conf.j2
|
||
dest: /etc/httpd/conf/httpd.conf
|
||
notify:
|
||
- Restart Apache
|
||
- Reload Nginx
|
||
|
||
handlers:
|
||
- name: Restart Apache
|
||
service:
|
||
name: httpd
|
||
state: restarted
|
||
|
||
- name: Reload Nginx
|
||
service:
|
||
name: nginx
|
||
state: reloaded
|
||
```
|
||
|
||
#### 5.3.3 Handler 监听
|
||
|
||
```yaml
|
||
- name: Config changed
|
||
template:
|
||
src: app.conf.j2
|
||
dest: /etc/app.conf
|
||
notify:
|
||
- Notify handler
|
||
|
||
handlers:
|
||
- name: Notify handler
|
||
service:
|
||
name: app
|
||
state: restarted
|
||
listen: "config changed"
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Playbook 模板 Templates
|
||
|
||
### 6.1 Jinja2 模板概述
|
||
|
||
Ansible 使用 Jinja2 作为模板引擎,支持变量、过滤器、循环等特性。
|
||
|
||
### 6.2 基础模板
|
||
|
||
```jinja
|
||
{# config.conf.j2 #}
|
||
# Server configuration
|
||
ServerName {{ server_name }}
|
||
Listen {{ http_port }}
|
||
DocumentRoot "{{ document_root }}"
|
||
|
||
{% if enable_ssl %}
|
||
SSLEngine on
|
||
SSLCertificateFile {{ ssl_cert }}
|
||
SSLCertificateKeyFile {{ ssl_key }}
|
||
{% endif %}
|
||
```
|
||
|
||
### 6.3 变量和过滤器
|
||
|
||
```jinja
|
||
{# 使用变量 #}
|
||
{{ variable }}
|
||
|
||
{# 默认值 #}
|
||
{{ variable | default('default_value') }}
|
||
|
||
{# 过滤器 #}
|
||
{{ name | upper }}
|
||
{{ list | join(',') }}
|
||
{{ number | int }}
|
||
|
||
{# 条件判断 #}
|
||
{% if var == 'value' %}
|
||
...
|
||
{% endif %}
|
||
|
||
{# 循环 #}
|
||
{% for item in items %}
|
||
{{ item }}
|
||
{% endfor %}
|
||
```
|
||
|
||
### 6.4 完整示例
|
||
|
||
```yaml
|
||
# playbook.yml
|
||
---
|
||
- name: Configure Nginx
|
||
hosts: web
|
||
become: yes
|
||
|
||
vars:
|
||
server_name: example.com
|
||
http_port: 80
|
||
document_root: /var/www/html
|
||
enable_ssl: true
|
||
ssl_cert: /etc/nginx/ssl/server.crt
|
||
ssl_key: /etc/nginx/ssl/server.key
|
||
|
||
tasks:
|
||
- name: Ensure Nginx installed
|
||
yum:
|
||
name: nginx
|
||
state: present
|
||
|
||
- name: Configure Nginx
|
||
template:
|
||
src: nginx.conf.j2
|
||
dest: /etc/nginx/nginx.conf
|
||
validate: 'nginx -t -c %s'
|
||
notify: Restart Nginx
|
||
|
||
handlers:
|
||
- name: Restart Nginx
|
||
service:
|
||
name: nginx
|
||
state: restarted
|
||
```
|
||
|
||
```jinja
|
||
{# nginx.conf.j2 #}
|
||
user nginx;
|
||
worker_processes {{ worker_processes | default('auto') }};
|
||
error_log /var/log/nginx/error.log;
|
||
|
||
events {
|
||
worker_connections {{ worker_connections | default(1024) }};
|
||
}
|
||
|
||
http {
|
||
include /etc/nginx/mime.types;
|
||
default_type application/octet-stream;
|
||
|
||
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 /var/log/nginx/access.log main;
|
||
|
||
sendfile on;
|
||
tcp_nopush on;
|
||
tcp_nodelay on;
|
||
keepalive_timeout {{ keepalive_timeout | default(65) }};
|
||
|
||
upstream backend {
|
||
{% for server in upstream_servers %}
|
||
server {{ server.host }}:{{ server.port }}{% if server.weight %} weight={{ server.weight }}{% endif %};
|
||
{% endfor %}
|
||
}
|
||
|
||
server {
|
||
listen {{ http_port }};
|
||
server_name {{ server_name }};
|
||
|
||
root {{ document_root }};
|
||
|
||
{% if enable_ssl %}
|
||
listen 443 ssl http2;
|
||
ssl_certificate {{ ssl_cert }};
|
||
ssl_certificate_key {{ ssl_key }};
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||
{% endif %}
|
||
|
||
location / {
|
||
proxy_pass http://backend;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6.5 模板变量文件
|
||
|
||
```yaml
|
||
# group_vars/web.yml
|
||
---
|
||
server_name: example.com
|
||
http_port: 80
|
||
document_root: /var/www/html
|
||
enable_ssl: true
|
||
ssl_cert: /etc/nginx/ssl/server.crt
|
||
ssl_key: /etc/nginx/ssl/server.key
|
||
|
||
upstream_servers:
|
||
- host: 192.168.1.10
|
||
port: 8080
|
||
weight: 5
|
||
- host: 192.168.1.11
|
||
port: 8080
|
||
weight: 3
|
||
|
||
worker_processes: 4
|
||
worker_connections: 2048
|
||
keepalive_timeout: 60
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Playbook 条件判断 When
|
||
|
||
### 7.1 when 基础
|
||
|
||
```yaml
|
||
- name: Install Apache on CentOS
|
||
yum:
|
||
name: httpd
|
||
state: present
|
||
when: ansible_os_family == "RedHat"
|
||
|
||
- name: Install Apache on Debian
|
||
apt:
|
||
name: apache2
|
||
state: present
|
||
when: ansible_os_family == "Debian"
|
||
```
|
||
|
||
### 7.2 多个条件
|
||
|
||
```yaml
|
||
# AND 条件
|
||
- name: Install on specific OS
|
||
yum:
|
||
name: httpd
|
||
state: present
|
||
when:
|
||
- ansible_os_family == "RedHat"
|
||
- ansible_distribution_version | int >= 7
|
||
|
||
# OR 条件
|
||
- name: Install web server
|
||
yum:
|
||
name: nginx
|
||
state: present
|
||
when: ansible_os_family == "RedHat" or ansible_os_family == "Debian"
|
||
```
|
||
|
||
### 7.3 变量判断
|
||
|
||
```yaml
|
||
- name: Register variable
|
||
command: /usr/bin/test -f /etc/httpd/conf/httpd.conf
|
||
register: httpd_conf
|
||
|
||
- name: Check result
|
||
debug:
|
||
msg: "Config file exists"
|
||
when: httpd_conf.rc == 0
|
||
|
||
- name: Check changed
|
||
command: /usr/bin/some-command
|
||
register: result
|
||
changed_when: result.rc != 0
|
||
|
||
- name: Conditional execution
|
||
debug:
|
||
msg: "Command changed"
|
||
when: result is changed
|
||
```
|
||
|
||
### 7.4 内置条件测试
|
||
|
||
```yaml
|
||
- name: Test defined
|
||
debug:
|
||
msg: "Variable defined"
|
||
when: my_var is defined
|
||
|
||
- name: Test undefined
|
||
debug:
|
||
msg: "Variable not defined"
|
||
when: my_var is not defined
|
||
|
||
- name: Test true
|
||
debug:
|
||
msg: "Value is true"
|
||
when: my_var | bool
|
||
|
||
- name: Test false
|
||
debug:
|
||
msg: "Value is false"
|
||
when: not my_var | bool
|
||
|
||
- name: Test string
|
||
debug:
|
||
msg: "String test"
|
||
when: my_string == "value"
|
||
|
||
- name: Test number
|
||
debug:
|
||
msg: "Number test"
|
||
when: my_number > 100
|
||
|
||
- name: Test in
|
||
debug:
|
||
msg: "In list"
|
||
when: ansible_hostname in groups['web']
|
||
```
|
||
|
||
### 7.5 循环 + 条件
|
||
|
||
```yaml
|
||
- name: Install packages based on OS
|
||
yum:
|
||
name: "{{ item }}"
|
||
state: present
|
||
loop:
|
||
- httpd
|
||
- nginx
|
||
when: ansible_os_family == "RedHat"
|
||
|
||
- name: Install specific packages
|
||
apt:
|
||
name: "{{ item.name }}"
|
||
state: present
|
||
loop:
|
||
- { name: 'apache2', os: 'Debian' }
|
||
- { name: 'httpd', os: 'RedHat' }
|
||
when: ansible_os_family == item.os
|
||
```
|
||
|
||
### 7.6 完整示例
|
||
|
||
```yaml
|
||
---
|
||
- name: Configure servers based on OS
|
||
hosts: all
|
||
gather_facts: yes
|
||
|
||
vars:
|
||
install_web: true
|
||
install_db: false
|
||
|
||
tasks:
|
||
- name: Install Apache
|
||
yum:
|
||
name: httpd
|
||
state: present
|
||
when:
|
||
- install_web | bool
|
||
- ansible_os_family == "RedHat"
|
||
|
||
- name: Install Apache on Debian
|
||
apt:
|
||
name: apache2
|
||
state: present
|
||
when:
|
||
- install_web | bool
|
||
- ansible_os_family == "Debian"
|
||
|
||
- name: Install MySQL
|
||
yum:
|
||
name: mysql-server
|
||
state: present
|
||
when:
|
||
- install_db | bool
|
||
- ansible_distribution == "CentOS"
|
||
|
||
- name: Configure firewall for CentOS 7+
|
||
firewalld:
|
||
service: http
|
||
permanent: yes
|
||
state: enabled
|
||
when:
|
||
- ansible_os_family == "RedHat"
|
||
- ansible_distribution_version | int >= 7
|
||
|
||
- name: Only on web servers
|
||
debug:
|
||
msg: "This is a web server"
|
||
when: "'web' in group_names"
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Playbook 字典 with_items
|
||
|
||
### 8.1 with_items 基础
|
||
|
||
```yaml
|
||
- name: Install multiple packages
|
||
yum:
|
||
name: "{{ item }}"
|
||
state: present
|
||
loop:
|
||
- httpd
|
||
- nginx
|
||
- php-fpm
|
||
|
||
- name: Create users
|
||
user:
|
||
name: "{{ item }}"
|
||
state: present
|
||
loop:
|
||
- alice
|
||
- bob
|
||
- charlie
|
||
```
|
||
|
||
### 8.2 字典列表
|
||
|
||
```yaml
|
||
- name: Create multiple users with attributes
|
||
user:
|
||
name: "{{ item.name }}"
|
||
comment: "{{ item.comment }}"
|
||
shell: "{{ item.shell }}"
|
||
create_home: yes
|
||
loop:
|
||
- { name: 'alice', comment: 'Alice User', shell: '/bin/bash' }
|
||
- { name: 'bob', comment: 'Bob User', shell: '/bin/sh' }
|
||
```
|
||
|
||
### 8.3 嵌套循环
|
||
|
||
```yaml
|
||
- name: Create directories
|
||
file:
|
||
path: "{{ item.0 }}/{{ item.1 }}"
|
||
state: directory
|
||
loop:
|
||
- ['/tmp', 'dir1']
|
||
- ['/tmp', 'dir2']
|
||
- ['/var', 'log']
|
||
```
|
||
|
||
### 8.4 with_dict
|
||
|
||
```yaml
|
||
- name: Define dictionary
|
||
set_fact:
|
||
users:
|
||
alice:
|
||
shell: /bin/bash
|
||
home: /home/alice
|
||
bob:
|
||
shell: /bin/sh
|
||
home: /home/bob
|
||
|
||
- name: Create users from dict
|
||
user:
|
||
name: "{{ item.key }}"
|
||
shell: "{{ item.value.shell }}"
|
||
home: "{{ item.value.home }}"
|
||
loop: "{{ dict(users) | dict2items }}"
|
||
```
|
||
|
||
### 8.5 with_fileglob
|
||
|
||
```yaml
|
||
- name: Copy all files
|
||
copy:
|
||
src: "{{ item }}"
|
||
dest: /tmp/
|
||
mode: '0644'
|
||
loop:
|
||
- "{{ playbook_dir }}/files/*"
|
||
```
|
||
|
||
### 8.6 with_sequence
|
||
|
||
```yaml
|
||
- name: Create sequence files
|
||
file:
|
||
path: "/tmp/file{{ item }}"
|
||
state: touch
|
||
loop: "{{ range(1, 11) | list }}"
|
||
```
|
||
|
||
### 8.7 with_together
|
||
|
||
```yaml
|
||
- name: Combine lists
|
||
debug:
|
||
msg: "{{ item.0 }} - {{ item.1 }}"
|
||
loop: "{{ list1 | zip(list2) | list }}"
|
||
```
|
||
|
||
### 8.8 with_nested
|
||
|
||
```yaml
|
||
- name: Nested loop
|
||
debug:
|
||
msg: "{{ item.0 }} - {{ item.1 }}"
|
||
loop: "{{ ['a', 'b', 'c'] | product(['1', '2', '3']) | list }}"
|
||
```
|
||
|
||
### 8.9 注册变量 + 循环
|
||
|
||
```yaml
|
||
- name: Get file contents
|
||
command: cat {{ item }}
|
||
register: file_contents
|
||
loop:
|
||
- /tmp/file1.txt
|
||
- /tmp/file2.txt
|
||
|
||
- name: Show contents
|
||
debug:
|
||
msg: "{{ item.stdout }}"
|
||
loop: "{{ file_contents.results }}"
|
||
```
|
||
|
||
### 8.10 完整示例
|
||
|
||
```yaml
|
||
---
|
||
- name: Configure multi-tier application
|
||
hosts: app
|
||
|
||
vars:
|
||
app_users:
|
||
- { name: 'appuser', uid: 1000, group: 'app', shell: '/bin/bash' }
|
||
- { name: 'deploy', uid: 1001, group: 'app', shell: '/bin/sh' }
|
||
|
||
app_dirs:
|
||
- { path: '/opt/app', owner: 'appuser', mode: '0755' }
|
||
- { path: '/var/log/app', owner: 'appuser', mode: '0755' }
|
||
- { path: '/tmp/app', owner: 'appuser', mode: '1777' }
|
||
|
||
packages:
|
||
- java-11-openjdk
|
||
- maven
|
||
- git
|
||
|
||
tasks:
|
||
- name: Create groups
|
||
group:
|
||
name: "{{ item }}"
|
||
state: present
|
||
loop:
|
||
- app
|
||
- deploy
|
||
|
||
- name: Create users
|
||
user:
|
||
name: "{{ item.name }}"
|
||
uid: "{{ item.uid }}"
|
||
group: "{{ item.group }}"
|
||
shell: "{{ item.shell }}"
|
||
create_home: yes
|
||
loop: "{{ app_users }}"
|
||
|
||
- name: Create directories
|
||
file:
|
||
path: "{{ item.path }}"
|
||
owner: "{{ item.owner }}"
|
||
mode: "{{ item.mode }}"
|
||
state: directory
|
||
loop: "{{ app_dirs }}"
|
||
|
||
- name: Install packages
|
||
yum:
|
||
name: "{{ item }}"
|
||
state: present
|
||
loop: "{{ packages }}"
|
||
when: ansible_os_family == "RedHat"
|
||
|
||
- name: Install packages (Debian)
|
||
apt:
|
||
name: "{{ item }}"
|
||
state: present
|
||
update_cache: yes
|
||
loop: "{{ packages }}"
|
||
when: ansible_os_family == "Debian"
|
||
```
|
||
|
||
---
|
||
|
||
## 9. Ansible Roles
|
||
|
||
### 9.1 Roles 概述
|
||
|
||
Roles 是 Ansible 的组织结构化机制,将 Playbook 分解为可重用的组件。
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Roles 目录结构 │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ roles/ │
|
||
│ └── role_name/ │
|
||
│ ├── defaults/ # 默认变量(最低优先级)│
|
||
│ │ └── main.yml │
|
||
│ ├── vars/ # 变量(最高优先级) │
|
||
│ │ └── main.yml │
|
||
│ ├── tasks/ # 任务 │
|
||
│ │ └── main.yml │
|
||
│ ├── handlers/ # 处理器 │
|
||
│ │ └── main.yml │
|
||
│ ├── templates/ # 模板 │
|
||
│ │ └── *.j2 │
|
||
│ ├── files/ # 静态文件 │
|
||
│ │ └── * │
|
||
│ ├── meta/ # 依赖关系 │
|
||
│ │ └── main.yml │
|
||
│ └── README.md # 文档 │
|
||
│ │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 9.2 创建 Role
|
||
|
||
```bash
|
||
# 使用 ansible-galaxy 创建
|
||
ansible-galaxy init role_name
|
||
|
||
# 手动创建目录结构
|
||
mkdir -p roles/nginx/{defaults,vars,tasks,handlers,templates,files,meta}
|
||
```
|
||
|
||
### 9.3 Role 示例:Nginx
|
||
|
||
#### 9.3.1 defaults/main.yml
|
||
|
||
```yaml
|
||
---
|
||
# defaults/main.yml
|
||
nginx_version: "1.24"
|
||
nginx_port: 80
|
||
nginx_worker_processes: auto
|
||
nginx_worker_connections: 1024
|
||
nginx_server_name: localhost
|
||
nginx_document_root: /var/www/html
|
||
```
|
||
|
||
#### 9.3.2 vars/main.yml
|
||
|
||
```yaml
|
||
---
|
||
# vars/main.yml
|
||
nginx_user: nginx
|
||
nginx_group: nginx
|
||
nginx_conf_dir: /etc/nginx
|
||
nginx_log_dir: /var/log/nginx
|
||
```
|
||
|
||
#### 9.3.3 tasks/main.yml
|
||
|
||
```yaml
|
||
---
|
||
# tasks/main.yml
|
||
- name: Ensure nginx is installed
|
||
yum:
|
||
name: nginx
|
||
state: present
|
||
when: ansible_os_family == "RedHat"
|
||
|
||
- name: Ensure nginx is installed
|
||
apt:
|
||
name: nginx
|
||
state: present
|
||
update_cache: yes
|
||
when: ansible_os_family == "Debian"
|
||
|
||
- name: Copy nginx configuration
|
||
template:
|
||
src: nginx.conf.j2
|
||
dest: /etc/nginx/nginx.conf
|
||
notify: Restart nginx
|
||
|
||
- name: Ensure nginx is running
|
||
service:
|
||
name: nginx
|
||
state: started
|
||
enabled: yes
|
||
```
|
||
|
||
#### 9.3.4 handlers/main.yml
|
||
|
||
```yaml
|
||
---
|
||
# handlers/main.yml
|
||
- name: Restart nginx
|
||
service:
|
||
name: nginx
|
||
state: restarted
|
||
|
||
- name: Reload nginx
|
||
service:
|
||
name: nginx
|
||
state: reloaded
|
||
```
|
||
|
||
#### 9.3.5 templates/nginx.conf.j2
|
||
|
||
```jinja
|
||
# nginx.conf.j2
|
||
user {{ nginx_user }};
|
||
worker_processes {{ nginx_worker_processes }};
|
||
error_log {{ nginx_log_dir }}/error.log;
|
||
|
||
events {
|
||
worker_connections {{ nginx_worker_connections }};
|
||
}
|
||
|
||
http {
|
||
include /etc/nginx/mime.types;
|
||
default_type application/octet-stream;
|
||
|
||
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_log_dir }}/access.log main;
|
||
|
||
sendfile on;
|
||
tcp_nopush on;
|
||
tcp_nodelay on;
|
||
keepalive_timeout 65;
|
||
|
||
server {
|
||
listen {{ nginx_port }};
|
||
server_name {{ nginx_server_name }};
|
||
|
||
root {{ nginx_document_root }};
|
||
|
||
location / {
|
||
index index.html index.htm;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 9.4 使用 Role
|
||
|
||
```yaml
|
||
# site.yml
|
||
---
|
||
- name: Configure web servers
|
||
hosts: web
|
||
|
||
roles:
|
||
- role: nginx
|
||
nginx_port: 8080
|
||
nginx_server_name: example.com
|
||
|
||
- name: Configure database servers
|
||
hosts: db
|
||
|
||
roles:
|
||
- role: mysql
|
||
mysql_port: 3306
|
||
```
|
||
|
||
### 9.5 Role 依赖
|
||
|
||
```yaml
|
||
# roles/common/meta/main.yml
|
||
---
|
||
dependencies:
|
||
- role: common
|
||
vars:
|
||
common_version: 1.0
|
||
- role: monitoring
|
||
```
|
||
|
||
### 9.6 完整 Playbook 示例
|
||
|
||
```yaml
|
||
# site.yml - 完整项目配置
|
||
---
|
||
- name: Infrastructure setup
|
||
hosts: all
|
||
gather_facts: yes
|
||
|
||
roles:
|
||
- common
|
||
- ntp
|
||
|
||
- name: Web servers setup
|
||
hosts: web
|
||
become: yes
|
||
|
||
roles:
|
||
- nginx
|
||
- php-fpm
|
||
- firewall
|
||
|
||
- name: Database servers setup
|
||
hosts: db
|
||
become: yes
|
||
|
||
roles:
|
||
- mysql
|
||
- backup
|
||
|
||
- name: Application deployment
|
||
hosts: app
|
||
become: yes
|
||
|
||
roles:
|
||
- app_deploy
|
||
- monitoring_agent
|
||
```
|
||
|
||
### 9.7 导入 Role
|
||
|
||
```yaml
|
||
# 静态导入
|
||
- name: Import role
|
||
import_role:
|
||
name: nginx
|
||
vars:
|
||
nginx_port: 8080
|
||
|
||
- name: Import handlers
|
||
import_tasks: handlers.yml
|
||
```
|
||
|
||
### 9.8 动态 Role
|
||
|
||
```yaml
|
||
# 动态导入
|
||
- name: Include role
|
||
include_role:
|
||
name: nginx
|
||
vars:
|
||
nginx_port: 80
|
||
```
|
||
|
||
### 9.9 Galaxy 角色
|
||
|
||
```bash
|
||
# 搜索角色
|
||
ansible-galaxy search nginx
|
||
|
||
# 安装角色
|
||
ansible-galaxy install geerlingguy.nginx
|
||
|
||
# 查看已安装角色
|
||
ansible-galaxy list
|
||
|
||
# 删除角色
|
||
ansible-galaxy remove geerlingguy.nginx
|
||
```
|
||
|
||
---
|
||
|
||
## 附录
|
||
|
||
### 常用命令速查
|
||
|
||
| 命令 | 说明 |
|
||
|------|------|
|
||
| `ansible all -m ping` | 测试连通性 |
|
||
| `ansible-playbook site.yml` | 执行 Playbook |
|
||
| `ansible-playbook --check site.yml` | 模拟执行 |
|
||
| `ansible-playbook --tags "web" site.yml` | 指定标签 |
|
||
| `ansible-doc -l` | 列出模块 |
|
||
| `ansible-doc user` | 查看模块文档 |
|
||
| `ansible-galaxy init role` | 创建角色 |
|
||
| `ansible-config dump` | 查看配置 |
|
||
|
||
### 配置参数速查
|
||
|
||
| 参数 | 说明 |
|
||
|------|------|
|
||
| `inventory` | 主机清单 |
|
||
| `forks` | 并行数 |
|
||
| `become` | 提权 |
|
||
| `host_key_checking` | 主机指纹检查 |
|
||
| `retry_files_enabled` | 重试文件 |
|
||
|
||
### 变量优先级
|
||
|
||
| 优先级(低到高) |
|
||
|----------|
|
||
| role defaults |
|
||
| inventory file/script group vars |
|
||
| inventory group vars |
|
||
| playbook group vars |
|
||
| host facts |
|
||
| register vars |
|
||
| set_facts |
|
||
| role/vars |
|
||
| include vars |
|
||
| include params |
|
||
| extra vars |
|
||
|
||
---
|
||
|
||
*文档创建时间:2024年* |