第 1 章:Ansible 入门认知
1.1 什么是 Ansible?
- 通俗解释:Ansible 是一款 "批量运维工具",可以让你在一台管理机上,同时操控几十、几百台服务器,不用逐台登录操作。
- 核心优势(小白友好):
- 无代理:被管理节点不用装额外软件,靠 SSH 就能通信;
- 简单:不用写复杂代码,用 "命令" 或 "配置文件" 就能实现批量操作;
- 强大:支持安装软件、执行命令、分发文件、定时任务等几乎所有运维场景。
1.2 Ansible 能做什么?(实际场景)
- 批量安装 Nginx、MySQL 等软件;
- 批量执行命令(如查看所有服务器磁盘使用率);
- 批量分发配置文件(如给所有 Web 服务器发 Nginx 配置);
- 批量启动 / 重启服务(如所有服务器重启防火墙);
- 批量创建用户、授权(如给所有节点创建运维用户)。
1.3 Ansible 核心概念(不用死记,后续慢慢理解)
- 管理端(控制节点):你操作的那台机器(比如你的电脑或一台专门的运维机);
- 被管理节点(被控节点):需要被批量管理的服务器(比如 Web 服务器、数据库服务器);
- 主机清单:一个配置文件,记录所有被管理节点的 IP / 主机名,还能分组(如 Web 组、数据库组);
- 模块:Ansible 内置的 "工具函数",比如
yum模块用来装软件、copy模块用来传文件; - Playbook:"剧本",把多个操作按顺序写在一个文件里,执行一次就能完成一系列任务(如 "装 Nginx → 传配置 → 启动服务")。
第 2 章:管理端安装与环境配置(1 课时)
2.1 安装 Ansible(CentOS 系统)
Ansible 不在 CentOS 官方默认源里,需要先装 "扩展源(EPEL)",再装 Ansible。
步骤 1:安装 EPEL 源
打开管理端的终端,执行以下命令(复制粘贴即可):
bash
运行
# CentOS 7 执行
yum install -y epel-release
# CentOS 8 执行(如果提示找不到包,再执行这个)
dnf install -y epel-release
- 解释:
yum是 CentOS 的软件安装工具,-y表示 "所有提示都选 yes",不用手动确认。
步骤 2:安装 Ansible
bash
运行
# CentOS 7 执行
yum install -y ansible
# CentOS 8 执行
dnf install -y ansible
步骤 3:验证安装成功
执行以下命令,能看到版本号就说明安装成功:
bash
运行
ansible --version
-
成功示例输出(版本号可能不同,正常): plaintext
ansible 2.9.27 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
2.2 认识 Ansible 默认目录
安装后,Ansible 会自动创建以下目录,核心文件就两个:
plaintext
/etc/ansible/ # Ansible 主目录
├── ansible.cfg # 全局配置文件(默认不用改!)
├── hosts # 主机清单(核心!记录被管理节点)
└── roles/ # 角色目录(后续进阶用)
2.3 配置主机清单(hosts 文件)
主机清单是 Ansible 识别 "要管理哪些服务器" 的配置文件,必须手动编辑。
步骤 1:编辑 hosts 文件
bash
运行
vi /etc/ansible/hosts
- 解释:
vi是 Linux 自带的文本编辑器,按i进入 "编辑模式"。
步骤 2:添加被管理节点(示例)
假设你有 2 台被管理节点:
- Web 服务器:192.168.10.14
- 数据库服务器:192.168.10.15
在 hosts 文件末尾添加以下内容(按 i 后复制粘贴):
ini
# 这是注释(# 开头的行是注释,Ansible 会忽略)
# 分组:Web 服务器组(组名自定义,比如 webservers)
[webservers]
192.168.10.14 # 被管理节点的 IP 地址
# 分组:数据库服务器组
[dbservers]
192.168.10.15 # 另一台被管理节点的 IP 地址
# 分组:所有服务器(嵌套组,包含上面两个组)
[all_servers:children]
webservers
dbservers
- 编辑完后,按
Esc键,输入:wq(冒号 + wq),回车保存退出。
步骤 3:验证主机清单
执行以下命令,查看 Ansible 是否能识别配置的节点:
bash
运行
# 查看所有被管理节点
ansible all --list-hosts
# 查看 webservers 组的节点
ansible webservers --list-hosts
-
成功示例(能看到配置的 IP 就是对的): plaintext
hosts (2): 192.168.10.14 192.168.10.15
2.4 配置免密 SSH 登录(核心!必须做)
Ansible 靠 SSH 通信,若每次操作都要输密码,非常麻烦。配置 "免密登录" 后,管理端能直接登录被管理节点,无需输入密码。
核心原理
- 管理端生成一对 "钥匙":公钥(可以给别人)和私钥(自己留着,不能泄露);
- 把管理端的 "公钥" 拷贝到所有被管理节点;
- 后续管理端登录被管理节点时,被管理节点用 "公钥" 验证管理端的 "私钥",验证通过就不用输密码。
步骤 1:管理端生成密钥对
在管理端终端执行以下命令,按 3 次回车(不用输入任何内容):
bash
运行
ssh-keygen -t rsa
- 执行后,会在
~/.ssh/目录下生成两个文件:id_rsa:私钥(自己留着,千万别删!);id_rsa.pub:公钥(要拷贝到被管理节点)。
步骤 2:拷贝公钥到被管理节点
首先安装 sshpass 工具(用于非交互输入密码,避免手动输密码):
bash
运行
yum install -y sshpass
然后执行以下命令,把公钥拷贝到被管理节点(替换成你的被管理节点 IP 和 root 密码):
bash
运行
# 拷贝到 webservers 组的 192.168.10.14(密码替换成你的被管理节点 root 密码)
sshpass -p '你的被管理节点密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.10.14
# 拷贝到 dbservers 组的 192.168.10.15
sshpass -p '你的被管理节点密码' ssh-copy-id -o StrictHostKeyChecking=no root@192.168.10.15
- 成功提示:
Number of key(s) added: 1(表示公钥拷贝成功)。
步骤 3:验证免密登录
在管理端执行以下命令,不用输密码能登录就说明成功:
bash
运行
# 登录 192.168.10.14
ssh root@192.168.10.14
# 登录成功后,输入 exit 退出
exit
2.5 测试 Ansible 连通性(最后一步)
执行以下命令,测试管理端是否能正常连接所有被管理节点:
bash
运行
# 测试所有节点(ping 模块:类似网络 ping,测试连通性)
ansible all -m ping
-
成功示例(每个节点都显示
SUCCESS和ping: pong):plaintext
192.168.10.14 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.10.15 | SUCCESS => { "changed": false, "ping": "pong" } -
若失败:回到前面步骤,检查免密配置或主机清单是否正确。
第 3 章:Ansible 命令基础
3.1 命令格式(核心!记牢)
Ansible 命令的通用格式:
bash
运行
ansible [目标节点/组] -m [模块名] -a [模块参数] [可选参数]
- 通俗解释:
[目标节点/组]:要操作的服务器(比如all所有节点、webservers组);-m [模块名]:用哪个 "工具"(比如ping模块测试连通、yum模块装软件);-a [模块参数]:工具的具体操作(比如yum模块的参数是 "装 nginx");- 可选参数:比如
-u指定登录用户、-vvv查看详细日志(排障用)。
3.2 常用可选参数(小白必备)
| 参数 | 作用 | 示例 |
|---|---|---|
-u 用户名 |
指定远程登录用户(默认是 root) | -u admin |
-k |
提示输入远程用户密码(免密失败时用) | -k |
-vvv |
详细输出日志(排障神器,能看到执行过程) | -vvv |
-i 清单路径 |
指定自定义主机清单(默认是 /etc/ansible/hosts) | -i ./my_hosts |
3.3 实战:执行简单命令
示例 1:查看所有节点的系统版本
bash
运行
# 用 command 模块(默认模块,可省略 -m command),执行命令 cat /etc/redhat-release
ansible all -a "cat /etc/redhat-release"
- 输出:每个节点的系统版本(比如 CentOS Linux release 7.9.2009 (Core))。
示例 2:查看 webservers 组节点的磁盘使用率
bash
运行
ansible webservers -a "df -h"
- 解释:
df -h是 Linux 查看磁盘使用率的命令,Ansible 会在所有 web 节点执行这个命令并返回结果。
示例 3:给 dbservers 组节点创建一个目录
bash
运行
ansible dbservers -a "mkdir -p /data/logs"
- 解释:
mkdir -p是 Linux 创建目录(递归创建,父目录不存在也能创建),这里在数据库节点创建/data/logs目录。
3.4 命令执行结果解读
Ansible 执行命令后,每个节点的结果会显示 3 种状态:
SUCCESS:执行成功;CHANGED:执行后节点状态发生变化(比如创建了目录、安装了软件);FAILED:执行失败(会显示错误原因,比如命令写错、权限不足)。
第 4 章:常用模块
Ansible 有几百个模块,但小白掌握以下 8 个核心模块,就能应对 90% 的运维场景!每个模块都带 "通俗解释 + 实战示例"。
4.1 ping 模块:测试连通性(最常用)
- 作用:测试管理端与被管理节点的网络和 SSH 连通性(类似网络 ping);
- 特点:无参数,执行后返回
pong就是成功。
示例:
bash
运行
# 测试所有节点连通性
ansible all -m ping
# 测试单个节点(192.168.10.14),并输出详细日志
ansible 192.168.10.14 -m ping -vvv
4.2 command 模块:执行简单 Linux 命令
- 作用:在被管理节点执行 Linux 命令;
- 缺点:不支持管道(
|)、重定向(>/>>)、通配符(*); - 场景:执行简单命令(如查看目录、创建文件)。
示例:
bash
运行
# 1. 查看所有节点的 /tmp 目录内容
ansible all -m command -a "ls /tmp"
# 2. 重启所有节点的 sshd 服务
ansible all -m command -a "systemctl restart sshd"
# 3. 查看节点的 CPU 使用率
ansible webservers -m command -a "top -bn1 | grep 'Cpu(s)'"
- 注意:如果命令带空格,必须用双引号包裹(比如
ls /tmp没问题,ls "/my dir"带空格需引号)。
4.3 shell 模块:执行复杂 Linux 命令
- 作用:和
command模块一样执行命令,但支持管道、重定向、通配符; - 场景:执行复杂命令(如过滤日志、统计数据)。
示例:
bash
运行
# 1. 查看所有节点的 nginx 进程(支持管道 |)
ansible webservers -m shell -a "ps aux | grep nginx | grep -v grep"
# 2. 把系统负载写入文件(支持重定向 >>)
ansible all -m shell -a "uptime >> /tmp/system_load.log"
# 3. 统计 /var/log 目录下的日志文件数(支持通配符 *.log)
ansible dbservers -m shell -a "ls -l /var/log/*.log | wc -l"
- 小白提示:分不清
command和shell时,直接用shell模块(兼容性更强)。
4.4 yum 模块:安装 / 卸载 RPM 软件
- 作用:在 CentOS 系统上安装、卸载、更新软件(自动处理依赖,比手动执行
yum install安全); - 核心参数:
name:软件包名(必填);state:状态(present= 安装,absent= 卸载,latest= 更新到最新版)。
示例:
bash
运行
# 1. 给 webservers 组节点安装 nginx
ansible webservers -m yum -a "name=nginx state=present"
# 2. 给 dbservers 组节点安装 mariadb-server 并更新到最新版
ansible dbservers -m yum -a "name=mariadb-server state=latest"
# 3. 卸载所有节点的 httpd(Apache 服务)
ansible all -m yum -a "name=httpd state=absent"
- 解释:
state=present表示 "确保软件已安装",如果已经安装,不会重复安装。
4.5 copy 模块:本地文件拷贝到远程节点
- 作用:把管理端的文件 / 目录,批量拷贝到被管理节点;
- 核心参数:
src:本地文件 / 目录路径(必填);dest:远程节点的目标路径(必填);mode:文件权限(如755执行权限、644只读权限);owner/group:文件所有者 / 所属组。
示例:
bash
运行
# 1. 把管理端的 /etc/hosts 拷贝到所有节点的 /tmp/ 目录(保留权限)
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts mode=644 owner=root group=root"
# 2. 把管理端的本地脚本(./deploy.sh)拷贝到 web 节点,并添加执行权限
ansible webservers -m copy -a "src=./deploy.sh dest=/usr/local/bin/ mode=755"
# 3. 直接在远程节点创建文件并写入内容(不用本地文件)
ansible dbservers -m copy -a "content='DB_HOST=192.168.10.15' dest=/etc/my.cnf.d/custom.cnf"
- 小白提示:
mode=755表示 "所有者可读写执行,其他人只读执行",脚本文件必须设为755才能运行。
4.6 service 模块:管理系统服务
- 作用:启动、停止、重启系统服务(如 nginx、mariadb),支持开机自启;
- 核心参数:
name:服务名(必填,如nginx、mariadb);state:状态(started= 启动,stopped= 停止,restarted= 重启,reloaded= 重载配置);enabled:是否开机自启(yes= 是,no= 否)。
示例:
bash
运行
# 1. 启动 web 节点的 nginx 服务,并设置开机自启
ansible webservers -m service -a "name=nginx state=started enabled=yes"
# 2. 重启 db 节点的 mariadb 服务
ansible dbservers -m service -a "name=mariadb state=restarted"
# 3. 停止所有节点的 httpd 服务,并禁用开机自启
ansible all -m service -a "name=httpd state=stopped enabled=no"
- 解释:
enabled=yes表示 "系统开机后自动启动该服务",避免服务器重启后服务停止。
4.7 file 模块:管理文件 / 目录属性
- 作用:创建目录、删除文件、修改文件权限 / 所有者等;
- 核心参数:
path:远程节点的文件 / 目录路径(必填);state:状态(directory= 创建目录,absent= 删除文件 / 目录,file= 确保文件存在);mode/owner/group:权限 / 所有者 / 所属组。
示例:
bash
运行
# 1. 在所有节点创建 /data/backup 目录(递归创建父目录)
ansible all -m file -a "path=/data/backup state=directory mode=755"
# 2. 删除所有节点的 /tmp/old.log 文件
ansible all -m file -a "path=/tmp/old.log state=absent"
# 3. 修改 web 节点的 nginx 配置文件权限(只读)
ansible webservers -m file -a "path=/etc/nginx/nginx.conf mode=644 owner=root group=root"
- 小白提示:
state=directory会自动创建父目录(比如/data/backup不存在时,会先创建/data再创建/backup)。
4.8 user 模块:管理系统用户
- 作用:创建用户、删除用户、修改用户密码、添加用户组等;
- 核心参数:
name:用户名(必填);state:状态(present= 创建,absent= 删除);password:用户密码(需要用加密后的字符串,不能直接写明文);groups:用户所属组;shell:登录 shell(如/bin/bash允许登录,/sbin/nologin禁止登录)。
示例:
bash
运行
# 1. 给所有节点创建运维用户 ops(密码是加密后的 123456)
# 先在管理端生成密码加密串:python -c 'import crypt; print crypt.crypt("123456")'
ansible all -m user -a "name=ops password='$6$xG8rI$z6V3eG9Q4...' groups=wheel shell=/bin/bash"
# 2. 删除所有节点的 test 用户
ansible all -m user -a "name=test state=absent"
# 3. 给 db 节点创建 mysql 用户(禁止登录,仅用于运行服务)
ansible dbservers -m user -a "name=mysql state=present shell=/sbin/nologin"
- 小白提示:密码不能直接写明文(比如
password=123456),必须用加密串!生成加密串的命令:python -c 'import crypt; print crypt.crypt("你的密码")',把输出的字符串作为password参数。
第 5 章:Playbook
5.1 什么是 Playbook?
- 通俗解释:Playbook 是 "剧本",把多个模块按顺序写在一个 YAML 格式的文件里,执行一次剧本,就能自动完成一系列操作(比如 "装 Nginx → 传配置 → 启动服务 → 设置开机自启")。
- 优势:可复用、可维护,适合复杂场景(比如批量部署 Web 服务)。
5.2 Playbook 基础语法(小白必记)
- 文件名后缀:通常用
.yml或.yaml(比如deploy_nginx.yml); - 语法规则:
- 缩进:用 2 个空格(不能用 Tab!),缩进决定层级关系;
- 键值对:
key: value(冒号后面必须加空格); - 列表:用
-开头(比如- name: 安装 nginx); - 注释:
#开头的行。
5.3 实战:编写 Playbook 批量部署 Nginx
目标:给 webservers 组所有节点部署 Nginx 服务,步骤:
- 安装 Nginx;
- 拷贝本地 Nginx 配置文件到远程;
- 启动 Nginx 服务并设置开机自启;
- 创建网站根目录。
步骤 1:准备本地 Nginx 配置文件
在管理端创建 nginx.conf 文件(简单配置示例):
bash
运行
vi nginx.conf
添加以下内容:
nginx
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html;
}
}
}
按 Esc → :wq 保存退出。
步骤 2:编写 Playbook(deploy_nginx.yml)
bash
运行
vi deploy_nginx.yml
添加以下内容(注意缩进用 2 个空格):
# 剧本名称:批量部署 Nginx
- name: Deploy Nginx Service
hosts: webservers # 目标组:webservers
remote_user: root # 远程登录用户:root
tasks: # 任务列表(按顺序执行)
# 任务 1:安装 Nginx
- name: Install Nginx
yum:
name: nginx
state: present
# 任务 2:拷贝本地 Nginx 配置文件到远程
- name: Copy Nginx config file
copy:
src: ./nginx.conf # 本地配置文件路径
dest: /etc/nginx/nginx.conf # 远程目标路径
mode: 644
owner: root
group: root
# 任务 3:创建网站根目录
- name: Create web root directory
file:
path: /usr/share/nginx/html
state: directory
mode: 755
# 任务 4:启动 Nginx 并设置开机自启
- name: Start and enable Nginx service
service:
name: nginx
state: started
enabled: yes
保存退出(Esc → :wq)。
示例2:Playbook 稳定完成 HTTPD 服务的部署、配置和启动全流程


.命令行运行 Playbook
ansible-playbook test1.yaml # 运行 playbook
ansible-playbook test1.yaml --syntax-check # 检查语法
ansible-playbook test1.yaml --list-task # 查看任务列表
ansible-playbook test1.yaml --list-hosts # 查看影响的主机
ansible-playbook test1.yaml --start-at-task='install httpd' # 从指定任务开始执行
步骤 3:执行 Playbook
在管理端执行以下命令,运行剧本:
bash
运行
ansible-playbook deploy_nginx.yml
- 执行过程:Ansible 会按任务顺序,在所有 web 节点执行操作,每个任务会显示
OK(已完成)、CHANGED(已修改)或FAILED(失败)。 - 成功提示:最后一行显示
PLAY RECAP,所有节点的failed=0就是成功。
步骤 4:验证部署结果
执行以下命令,检查 Nginx 是否正常运行:
bash
运行
# 查看 web 节点的 Nginx 状态
ansible webservers -a "systemctl status nginx"
# 访问 Nginx 首页(测试 80 端口是否通)
ansible webservers -m shell -a "curl http://localhost"
- 若能看到 Nginx 的默认首页内容,说明部署成功!
第 6 章:常见问题排查(1 课时)
小白使用 Ansible 时,最容易遇到以下问题,掌握排查方法就能快速解决:
6.1 免密登录失败(Permission denied)
如果要使用 SSH****密码或 sudo****密码,可以使用以下选项:
ansible-playbook test1.yaml -k # 提示输入 SSH 密码
ansible-playbook test1.yaml -K # 提示输入 sudo 密码
报错示例
plaintext
192.168.10.14 | UNREACHABLE! => {
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,password)"
}
排查步骤
- 手动 SSH 测试:
ssh root@192.168.10.14,看是否能登录; - 若提示
publickey失败:重新执行公钥分发命令(ssh-copy-id); - 若提示
password失败:- 检查被管理节点的
sshd_config文件:PasswordAuthentication yes(是否启用密码登录); - 重启 SSH 服务:
systemctl restart sshd;
- 检查被管理节点的
- 检查权限:被管理节点的
~/.ssh目录权限必须是700,authorized_keys文件权限必须是600(执行chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys)。
6.2 模块执行失败(如 yum 安装失败)
报错示例
plaintext
192.168.10.14 | FAILED! => {
"msg": "No package matching 'nginx' found available, installed or updated"
}
排查步骤
- 用
-vvv查看详细日志:ansible webservers -m yum -a "name=nginx" -vvv; - 检查被管理节点的 yum 源是否正常:
ansible webservers -m shell -a "yum repolist"; - 若 yum 源异常:重新安装 EPEL 源(
yum install -y epel-release)。
6.3 Playbook 语法错误
报错示例
plaintext
ERROR! Syntax Error while loading YAML.
expected <block end>, but found '-'
排查步骤
- 检查缩进:是否用了 2 个空格(不能用 Tab);
- 检查冒号:
key: value冒号后面是否加了空格; - 检查列表:
- name: 任务名前面是否有正确缩进; - 用
ansible-playbook --syntax-check deploy_nginx.yml检查语法(不执行,只检查语法错误)。
6.4 被管理节点防火墙 / SELinux 拦截
现象
- 手动 SSH 能登录,但 Ansible 执行命令超时或失败;
- 安装 Nginx 后,无法访问 80 端口。
解决方法
-
临时关闭防火墙(测试用): bash
运行
ansible all -m command -a "systemctl stop firewalld" -
临时关闭 SELinux(测试用): bash
运行
ansible all -m command -a "setenforce 0" -
生产环境推荐:放行需要的端口(如 80、22),而非关闭防火墙。
第 7 章:课程总结与进阶方向
7.1 核心知识点总结
- Ansible 核心流程:管理端 → 主机清单 → 被管理节点(靠 SSH 通信);
- 命令格式:
ansible 目标 -m 模块 -a 参数; - 8 个核心模块:
ping、command、shell、yum、copy、service、file、user; - Playbook:按顺序执行多个任务,适合复杂场景。
附录:常用命令速查(小白必备)
| 功能 | 命令示例 | |
|---|---|---|
| 测试所有节点连通性 | ansible all -m ping |
|
| 批量安装 Nginx | ansible webservers -m yum -a "name=nginx state=present" |
|
| 批量启动 Nginx | ansible webservers -m service -a "name=nginx state=started enabled=yes" |
|
| 批量传文件 | ansible all -m copy -a "src=./a.txt dest=/tmp/" |
|
| 批量执行复杂命令 | `ansible all -m shell -a "ps aux | grep nginx"` |
| 查看 Playbook 语法 | ansible-playbook --syntax-check deploy.yml |
|
| 执行 Playbook | ansible-playbook deploy.yml |
|
| 查看被管理节点列表 | ansible all --list-hosts |
第 8 章:变量
在 Ansible Playbook 中,变量是实现 "代码复用、灵活配置、环境适配" 的核心机制------ 通过将可变信息(如软件版本、文件路径、端口号、主机参数等)抽象为变量,无需修改 Playbook 核心逻辑,即可适配不同环境、主机组或需求,大幅提升 Playbook 的通用性和可维护性。
简单说:变量让 Playbook 从 "写死配置" 变成 "动态适配",避免重复编写相似 Playbook,同时降低修改成本(比如修改服务端口时,只需改变量值,无需遍历所有任务)。
8.1、变量的核心作用(结合实际场景)
8.1.1. 统一配置,减少重复编写
将多个任务共用的参数(如软件版本、文件路径、端口)定义为变量,集中管理,避免 "一处修改需改多处" 的麻烦。
示例场景:部署 HTTPD 时,统一指定服务端口、配置文件路径、安装版本:
yaml
---
- name: Deploy HTTPD with variables
hosts: webservers
remote_user: root
vars: # 定义变量(集中管理)
httpd_port: 8080 # 服务监听端口
httpd_conf_src: /opt/httpd.conf # 本地配置文件路径
httpd_version: latest # 安装版本
tasks:
- name: Install HTTPD
yum:
name: httpd
state: "{{ httpd_version }}" # 引用变量({{ 变量名 }} 语法)
- name: Copy config file
copy:
src: "{{ httpd_conf_src }}"
dest: /etc/httpd/conf/httpd.conf
- name: Modify listen port (通过变量动态改配置)
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^Listen'
line: "Listen {{ httpd_port }}" # 引用端口变量
- 若后续需将端口改为 80,只需修改
httpd_port: 80,无需改所有关联任务。
8.1.2. 适配多环境 / 多主机组
不同环境(开发、测试、生产)或不同主机组(web、db)的配置可能不同,用变量可实现 "一套 Playbook 适配所有场景"。
示例场景:开发环境 HTTPD 用 8080 端口,生产环境用 80 端口:
yaml
---
- name: Deploy HTTPD across environments
hosts: "{{ target_hosts }}" # 外部传入主机组变量
remote_user: root
vars:
# 环境变量映射(按环境区分配置)
env_config:
dev: # 开发环境
httpd_port: 8080
httpd_conf_src: /opt/dev_httpd.conf
prod: # 生产环境
httpd_port: 80
httpd_conf_src: /opt/prod_httpd.conf
vars_files:
- ./secret_vars.yml # 从文件加载敏感变量(如密码,避免硬编码)
tasks:
- name: Install HTTPD
yum: name=httpd state=latest
- name: Copy environment-specific config
copy:
src: "{{ env_config[target_env].httpd_conf_src }}" # 按环境取配置
dest: /etc/httpd/conf/httpd.conf
- name: Set listen port
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^Listen'
line: "Listen {{ env_config[target_env].httpd_port }}"
-
执行时通过
-e传入环境变量,适配不同场景:bash
运行
# 部署开发环境(webservers_dev 主机组) ansible-playbook deploy_httpd.yml -e "target_hosts=webservers_dev target_env=dev" # 部署生产环境(webservers_prod 主机组) ansible-playbook deploy_httpd.yml -e "target_hosts=webservers_prod target_env=prod"
8.1.3. 引用目标主机的系统信息(事实变量)
Ansible 的 setup 模块会自动采集目标主机的系统信息(如 IP、操作系统、磁盘路径、CPU 核心数),这些信息以 "事实变量"(ansible_*)形式存在,可直接在 Playbook 中引用,实现 "按主机状态动态配置"。
示例场景 :根据目标主机的操作系统,选择不同的 HTTPD 包名(如 Debian 系叫 apache2,RHEL 系叫 httpd):
yaml
---
- name: Deploy HTTPD (cross-distribution)
hosts: webservers
gather_facts: true # 必须开启(默认开启),才能采集事实变量
remote_user: root
tasks:
- name: Install HTTPD on RHEL/CentOS
yum: name=httpd state=latest
when: ansible_os_family == "RedHat" # 引用事实变量:判断操作系统家族
- name: Install HTTPD on Debian/Ubuntu
apt: name=apache2 state=latest update_cache=yes
when: ansible_os_family == "Debian" # 适配不同系统
- 常用事实变量:
ansible_all_ipv4_addresses(主机 IP)、ansible_distribution(操作系统名称)、ansible_mounts(磁盘挂载信息)等。
8.1.4. 接收外部输入(动态传参)
执行 Playbook 时,通过 -e(--extra-vars)参数动态传入变量,无需修改 Playbook 即可灵活调整配置,适合临时变更需求。
示例场景:临时指定 HTTPD 版本进行安装:
yaml
# playbook.yml
---
- name: Install specified HTTPD version
hosts: webservers
remote_user: root
tasks:
- name: Install HTTPD {{ httpd_version }} # 引用外部传入的变量
yum:
name: "httpd-{{ httpd_version }}" # 拼接变量(如 httpd-2.4.6)
state: present
-
执行时传入版本变量: bash
运行
# 安装 2.4.6 版本 ansible-playbook playbook.yml -e "httpd_version=2.4.6" # 安装最新版本 ansible-playbook playbook.yml -e "httpd_version=latest"
8.1.5. 存储敏感信息(安全管理)
通过变量文件(如 vars_files)或 Ansible Vault 存储密码、密钥等敏感信息,避免硬编码到 Playbook 中,提升安全性。
示例场景:存储数据库密码(非加密,适合测试环境):
yaml
# secret_vars.yml(单独文件,不要提交到代码仓库)
db_user: root
db_password: "MySecurePass123"
# playbook.yml
---
- name: Connect to database
hosts: dbservers
remote_user: root
vars_files:
- ./secret_vars.yml # 加载敏感变量
tasks:
- name: Test database connection
command: "mysql -u {{ db_user }} -p{{ db_password }} -e 'select 1'"
-
生产环境建议用
ansible-vault加密敏感变量文件:bash
运行
# 加密文件 ansible-vault encrypt secret_vars.yml # 执行时解密(需输入密码) ansible-playbook playbook.yml --ask-vault-pass
8.2、变量的优先级(避免冲突)
Ansible 变量有明确的优先级(从高到低),优先级高的变量会覆盖优先级低的,需注意避免冲突:
- 命令行传入的变量(
-e参数)→ 最高优先级; - Playbook 中
vars_prompt(交互输入变量); - Playbook 中
vars定义的变量; - 变量文件(
vars_files); - 事实变量(
setup模块采集的ansible_*); - Inventory 中定义的主机 / 主机组变量;
- Ansible 配置文件(
ansible.cfg)中的变量 → 最低优先级。
8.3、变量的核心价值总结
| 作用 | 解决的问题 | 典型场景 |
|---|---|---|
| 统一配置 | 重复编写、多处修改麻烦 | 固定端口、文件路径、软件版本 |
| 多环境适配 | 一套 Playbook 适配开发 / 测试 / 生产 | 不同环境的配置文件、端口、主机组 |
| 动态引用主机信息 | 按主机状态差异化配置 | 跨操作系统安装、按硬件配置服务 |
| 外部动态传参 | 临时变更配置无需改 Playbook | 临时指定软件版本、开关功能 |
| 敏感信息管理 | 避免密码硬编码导致泄露 | 数据库密码、API 密钥 |
简单说:变量是 Playbook 的 "灵活开关",用好变量能让你的 Playbook 从 "一次性脚本" 升级为 "可复用、可扩展的自动化工具"。如果需要具体学习 "变量的定义方式"(如 Inventory 变量、角色变量)或 "变量的高级用法"(如循环变量、注册变量),可以告诉我!