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  # 重启后等待时间

相关推荐
虾..2 小时前
Linux 多线程,线程分离
linux·运维·服务器
云飞云共享云桌面2 小时前
推荐一些适合10个SolidWorks设计共享算力的服务器硬件配置
运维·服务器·前端·数据库·人工智能
DO_Community2 小时前
如何选择对象存储?Amazon S3 与 DigitalOcean Spaces 深度解析
运维·服务器·ai·aws·对象存储·云服务·金融科技
ZCXZ12385296a2 小时前
物流自动化环境下的纸箱检测与识别_YOLO13-SEG-REPVGGOREPA模型应用
运维·自动化
2401_832298102 小时前
安卓证书在线生成,一键签名・安全高效
运维
蜡笔小炘2 小时前
LVS -- 部署DR模式集群案例
运维·服务器·lvs
成都极云科技3 小时前
成都GPU服务器托管 - 成都服务器idc托管
运维·服务器
AZ996ZA3 小时前
自学linux的二十天【DNS 服务从入门到实战】
linux·运维·服务器
这个软件需要设计一下3 小时前
ninedata安装磁盘不足问题解决
运维·bug