Ansible 多 Play 编写与模块使用全解析

目录

[一、多 Play Playbook管理服务器](#一、多 Play Playbook管理服务器)

[什么是多 Play Playbook?](#什么是多 Play Playbook?)

基本结构示例

关键点

二、用户和权限:谁在做什么?

[1. 连接用户配置层级](#1. 连接用户配置层级)

[2. 权限提升控制](#2. 权限提升控制)

[3. 实际场景示例](#3. 实际场景示例)

[三、Ansible 模块宝库:找到合适的工具](#三、Ansible 模块宝库:找到合适的工具)

常用模块分类速查

文件管理模块

软件包管理模块

系统管理模块

如何查找和使用模块

四、执行命令模块:最后的备用方案

三个命令模块的区别

如何安全使用命令模块

[五、YAML 语法细节:写出优雅的 Playbook](#五、YAML 语法细节:写出优雅的 Playbook)

[1. 注释的写法](#1. 注释的写法)

[2. 字符串的多种写法](#2. 字符串的多种写法)

[3. 列表和字典的格式](#3. 列表和字典的格式)

[4. 任务格式的选择](#4. 任务格式的选择)


一、多 Play Playbook管理服务器

什么是多 Play Playbook?

想象一下你要部署一个完整的 Web 应用,需要:

  1. 先在数据库服务器上安装和配置 MySQL

  2. 然后在 Web 服务器上部署应用代码

  3. 最后在负载均衡器上配置转发规则

这就是多 Play Playbook 的用武之地!一个 Playbook 可以包含多个 Play,每个 Play 针对不同的主机组执行不同的任务。

基本结构示例

bash 复制代码
---
# Playbook:部署完整的博客系统

# 第一个 Play:配置数据库服务器
- name: 配置MySQL数据库服务器
  hosts: db_servers          # 针对数据库服务器组
  tasks:
    - name: 安装MySQL服务器
      ansible.builtin.dnf:
        name: mysql-server
        state: present
    
    - name: 初始化数据库
      ansible.builtin.mysql_db:
        name: blogdb
        state: present

# 第二个 Play:配置Web应用服务器
- name: 部署Web应用程序
  hosts: web_servers         # 针对Web服务器组
  tasks:
    - name: 安装PHP环境
      ansible.builtin.dnf:
        name: [php, php-mysql, httpd]
        state: present
    
    - name: 部署博客代码
      ansible.builtin.copy:
        src: ./blog-code/
        dest: /var/www/html/

# 第三个 Play:配置负载均衡器
- name: 配置Nginx负载均衡
  hosts: lb_servers          # 针对负载均衡器组
  tasks:
    - name: 安装Nginx
      ansible.builtin.dnf:
        name: nginx
        state: latest
    
    - name: 配置负载均衡
      ansible.builtin.copy:
        src: ./nginx-config.conf
        dest: /etc/nginx/nginx.conf

关键点

  • 顺序执行:Ansible 按顺序执行每个 Play

  • 独立配置:每个 Play 可以有完全不同的配置

  • 灵活组合:可以针对不同环境(开发、测试、生产)编写不同的 Play


二、用户和权限:谁在做什么?

1. 连接用户配置层级

Ansible 决定使用哪个用户连接服务器的优先级(从高到低):

bash 复制代码
# 第1优先级:主机或组变量
# 在 inventory 或变量文件中设置
[web_servers]
web01.example.com ansible_user=app_deploy

# 第2优先级:Play 中的 remote_user
- name: 以特定用户执行任务
  hosts: web_servers
  remote_user: app_deploy    # 覆盖默认用户
  tasks: ...

# 第3优先级:ansible.cfg 中的配置
[defaults]
remote_user = ansible_user   # 全局默认用户

# 第4优先级:默认值
# ansible-navigator: root
# ansible-playbook: 当前执行用户

2. 权限提升控制

权限提升(比如使用 sudo)可以在不同层级控制:

bash 复制代码
---
# 全局启用(ansible.cfg中)
[privilege_escalation]
become = true
become_method = sudo
become_user = root

# Play 级别覆盖
- name: 以非root用户部署应用
  hosts: app_servers
  remote_user: deploy_user
  become: true               # 需要时提升权限
  become_user: app_user      # 提升到app_user,不是root
  tasks:
    - name: 创建应用目录
      ansible.builtin.file:
        path: /opt/myapp
        state: directory
        owner: app_user
        mode: '0755'

- name: 执行系统级配置
  hosts: all
  remote_user: admin
  become: true               # 提升到root
  become_method: sudo
  tasks:
    - name: 更新系统
      ansible.builtin.dnf:
        name: "*"
        state: latest

3. 实际场景示例

bash 复制代码
---
# 场景:混合权限需求

# Play 1:普通用户执行,无需特权
- name: 拉取应用代码
  hosts: dev_servers
  remote_user: developer
  become: false              # 明确禁用权限提升
  tasks:
    - name: 从Git拉取代码
      ansible.builtin.git:
        repo: https://github.com/company/app.git
        dest: /home/developer/app
        version: main

# Play 2:需要root权限的系统配置
- name: 系统环境配置
  hosts: dev_servers
  remote_user: developer
  become: true               # 需要时使用sudo
  become_method: sudo
  become_user: root
  tasks:
    - name: 安装系统依赖
      ansible.builtin.dnf:
        name: [gcc, make, python3-devel]
        state: present

三、Ansible 模块宝库:找到合适的工具

常用模块分类速查

文件管理模块
bash 复制代码
# 1. copy - 复制文件
- name: 复制配置文件
  ansible.builtin.copy:
    src: configs/app.conf
    dest: /etc/myapp/app.conf
    owner: appuser
    mode: '0644'

# 2. file - 管理文件和目录
- name: 创建日志目录
  ansible.builtin.file:
    path: /var/log/myapp
    state: directory
    owner: appuser
    group: appuser
    mode: '0755'

# 3. lineinfile - 管理文件中的行
- name: 配置时区
  ansible.builtin.lineinfile:
    path: /etc/sysconfig/clock
    line: 'ZONE="Asia/Shanghai"'
    regexp: '^ZONE='
软件包管理模块
bash 复制代码
# 1. dnf - RHEL 8+ 系统
- name: 安装Web服务器
  ansible.builtin.dnf:
    name: [nginx, php-fpm, mysql-client]
    state: present

# 2. package - 自动检测包管理器
- name: 跨平台安装curl
  ansible.builtin.package:
    name: curl
    state: present

# 3. pip - Python包管理
- name: 安装Python依赖
  ansible.builtin.pip:
    name:
      - django
      - requests
    state: latest
系统管理模块
bash 复制代码
# 1. service - 服务管理
- name: 启动并启用服务
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: true

# 2. user - 用户管理
- name: 创建应用用户
  ansible.builtin.user:
    name: appuser
    uid: 1001
    group: appgroup
    shell: /bin/bash

# 3. firewalld - 防火墙管理
- name: 开放Web端口
  ansible.posix.firewalld:
    service: http
    permanent: true
    state: enabled
    immediate: yes

如何查找和使用模块

bash 复制代码
# 1. 浏览所有可用的集合和模块
ansible-navigator collections

# 2. 查看特定模块的详细文档
ansible-navigator doc ansible.builtin.copy -m stdout

# 3. 查看模块的简短用法摘要(很好的起点)
ansible-navigator doc ansible.builtin.service -s

四、执行命令模块:最后的备用方案

三个命令模块的区别

bash 复制代码
# 1. command - 最简单,不支持shell特性
- name: 运行简单命令
  ansible.builtin.command:
    cmd: /usr/local/bin/setup.sh
  # 缺点:不支持管道、重定向、环境变量

# 2. shell - 支持完整的shell功能
- name: 运行shell命令
  ansible.builtin.shell:
    cmd: |
      cd /opt/app &&
      source venv/bin/activate &&
      python manage.py migrate
  # 支持:管道、重定向、环境变量、多命令

# 3. raw - 最底层,绕过Ansible模块系统
- name: 在没有Python的系统上运行命令
  ansible.builtin.raw:
    cmd: yum install -y python3
  # 用于:网络设备、安装Python、特殊情况

注:不推荐这种用法,因为他没有幂等性

如何安全使用命令模块

重要原则:尽量使用专用模块,命令模块是最后的选择!

bash 复制代码
# ❌ 不好的做法:非幂等的shell命令
- name: 添加用户(非幂等)
  ansible.builtin.shell:
    cmd: useradd -m appuser
  # 问题:第二次运行会失败(用户已存在)

# ✅ 好的做法:使用专用模块
- name: 确保用户存在(幂等)
  ansible.builtin.user:
    name: appuser
    state: present
  # 优点:可以安全地多次运行

# ⚠️ 必要时:使命令模块尽量幂等
- name: 初始化数据库(如果不存在)
  ansible.builtin.command:
    cmd: /opt/bin/initdb.sh
    creates: /var/lib/mysql/ibdata1
  # creates参数:文件存在则跳过

- name: 清理临时文件(如果存在)
  ansible.builtin.command:
    cmd: rm -rf /tmp/oldcache
    removes: /tmp/oldcache
  # removes参数:文件不存在则跳过

五、YAML 语法细节:写出优雅的 Playbook

1. 注释的写法

bash 复制代码
---
# 这是整个Playbook的标题
# 部署生产环境博客系统

- name: 配置数据库服务器
  # 这个Play会先执行
  hosts: db_servers
  vars:
    db_name: blog_prod      # 生产环境数据库名
    db_user: blog_admin     # 数据库管理员用户
  
  tasks:
    - name: 安装MySQL服务器
      ansible.builtin.dnf:
        name: mysql-server
        state: latest       # 使用最新版本

2. 字符串的多种写法

bash 复制代码
# 普通字符串(大多数情况)
name: 我的应用配置
path: /opt/myapp

# 带特殊字符需要引号
error_message: "错误:文件 'config.yaml' 不存在"
sql_query: 'SELECT * FROM users WHERE status="active"'

# 多行字符串的两种方式
config_content: |
  server {
    listen 80;
    server_name example.com;
    root /var/www/html;
  }  # 保留换行符

description: >
  这是一个很长的描述,
  会被折叠成一行,
  在空格处换行只是为了可读性。

3. 列表和字典的格式

bash 复制代码
# 列表的推荐写法(垂直)
packages:
  - nginx
  - php-fpm
  - mysql-client
  - python3-pip

# 字典的推荐写法(垂直)
app_config:
  name: "博客系统"
  version: "2.1.0"
  port: 8080
  debug: false

# 不推荐的紧凑写法(除非必要)
packages: [nginx, php-fpm, mysql-client, python3-pip]
app_config: {name: "博客系统", version: "2.1.0", port: 8080, debug: false}

4. 任务格式的选择

bash 复制代码
# ❌ 不推荐的简写格式(旧式)
tasks:
  - name: 启动服务
    ansible.builtin.service: name=nginx state=started enabled=true

# ✅ 推荐的完整格式(易读易维护)
tasks:
  - name: 启动并启用Nginx服务
    ansible.builtin.service:
      name: nginx
      state: started
      enabled: true
      # 可以轻松添加更多参数
      sleep: 5  # 重启后等待时间

相关推荐
05大叔10 分钟前
网络基础知识 域名,JSON格式,AI基础
运维·服务器·网络
安当加密13 分钟前
无需改 PAM!轻量级 RADIUS + ASP身份认证系统 实现 Linux 登录双因子认证
linux·运维·服务器
dashizhi201514 分钟前
服务器共享禁止保存到本地磁盘、共享文件禁止另存为本地磁盘、移动硬盘等
运维·网络·stm32·安全·电脑
卷福同学1 小时前
【养虾日记】QClaw操作浏览器自动化发文
运维·人工智能·程序人生·自动化
woho7788992 小时前
不同网段IP的网络打印机,打印、扫描设置
运维·服务器·网络
耗子会飞2 小时前
小白学习固定VM虚拟机的centos服务器的IP
运维·服务器·centos
门豪杰2 小时前
Ubuntu下安装Claude Code
linux·运维·ubuntu·claude·claude code
新新学长搞科研3 小时前
第五届电子、集成电路与通信技术国际学术会议(EICCT 2026)
运维·人工智能·自动化·集成测试·信号处理·集成学习·电气自动化
桌面运维家3 小时前
Windows/Linux双启动:BIOS/UEFI多配置桌面创建指南
linux·运维·windows
無法複制3 小时前
debian安装Postgresql-14.x
运维·postgresql·debian