前言
在当今的运维工作中,自动化已经成为提升效率、减少人为错误的关键手段。Ansible 作为一款开源的自动化工具,凭借其 无客户端架构(Agentless)、简洁易用的语法以及强大的跨平台能力,已经成为 DevOps 工程师和系统管理员的首选工具。
本文将从零开始,带你全面了解 Ansible 的安装、配置以及 Playbook 编写技巧,涵盖 copy、user、file、yum_repository、get_url、shell 等常用模块的详细讲解,并额外补充 yum、service、cron、template、script、command、group、authorized_key 等高频模块的使用方法。
一、Ansible 简介
1.1 什么是 Ansible?
Ansible 是一个基于 Python 编写的自动化平台,用于:
• 配置管理:集中化配置文件
• 应用部署:批量安装和部署软件
• 任务自动化:同时在多台主机上执行相同任务
1.2 Ansible 的核心特点
|
特点 |
说明 |
|
无客户端(Agentless) |
无需在被管理主机上安装代理软件,通过 SSH 即可管理 |
|
幂等性(Idempotent) |
多次执行结果一致,不会造成重复操作 |
|
YAML 语法 |
使用简洁的 YAML 格式编写 Playbook |
|
模块化设计 |
提供丰富的内置模块,支持自定义扩展 |
|
跨平台支持 |
支持 Linux、Windows、网络设备等 |
1.3 Ansible 的管理范围
┌─────────────────────────────────────────────────────────────┐
│ Ansible Control Node │
│ (控制节点 - Python) │
└──────────────────────┬──────────────────────────────────────┘
│ SSH / WinRM
┌──────────────┼──────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────────┐
│ Linux │ │ Windows │ │ Network │
│ Hosts │ │ Hosts │ │ Devices │
└─────────┘ └─────────┘ └─────────────┘
二、环境说明
在开始之前,我们需要了解本教程所使用的实验环境:
|
角色 |
主机名 |
IP 地址 |
说明 |
|
控制节点 |
control |
192.168.1.10 |
安装 Ansible,运行 Playbook |
|
被管理节点 |
node1 |
192.168.1.11 |
目标主机(prod 组) |
|
被管理节点 |
node2 |
192.168.1.12 |
目标主机(prod 组) |
|
负载均衡器 |
node3 |
192.168.1.13 |
目标主机(balancers 组) |
三、Ansible 安装与配置
3.1 安装 EPEL 仓库
Ansible 默认不在 CentOS/RHEL 的官方仓库中,需要先配置 EPEL 仓库:
// bash
sudo wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
3.2 安装 Ansible
为安全起见,建议使用普通用户而非 root 登录系统:
// bash
# 使用普通用户 wuge 登录控制节点
[wuge@control ~]$ sudo yum -y install ansible
# 验证安装
[wuge@control ~]$ ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/wuge/.ansible/plugins/modules']
python version = 3.6.8
3.3 配置 Ansible 工作环境
创建工作目录并复制配置文件:
// bash
[wuge@control ~]$ mkdir shixun && cd shixun/
[wuge@control shixun]$ cp /etc/ansible/ansible.cfg .
3.4 配置文件详解
编辑 ansible.cfg 文件,主要配置项如下:
// ini
[defaults]
inventory = ./inventory # 指定清单文件路径
remote_user = wuge # 远程连接用户名
ask_pass = False # 不询问密码(使用 SSH 密钥)
[privilege_escalation]
become = True # 启用权限提升
become_method = sudo # 使用 sudo 提权
become_user = root # 提权到 root 用户
become_ask_pass = False # 不询问 sudo 密码
最佳实践:
- 生产环境中建议使用 SSH 密钥认证,避免密码传输
- 权限提升使用 sudo,保持最小权限原则
- 配置文件应纳入版本控制
3.5 创建 Inventory 清单文件
Inventory 文件用于定义被管理主机和主机组:
// ini
[prod]
node1
node2
[balancers]
node3
[webservers:children]
prod
3.6 验证连通性
// bash
# 验证清单中定义的主机
[wuge@control shixun]$ ansible all --list-hosts
# 测试主机连通性(使用 ping 模块)
[wuge@control shixun]$ ansible all -m ping
四、Ad-hoc 临时命令
Ansible 支持两种运行方式:
1. Ad-hoc:单次命令执行,适合快速任务
2. Playbook:编写剧本,适合复杂任务
4.1 什么是 Ad-hoc?
Ad-hoc 是 Ansible 的临时命令模式,语法简洁,但不适合复杂场景:
// bash
ansible <主机或组> -m <模块名> -a <模块参数>
4.2 Ad-hoc 使用示例
// bash
# 在所有主机上执行 ping
ansible all -m ping
# 在 prod 组主机上查看内存使用
ansible prod -m command -a "free -h"
# 在所有主机上查看系统信息
ansible all -m setup
五、Ansible 核心模块详解
学习提示:每个模块都包含功能介绍、常用参数、Playbook 范文和 Ad-hoc 命令四种形式,方便读者全面理解和快速查阅。
5.1 copy 模块
功能介绍
copy 模块用于将文件从控制节点复制到被管理主机,支持文件属性设置(权限、所有者等)。
常用参数
|
参数 |
类型 |
说明 |
|
src |
路径 |
源文件路径(控制节点上) |
|
dest |
路径 |
目标路径(远程主机上) |
|
owner |
字符串 |
文件所有者 |
|
group |
字符串 |
文件所属组 |
|
mode |
权限 |
文件权限(如 0644、u+x) |
|
backup |
布尔 |
覆盖前是否备份(默认 no) |
|
content |
字符串 |
直接写入文件内容 |
|
remote_src |
布尔 |
是否从远程复制(默认 no) |
Playbook 使用范文
// yaml
---
- name: copy a file
hosts: all
tasks:
- name: copy testfile to all nodes
copy:
src: ./testfile
dest: /opt/testfile
owner: root
group: wuge
mode: 0444
Ad-hoc 命令范文
// bash
# 复制文件到远程主机
ansible all -m copy -a "src=./testfile dest=/opt/testfile owner=root group=wuge mode=0444"
# 直接写入内容到文件
ansible all -m copy -a "content='Hello Ansible' dest=/tmp/hello.txt"
5.2 user 模块
功能介绍
user 模块用于管理系统用户账户,包括创建、删除、修改用户属性。
常用参数
|
参数 |
类型 |
说明 |
|
name |
字符串 |
用户名(必选) |
|
uid |
整数 |
用户 UID |
|
groups |
列表 |
附加组(逗号分隔) |
|
append |
布尔 |
追加附加组而非替换(默认 no) |
|
comment |
字符串 |
用户描述/GECOS |
|
shell |
路径 |
用户登录 shell |
|
password |
字符串 |
用户密码(加密后) |
|
state |
字符串 |
present(创建)或 absent(删除) |
|
remove |
布尔 |
删除用户时是否删除家目录(默认 no) |
|
generate_ssh_key |
布尔 |
是否生成 SSH 密钥(默认 no) |
Playbook 使用范文
// yaml
---
- name: create a user
hosts: all
tasks:
- name: create a user zhangsan
user:
name: zhangsan
uid: 2234
groups: root,wuge
append: yes
comment: 'small zhangsan'
shell: /bin/bash
Ad-hoc 命令范文
// bash
# 创建用户
ansible all -m user -a "name=zhangsan uid=2234 groups=root,wuge append=yes comment='small zhangsan'"
# 删除用户(同时删除家目录)
ansible all -m user -a "name=zhangsan state=absent remove=yes"
5.3 file 模块
功能介绍
file 模块用于创建、删除文件、目录和符号链接,以及设置文件属性。
常用参数
|
参数 |
类型 |
说明 |
|
path |
路径 |
文件/目录路径(必选) |
|
state |
字符串 |
file(文件)、directory(目录)、link(链接)、absent(删除)、touch(创建空文件) |
|
src |
路径 |
源路径(创建链接时使用) |
|
owner |
字符串 |
文件所有者 |
|
group |
字符串 |
文件所属组 |
|
mode |
权限 |
文件权限 |
|
recurse |
布尔 |
递归设置属性(目录时使用) |
|
force |
布尔 |
强制创建链接(默认 no) |
Playbook 使用范文
// yaml
---
- name: file module examples
hosts: all
tasks:
# 创建目录
- name: create a directory
file:
path: /opt/mydir
state: directory
owner: wuge
group: wuge
mode: 0755
# 创建文件
- name: create an empty file
file:
path: /opt/myfile.txt
state: touch
mode: 0644
# 创建符号链接
- name: create a symbolic link
file:
src: /opt/testfile
dest: /opt/testfile_link
state: link
force: yes
# 删除文件/目录
- name: remove a directory
file:
path: /opt/mydir
state: absent
Ad-hoc 命令范文
// bash
# 创建目录
ansible all -m file -a "path=/opt/mydir state=directory owner=wuge mode=0755"
# 创建符号链接
ansible all -m file -a "src=/opt/testfile dest=/opt/testfile_link state=link"
# 创建空文件
ansible all -m file -a "path=/opt/myfile.txt state=touch"
# 删除文件/目录
ansible all -m file -a "path=/opt/mydir state=absent"
5.4 yum_repository 模块
功能介绍
yum_repository 模块用于管理 YUM/DNF 仓库配置文件,创建或删除 .repo 文件。
常用参数
|
参数 |
类型 |
说明 |
|
name |
字符串 |
仓库名称(必选) |
|
description |
字符串 |
仓库描述 |
|
baseurl |
字符串 |
仓库的基础 URL |
|
gpgcheck |
布尔 |
是否启用 GPG 检查(默认 yes) |
|
gpgkey |
URL |
GPG 密钥 URL |
|
enabled |
布尔 |
是否启用仓库(默认 yes) |
|
file |
字符串 |
仓库文件名(不含 .repo) |
|
state |
字符串 |
present(创建)或 absent(删除) |
Playbook 使用范文
// yaml
---
- name: configure yum repositories
hosts: all
tasks:
# 添加阿里云 EPEL 仓库
- name: add aliyun EPEL repository
yum_repository:
name: epel
description: Extra Packages for Enterprise Linux 7
baseurl: https://mirrors.aliyun.com/epel/7/x86_64/
gpgcheck: no
enabled: yes
# 添加自定义仓库
- name: add custom repository
yum_repository:
name: myrepo
description: My Custom Repository
baseurl: http://yum.example.com/custom/$releasever/$basearch/
gpgcheck: yes
gpgkey: http://yum.example.com/RPM-GPG-KEY-myrepo
enabled: yes
Ad-hoc 命令范文
// bash
# 添加 EPEL 仓库
ansible all -m yum_repository -a "name=epel description='EPEL YUM Repository' baseurl=https://mirrors.aliyun.com/epel/7/x86_64/ gpgcheck=no"
# 删除仓库
ansible all -m yum_repository -a "name=epel state=absent"
5.5 get_url 模块
功能介绍
get_url 模块用于从 HTTP、HTTPS、FTP 等 URL 下载文件到远程主机,支持校验和验证。
常用参数
|
参数 |
类型 |
说明 |
|
url |
字符串 |
下载地址(必选) |
|
dest |
路径 |
目标文件路径(必选) |
|
timeout |
整数 |
下载超时时间(秒) |
|
checksum |
字符串 |
校验和(格式:算法:校验值) |
|
mode |
权限 |
文件权限 |
|
owner |
字符串 |
文件所有者 |
|
group |
字符串 |
文件所属组 |
|
url_username |
字符串 |
HTTP 基本认证用户名 |
|
url_password |
字符串 |
HTTP 基本认证密码 |
|
force |
布尔 |
强制覆盖(默认 no) |
|
force_basic_auth |
布尔 |
强制使用基本认证(默认 no) |
Playbook 使用范文
// yaml
---
- name: download files using get_url
hosts: all
tasks:
# 下载 Nginx 官方 RPM 包
- name: download nginx rpm
get_url:
url: https://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.24.0-1.el7.ngx.x86_64.rpm
dest: /tmp/nginx.rpm
mode: 0644
# 下载文件并校验
- name: download with checksum verification
get_url:
url: https://example.com/software.tar.gz
dest: /opt/software.tar.gz
checksum: sha256:abc123...
# 下载需要认证的文件
- name: download from authenticated URL
get_url:
url: https://example.com/private/file.zip
dest: /opt/file.zip
url_username: myuser
url_password: mypassword
force_basic_auth: yes
Ad-hoc 命令范文
// bash
# 下载文件
ansible all -m get_url -a "url=https://example.com/file.tar.gz dest=/opt/file.tar.gz"
# 下载并校验
ansible all -m get_url -a "url=https://example.com/file.tar.gz dest=/opt/file.tar.gz checksum=sha256:abc123..."
5.6 shell 模块
功能介绍
shell 模块用于在远程主机上执行 Shell 命令,支持管道、重定向等 Shell 特性。
常用参数
|
参数 |
类型 |
说明 |
|
cmd |
字符串 |
要执行的命令(必选) |
|
executable |
路径 |
指定 Shell 程序(默认 /bin/sh) |
|
creates |
路径 |
如果文件存在则不执行 |
|
removes |
路径 |
如果文件存在则执行 |
|
chdir |
路径 |
执行前切换目录 |
|
warn |
布尔 |
是否发出警告(默认 yes) |
Playbook 使用范文
// yaml
---
- name: shell module examples
hosts: all
tasks:
# 使用管道组合命令
- name: check memory usage
shell: free -h | grep Mem
register: mem_info
- name: display memory info
debug:
var: mem_info.stdout
# 复杂的多行命令
- name: execute multi-line command
shell: |
cd /opt && \
tar -xzf app.tar.gz && \
mv app-v1.0 app-current
# 条件执行(文件不存在时)
- name: run script only if output file doesn't exist
shell: /opt/build.sh
args:
creates: /opt/output.log
Ad-hoc 命令范文
// bash
# 执行简单命令
ansible all -m shell -a "free -h"
# 组合命令
ansible all -m shell -a "df -h | grep -v tmpfs"
# 多行命令
ansible all -m shell -a "cmd='cd /opt && tar -xzf app.tar.gz'"
注意:shell 模块功能强大但需谨慎使用,优先考虑其他专用模块(如 copy、yum、service 等),因为专用模块具有幂等性,而 Shell 命令可能产生意外结果。
5.7 command 模块
功能介绍
command 模块用于在远程主机上执行简单命令,与 shell 模块类似,但不支持管道、重定向等 Shell 特性。
常用参数
|
参数 |
类型 |
说明 |
|
cmd |
字符串 |
要执行的命令(必选) |
|
creates |
路径 |
如果文件存在则不执行 |
|
removes |
路径 |
如果文件存在则执行 |
|
chdir |
路径 |
执行前切换目录 |
|
executable |
路径 |
指定可执行文件路径 |
Playbook 使用范文
// yaml
---
- name: command module examples
hosts: all
tasks:
# 查看文件内容
- name: cat file content
command: cat /etc/hostname
register: hostname_output
- name: display hostname
debug:
var: hostname_output.stdout
# 创建符号链接(需要完整路径)
- name: create symlink
command: ln -s /opt/app /usr/local/bin/app
args:
creates: /usr/local/bin/app
Ad-hoc 命令范文
// bash
# 执行简单命令
ansible all -m command -a "uptime"
# 查看系统版本
ansible all -m command -a "cat /etc/redhat-release"
5.8 yum / dnf 模块
功能介绍
yum 和 dnf 模块用于在 Red Hat 系列 Linux 发行版上安装、更新、删除软件包。
常用参数
|
参数 |
类型 |
说明 |
|
name |
字符串/列表 |
软件包名或包列表 |
|
state |
字符串 |
present(安装)、latest(最新版)、absent(删除) |
|
enablerepo |
字符串 |
启用的仓库 |
|
disablerepo |
字符串 |
禁用的仓库 |
|
install_root |
路径 |
安装根目录(用于 chroot) |
|
exclude |
字符串 |
排除的软件包 |
|
update_cache |
布尔 |
执行前更新缓存(默认 no) |
Playbook 使用范文
// yaml
---
- name: yum/dnf module examples
hosts: all
tasks:
# 安装单个软件包
- name: install nginx
yum:
name: nginx
state: present
# 安装多个软件包
- name: install multiple packages
yum:
name:
- httpd
- httpd-tools
- mod_ssl
state: present
# 安装最新版本
- name: update nginx to latest
yum:
name: nginx
state: latest
# 删除软件包
- name: remove nginx
yum:
name: nginx
state: absent
# 安装本地 RPM 包
- name: install rpm from local file
yum:
name: /opt/nginx.rpm
state: present
disablerepo: "*"
Ad-hoc 命令范文
// bash
# 安装软件包
ansible all -m yum -a "name=nginx state=present"
# 安装多个软件包
ansible all -m yum -a "name=httpd,httpd-tools state=present"
# 更新所有软件包
ansible all -m yum -a "name=* state=latest"
# 删除软件包
ansible all -m yum -a "name=nginx state=absent"
5.9 service / systemd 模块
功能介绍
service 和 systemd 模块用于管理系统服务,包括启动、停止、重启、启用开机自启等。
常用参数
|
参数 |
类型 |
说明 |
|
name |
字符串 |
服务名称(必选) |
|
state |
字符串 |
started、stopped、restarted、reloaded |
|
enabled |
布尔 |
开机自启(默认 no) |
|
daemon_reload |
布尔 |
重新加载 systemd(仅 systemd 模块) |
|
pattern |
字符串 |
进程匹配模式(用于检测状态) |
Playbook 使用范文
// yaml
---
- name: service/systemd module examples
hosts: all
tasks:
# 启动并启用服务(systemd)
- name: start and enable nginx
systemd:
name: nginx
state: started
enabled: yes
daemon_reload: yes
# 停止服务
- name: stop httpd service
systemd:
name: httpd
state: stopped
# 重启服务
- name: restart firewalld
systemd:
name: firewalld
state: restarted
# 使用 service 模块(旧版系统)
- name: start apache service
service:
name: httpd
state: started
enabled: yes
Ad-hoc 命令范文
// bash
# 启动并启用服务
ansible all -m systemd -a "name=nginx state=started enabled=yes"
# 停止服务
ansible all -m systemd -a "name=httpd state=stopped"
# 重启服务
ansible all -m systemd -a "name=nginx state=restarted"
5.10 cron 模块
功能介绍
cron 模块用于管理 crontab 定时任务,支持创建、删除、修改计划任务。
常用参数
|
参数 |
类型 |
说明 |
|
name |
字符串 |
任务描述(必选,用于标识任务) |
|
minute |
字符串 |
分钟(默认 *) |
|
hour |
字符串 |
小时(默认 *) |
|
day |
字符串 |
日期(默认 *) |
|
month |
字符串 |
月份(默认 *) |
|
weekday |
字符串 |
星期(默认 *) |
|
job |
字符串 |
要执行的命令 |
|
state |
字符串 |
present(创建)或 absent(删除) |
|
user |
字符串 |
指定用户 crontab(默认 root) |
|
special_time |
字符串 |
特殊时间:reboot、yearly、monthly、weekly、daily、hourly |
|
disabled |
布尔 |
禁用任务(注释掉) |
Playbook 使用范文
// yaml
---
- name: cron module examples
hosts: all
tasks:
# 每天凌晨 2 点执行备份脚本
- name: backup database daily at 2am
cron:
name: "Backup database"
minute: "0"
hour: "2"
job: "/opt/scripts/backup.sh"
state: present
user: root
# 每周一早上 6 点清理日志
- name: clean logs every Monday
cron:
name: "Clean old logs"
weekday: "1"
hour: "6"
minute: "0"
job: "find /var/log -name '*.log' -mtime +7 -delete"
state: present
# 系统重启后执行任务
- name: run script on reboot
cron:
name: "Run after reboot"
special_time: reboot
job: "/opt/scripts/startup.sh"
# 删除定时任务
- name: remove backup cron
cron:
name: "Backup database"
state: absent
# 禁用任务(注释掉)
- name: disable backup cron temporarily
cron:
name: "Backup database"
disabled: yes
Ad-hoc 命令范文
// bash
# 创建定时任务
ansible all -m cron -a "name='backup' minute=0 hour=2 job='/opt/backup.sh' state=present"
# 删除定时任务
ansible all -m cron -a "name='backup' state=absent"
# 查看定时任务
ansible all -m cron -a "name='backup'"
5.11 template 模块
功能介绍
template 模块用于生成配置文件,支持 Jinja2 模板语法,可以将变量动态写入配置文件。
常用参数
|
参数 |
类型 |
说明 |
|
src |
路径 |
模板文件路径(必选,相对于 templates 目录) |
|
dest |
路径 |
目标文件路径(必选) |
|
owner |
字符串 |
文件所有者 |
|
group |
字符串 |
文件所属组 |
|
mode |
权限 |
文件权限 |
|
validate |
字符串 |
复制前验证的命令(%s 替换目标文件) |
|
backup |
布尔 |
覆盖前备份(默认 no) |
Playbook 使用范文
**首先创建模板文件 templates/nginx.conf.j2:**
// jinja2
# Nginx configuration template
server {
listen {{ nginx_port }};
server_name {{ server_name }};
location / {
root {{ document_root }};
index index.html;
}
access_log {{ log_path }}/access.log;
error_log {{ log_path }}/error.log;
}
Playbook 文件:
// yaml
---
- name: deploy nginx configuration using template
hosts: webservers
vars:
nginx_port: 80
server_name: example.com
document_root: /var/www/html
log_path: /var/log/nginx
tasks:
- name: deploy nginx.conf
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/conf.d/example.conf
owner: root
group: root
mode: 0644
validate: nginx -t
backup: yes
Ad-hoc 命令范文
// bash
# 直接使用变量生成配置
ansible webservers -m template -a "src=templates/nginx.conf.j2 dest=/etc/nginx/conf.d/example.conf validate='nginx -t'"
5.12 script 模块
功能介绍
script 模块用于将本地脚本复制到远程主机并执行,非常适合执行复杂的 Shell 或 Python 脚本。
常用参数
|
参数 |
类型 |
说明 |
|
cmd |
字符串 |
本地脚本路径(必选) |
|
creates |
路径 |
如果文件存在则不执行 |
|
removes |
路径 |
如果文件存在则执行 |
|
chdir |
路径 |
执行前切换目录 |
|
executable |
路径 |
指定脚本解释器 |
Playbook 使用范文
**首先创建脚本文件 scripts/check_system.sh:**
// bash
#!/bin/bash
# Check system resources and log to file
LOG_FILE="/var/log/system_check.log"
echo "=== System Check $(date) ===" >> $LOG_FILE
echo "Memory:" >> $LOG_FILE
free -h >> $LOG_FILE
echo "" >> $LOG_FILE
echo "Disk:" >> $LOG_FILE
df -h >> $LOG_FILE
Playbook 文件:
// yaml
---
- name: execute local script on remote hosts
hosts: all
tasks:
- name: run system check script
script:
cmd: scripts/check_system.sh
creates: /var/log/system_check.log
register: script_output
- name: display script output
debug:
var: script_output.stdout_lines
Ad-hoc 命令范文
// bash
# 执行本地脚本
ansible all -m script -a "scripts/check_system.sh"
5.13 group 模块
功能介绍
group 模块用于管理系统用户组,支持创建和删除组。
常用参数
|
参数 |
类型 |
说明 |
|
name |
字符串 |
组名(必选) |
|
gid |
整数 |
组 GID |
|
state |
字符串 |
present(创建)或 absent(删除) |
|
system |
布尔 |
创建为系统组(gid < 1000) |
Playbook 使用范文
// yaml
---
- name: group module examples
hosts: all
tasks:
# 创建系统组
- name: create system group
group:
name: appserver
gid: 1000
system: yes
state: present
# 创建普通组
- name: create application group
group:
name: webapp
state: present
# 删除组
- name: remove group
group:
name: webapp
state: absent
Ad-hoc 命令范文
// bash
# 创建组
ansible all -m group -a "name=appserver gid=1000 state=present"
# 删除组
ansible all -m group -a "name=webapp state=absent"
5.14 authorized_key 模块
功能介绍
authorized_key 模块用于管理 SSH 授权密钥,将公钥添加到用户的 ~/.ssh/authorized_keys 文件中。
常用参数
|
参数 |
类型 |
说明 |
|
user |
字符串 |
用户名(必选) |
|
key |
字符串 |
公钥内容 |
|
key_opts |
列表 |
密钥选项(如 no-port-forwarding) |
|
state |
字符串 |
present(添加)或 absent(删除) |
|
path |
路径 |
指定 authorized_keys 文件路径 |
|
exclusive |
布尔 |
替换整个文件(默认 no) |
Playbook 使用范文
// yaml
---
- name: manage SSH authorized keys
hosts: all
tasks:
# 添加单个公钥
- name: add admin SSH key
authorized_key:
user: wuge
key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD... admin@workstation"
state: present
# 添加多个公钥(使用文件)
- name: add multiple keys for deploy user
authorized_key:
user: deploy
key: "{{ lookup('file', 'keys/jenkins.pub') }}"
key_opts: 'no-agent-forwarding,no-pty'
state: present
# 删除公钥
- name: remove old key
authorized_key:
user: wuge
key: "ssh-rsa AAAAB3NzaC1... old-key@oldmachine"
state: absent
# 替换所有密钥(清空后添加)
- name: set exclusive keys for admin
authorized_key:
user: admin
key: "{{ item }}"
exclusive: yes
with_file:
- keys/admin_key1.pub
- keys/admin_key2.pub
Ad-hoc 命令范文
// bash
# 添加公钥
ansible all -m authorized_key -a "user=wuge key='ssh-rsa AAAAB3NzaC1...'"
# 删除公钥
ansible all -m authorized_key -a "user=wuge key='ssh-rsa AAAAB3NzaC1...' state=absent"
5.15 mount 模块
功能介绍
mount 模块用于管理文件系统的挂载,包括挂载、卸载、永久挂载配置等。
常用参数
|
参数 |
类型 |
说明 |
|
path |
路径 |
挂载点路径(必选) |
|
src |
路径 |
设备或 NFS 路径(必选) |
|
fstype |
字符串 |
文件系统类型(必选) |
|
opts |
字符串 |
挂载选项 |
|
state |
字符串 |
mounted(挂载并写入 fstab)、unmounted(卸载)、present(仅写入 fstab)、absent(移除 fstab) |
|
boot |
布尔 |
是否在启动时挂载(默认 yes) |
Playbook 使用范文
// yaml
---
- name: mount module examples
hosts: all
tasks:
# 挂载 NFS 共享
- name: mount NFS share
mount:
path: /mnt/nfs
src: nfsserver:/share
fstype: nfs
opts: defaults,rw
state: mounted
# 挂载临时文件系统
- name: mount tmpfs
mount:
path: /mnt/ramdisk
src: tmpfs
fstype: tmpfs
opts: size=1G
state: mounted
# 卸载并移除 fstab 条目
- name: unmount and remove
mount:
path: /mnt/nfs
state: absent
Ad-hoc 命令范文
// bash
# 挂载 NFS
ansible all -m mount -a "path=/mnt/nfs src=nfsserver:/share fstype=nfs state=mounted"
# 卸载
ansible all -m mount -a "path=/mnt/nfs state=unmounted"
5.16 firewalld 模块
功能介绍
firewalld 模块用于管理 firewalld 防火墙规则,支持添加、删除端口和服务规则。
常用参数
|
参数 |
类型 |
说明 |
|
service |
字符串 |
服务名称(如 http、https) |
|
port |
字符串 |
端口/协议(如 80/tcp、443/tcp) |
|
permanent |
布尔 |
永久规则(默认 no) |
|
immediate |
布尔 |
立即生效(默认 no) |
|
state |
字符串 |
enabled 或 disabled |
|
zone |
字符串 |
firewalld 区域 |
|
rich_rule |
字符串 |
复杂规则 |
Playbook 使用范文
// yaml
---
- name: configure firewalld
hosts: all
tasks:
# 开放 HTTP 和 HTTPS 服务
- name: allow http and https
firewalld:
service: "{{ item }}"
permanent: yes
immediate: yes
state: enabled
loop:
- http
- https
# 开放自定义端口
- name: open custom port
firewalld:
port: 8080/tcp
permanent: yes
immediate: yes
state: enabled
# 关闭防火墙
- name: disable firewalld
firewalld:
state: stopped
permanent: no
immediate: yes
# 添加富规则(限制 IP 访问)
- name: allow limited access to mysql
firewalld:
rich_rule: 'rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept'
permanent: yes
immediate: yes
state: enabled
Ad-hoc 命令范文
// bash
# 开放端口
ansible all -m firewalld -a "port=80/tcp permanent=yes immediate=yes state=enabled"
# 开放服务
ansible all -m firewalld -a "service=http permanent=yes immediate=yes state=enabled"
六、综合实战案例
下面是一个完整的 LAMP 环境部署实战:
// yaml
---
- name: Deploy LAMP Stack
hosts: webservers
become: yes
vars:
db_root_password: "MySecurePass123"
document_root: /var/www/html
tasks:
# 安装软件包
- name: install LAMP packages
yum:
name:
- httpd
- mariadb-server
- mariadb
- php
- php-mysql
state: present
# 创建应用用户和组
- name: create app group
group:
name: app
state: present
- name: create app user
user:
name: appuser
group: app
shell: /bin/bash
create_home: yes
# 部署配置文件
- name: deploy httpd config
template:
src: templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
owner: root
group: root
mode: 0644
validate: /usr/sbin/httpd -t
notify: restart httpd
# 启动服务
- name: start and enable services
systemd:
name: "{{ item }}"
state: started
enabled: yes
loop:
- httpd
- mariadb
# 配置防火墙
- name: open firewall ports
firewalld:
service: "{{ item }}"
permanent: yes
immediate: yes
state: enabled
loop:
- http
- https
# 创建数据库
- name: create database
mysql_db:
name: myapp
state: present
- name: set mysql root password
mysql_user:
name: root
host: localhost
password: "{{ db_root_password }}"
priv: '*.*:ALL,GRANT'
state: present
# 创建测试页面
- name: deploy index page
copy:
content: |
<html>
<head><title>LAMP Deployed</title></head>
<body>
<h1>LAMP Stack Successfully Deployed!</h1>
<p>Server: {{ ansible_hostname }}</p>
<p>PHP Version: <?php echo phpversion(); ?></p>
</body>
</html>
dest: "{{ document_root }}/index.php"
owner: apache
group: apache
mode: 0644
handlers:
- name: restart httpd
systemd:
name: httpd
state: restarted
七、总结
7.1 模块对比速查表
|
模块 |
用途 |
适用场景 |
|
copy |
文件复制 |
分发配置文件 |
|
file |
文件/目录/链接管理 |
创建路径、修改权限 |
|
template |
动态配置生成 |
生成含变量的配置文件 |
|
script |
执行本地脚本 |
复杂 Shell/Python 任务 |
|
command |
执行简单命令 |
单次命令执行 |
|
shell |
执行复杂命令 |
含管道、重定向的命令 |
|
yum/dnf |
包管理 |
安装/更新/删除软件 |
|
service/systemd |
服务管理 |
启动/停止/重启服务 |
|
user/group |
账户管理 |
创建/删除用户和组 |
|
authorized_key |
SSH 密钥管理 |
管理 SSH 公钥 |
|
cron |
定时任务 |
计划任务 |
|
get_url |
文件下载 |
HTTP/FTP 下载 |
|
mount |
挂载管理 |
挂载文件系统 |
|
firewalld |
防火墙管理 |
配置防火墙规则 |
|
yum_repository |
仓库管理 |
添加/删除 YUM 仓库 |
7.2 学习建议
1. 从 Ad-hoc 开始:先用临时命令熟悉模块的用法
2. **善用 ansible-doc**:查看模块详细文档(ansible-doc <module_name>)
3. 幂等性优先:优先使用专用模块,而非 Shell 命令
4. 版本控制:将 Playbook 和 Inventory 纳入 Git 管理
5. 测试环境验证:生产环境部署前先在测试环境验证
7.3 进阶方向
• 学习 Ansible Galaxy 使用和角色编写
• 掌握 Ansible Vault 加密敏感信息
• 了解 Ansible Tower/AWX 企业级管理平台
• 实践 动态 Inventory 与 CMDB 集成
📌 本文首发于CSDN,转载需注明出处。
💬 如有疑问或补充,欢迎评论区交流!
👍 觉得有用请点赞、收藏、关注,支持作者创作更多优质内容~

318

被折叠的 条评论
为什么被折叠?



