编写和运行 Playbook

编写和运行 Playbook

Playbook 介绍

adhoc 命令可以作为一次性命令对一组主机运行一项简单的任务。不过,若要真正发挥Ansible的能力,需要使用功能 playbook。

playbook 是一个文本文件,其中包含由一个或多个按特定顺序运行的play组成的列表。play是针对清单中选定的主机运行的一组有序任务。play可以让您将一系列冗长而复杂的手动管理任务转变为可轻松重复的例程,并且具有可预测性。

在 playbook 中,您可以将play内的任务序列保存为人类可读并可立即运行的形式。根据任务的编写方式,任务本身记录了部署应用或基础架构所需的步骤。

ad hoc 命令示例:

[root@controller ~ 15:54:05]# ansible -m user -a "name=new

Playbooks以yaml格式编写,通常以 yaml 和 yml 扩展名保存。

改写成playbook:

---
- name: Configure important user consistently
  hosts: node1
  tasks:
    - name: newbie exists with UID 4000
      user:
        name: newbie
        uid: 4000
        state: present
...
  1. - name: Configure important user consistently
    • 这是一个 Play 的起始行,-表示这是列表中的一个项
    • name参数用于给这个 Play 定义一个描述性名称,说明该 Play 的功能是 “持续标准化配置重要用户”
  2. hosts: node1
    • hosts参数指定该 Play 要在哪些目标主机上执行
    • 这里设置为node1,表示只在名为node1的主机上运行后续任务
    • 缩进表示这是上一行 Play 的属性
  3. tasks:
    • tasks关键字标志着任务列表的开始
    • 后续缩进的内容都是要在目标主机上执行的具体任务
    • 缩进表示这是上一行 Play 的属性
  4. - name: newbie exists with UID 4000
    • -表示这是任务列表中的一个任务
    • name参数给这个具体任务定义名称,说明任务是 “确保 newbie 用户存在且 UID 为 4000”
    • 比上一行多一级缩进,表示这是tasks列表中的项
  5. user:
    • 指定该任务要使用的 Ansible 模块为user模块(用于管理系统用户)
    • 缩进表示这是上一行任务的属性
  6. name: newbie
    • nameuser模块的参数,指定要操作的用户名为newbie
    • 缩进表示这是user模块的参数
  7. uid: 4000
    • uiduser模块的参数,指定该用户的 UID(用户 ID)为 4000
    • 缩进表示这是user模块的参数
  8. state: present
    • stateuser模块的参数,present表示确保该用户存在(如果不存在则创建)
    • 缩进表示这是user模块的参数
  9. ...
    • YAML 格式中,...表示文档结束符,是可选的结束标记

yaml格式只使用空格缩进,对于空格的数量没有强制要求。

基本规则:

  • 同一级别的元素,使用相同的缩进。
  • 对于子项目,使用比父项目更多的缩进。
  • 增加空白行,提高可读性。

Vim 编辑器设置

如果使用vim编辑器,设置vim环境便于编辑Playbooks。

在$HOME/.vimrc文件中添加以下内容:

set ai ts=2

效果:

  • “ai”,即 “autoindex”,表示自动缩进。
  • “ts”,即 “tabstop”,表示tab键使用2个空格代替。
  • autocmd FileType yam,代表文件类型是yaml时,自动执行“set ai ts=2”。

Playbook 编写

Playbook 示例

playbook.yaml 内容如下:

# yaml格式起始行,一般不省略
---

# Playbook中第一个play
# play具有属性:name,hosts,become,tasks,缩进一致
# name属性,用于简要描述play
- name: Enable intranet services
  
  # hosts属性,用于定义要在哪个受管理节点执行
  hosts: node1
  
  # tasks属性,用于描述play中任务,属性是列表格式
  tasks:
    
    # 第一个任务
    # 任务具有属性:涵name和模块名等。
    # name属性,用于简要描述任务
    - name: latest version of httpd and firewalld installed
      
      # 指明模块名,也就是要执行的任务
      yum:
        
        # 执行要操作的rpm包名称
        name:
          # rpm包名称是-开头的列表格式,或者逗号分隔的列表格式
          - httpd
          - firewalld
        
        # 定义软件包的状态,lastet代表升级为最新版本
        state: latest
    
    # 第二个任务
    - name: test html page is installed
      # copy模块,用于将content属性值写入到目标文件
      copy:
        content: "Welcome Laoma WebSite!\n"
        dest: /var/www/html/index.html
    
    # 第三个任务
    - name: firewalld enabled and running
      # service模块,用于启用并启动firewalld服务
      service:
        name: firewalld
        enabled: true
        state: started
    
    # 第四个任务
    - name: firewalld permits access to httpd service
      # firewalld,用于放行http服务
      firewalld:
        service: http
        permanent: true
        state: enabled
        immediate: yes
    
    # 第五个任务
    - name: httpd enabled and running
      # service模块,用于启用并启动httpd服务
      service:
        name: httpd
        enabled: true
        state: started

# Playbook中第二个play,-开头表示列表
- name: Test intranet web server
  hosts: localhost
  become: no
  tasks:
    - name: connect to intranet web server
      # uri模块,用于测试网站是否可以访问
      uri:
        url: http://node1
        return_content: yes
        status_code: 200

# yaml格式结束行,一般省略
...
YAML 注释

在 YAML中, 编号或井号符号(#)右侧的所有内容都是注释。如果注释的左侧有内容, 请在该编号符号的前面加一个空格。注释可用于提高可读性。

YAML 单行字符串

YAML中的字符串通常不需要放在引号里,即使字符串中包含空格。

字符串也可以用双引号或单引号括起。

YAML 多行字符串
  • 可以使用竖线(I)字符表示,保留字符串中的换行字符。

  • 也可以使用大于号(>)字符表示换行字符。执行时换行符使用空格代替,并且行内的引导空白将被删除。

YAML 字典

可以把 YAML 字典想象成一个 “多层抽屉柜”:

  • 最外层是一个大柜子(整个 YAML 文档),柜子上贴着标签(键),比如 “person”“company”。
  • 打开柜子,里面可能有小抽屉(子字典),每个小抽屉也有自己的标签,比如 “person” 柜子里有 “name”“age” 抽屉。
  • 每个抽屉里装着具体的东西(值):“name” 抽屉里放着 “Alice”,“age” 抽屉里放着 “30”。
  • 要是某个抽屉标签后面跟着 “:” 再换行缩进,就像 “拉开抽屉看到里面还有小格子”,比如 “address” 抽屉里还有 “city”“street” 这些更小的格子。

一组键值对的集合,又称为映射(mapping)和哈希(hashes)。

以缩进块的形式编写键值对集合,如下方所示:user属性是字典格式,是多个键值对集合。

user:
  name: laoma 
  uid: 1088
  state: absent

字典也可以使用以花括号括起的内联块格式编写,如下方所示:

user: {name: laoma, uid: 1088, state: absent}

YAML 字典的基本语法规则:

  • 键和值之间用冒号 : 分隔,冒号后必须有空格(key: value
  • 通常使用缩进来表示层级关系(推荐 2 个空格,不建议用制表符)
  • 字典可以嵌套,形成复杂的数据结构

基础示例

# 简单字典
person:
  name: Alice
  age: 30
  is_student: false

等价于 Python 字典:

{
  "person": {
    "name": "Alice",
    "age": 30,
    "is_student": False
  }
}

行内式字典

也可以在一行内定义字典,用花括号 {} 包裹,键值对之间用逗号 , 分隔:

person: { name: Bob, age: 25, is_student: true }

嵌套字典

字典的值可以是另一个字典,形成多层结构:

company:
  name: Tech Corp
  address:
    city: Beijing
    street: Main Road 123
    zipcode: 100000
  departments:
    - name: HR
      count: 5
    - name: IT
      count: 20

(注:- 表示列表项,字典可以和列表结合使用)

在 Ansible 中的应用

你之前看到的 Ansible Playbook 就是典型的 YAML 字典结构:

- name: Configure user  # 列表项(Play)
  hosts: node1         # Play 的键值对
  tasks:               # Play 的键值对,值是一个列表
    - name: Create user  # 任务列表项
      user:              # 任务的键,值是一个字典
        name: newbie     # user 模块的参数(键值对)
        uid: 4000

这里的 hosts: node1user: {name: newbie, uid: 4000} 都是字典键值对的体现。

YAML 字典的核心是 “键值对应”,通过缩进和冒号来清晰表达数据之间的关系,这也是它在配置文件(如 Ansible、Docker Compose 等)中被广泛使用的原因

YAML 列表

一组按次序排列的值,又称为序列(sequence)和数组(array)。

以缩进块的形式编写的键值对集合,如下方所示:

- name: latest version of httpd and firewalld installed
  yum:
    name:
      - httpd
      - firewalld
    state: latest
- name: test html page is installed
  copy:
    content: "Welcome to the example.com intranet!\n"
    dest: /var/www/html/index.html

以上有两个任务,每个任务都是多个键值对描述。其中yum模块操作的软件包是一个简单的名称列表。

内联格式:

name: [httpd, firewalld]

尽量避免内联格式。

可以把 YAML 列表想象成 “一串带编号的收纳盒”,或者 “排队的队伍”—— 每个盒子 / 队伍里的人都是独立的,但都属于同一串 / 同一队,没有专属名字(不像字典的 “键”),只能靠 “位置” 来区分。

比如你去超市买水果,装了一袋苹果、一串葡萄、一个橙子,这袋水果就是一个列表:里面每样水果都是独立项,按顺序排着,要找葡萄就知道是 “袋子里的第二个”。

1. 基础样子:用 “-” 开头的 “队伍”

YAML 里用 - (减号 + 空格)表示列表里的一个项,所有项对齐缩进,就像队伍站成一列:

# 水果列表
fruits:
  - apple  # 第1项:苹果
  - grape  # 第2项:葡萄
  - orange # 第3项:橙子

就像在 “fruits” 这个袋子里,按顺序放了苹果、葡萄、橙子三个独立的水果,没有谁属于谁,只是 “凑在一起的一组东西”。

2. 列表里也能装 “抽屉柜”(嵌套字典)

列表的每个项不只能是简单的文字,还能装之前说的 “字典抽屉柜”。比如记录几个人的信息,每个人都是一个 “抽屉柜”,再把这些 “抽屉柜” 排成一队:

# 人员列表(每个项是一个字典)
people:
  - name: Alice  # 第1个人的抽屉柜
    age: 30
  - name: Bob    # 第2个人的抽屉柜
    age: 25
  - name: Charlie# 第3个人的抽屉柜
    age: 35

这就像 “people” 这个队伍里,站了三个带抽屉的人:第一个人(Alice)的抽屉里有 “name”“age”,第二个人(Bob)也有自己的抽屉,互不干扰,只按排队顺序区分。

3. 一行写完的 “紧凑队伍”

如果列表项少,也能像 “挤在一起排队” 一样写在一行,用方括号 [] 把所有项包起来,项之间用逗号隔开:

# 一行式列表
colors: [red, green, blue]  # 相当于:- red; - green; - blue

4. 在 Ansible 里的实际用法

你之前看的 Playbook 里,tasks 就是一个列表 —— 要执行的多个任务,按顺序排成一队:

tasks:
  - name: 确保newbie用户存在  # 第1个任务(列表项)
    user:
      name: newbie
  - name: 给newbie加sudo权限  # 第2个任务(列表项)
    copy:
      src: sudoers.d/newbie
      dest: /etc/sudoers.d/

这就像 “任务清单”,先做 “创建用户”,再做 “加 sudo 权限”,按列表顺序一个接一个执行,没有跳过的道理。

总结来说,YAML 列表的核心就是 “按顺序排的一组东西”,不管里面装的是简单文字,还是复杂的 “字典抽屉柜”,都靠 - 标识 “这是队伍里的一个”,靠顺序确定 “先谁后谁”。

Playbook 运行

[yy@controller ~ 16:16:47 web]$ ansible-playbook playbook.yaml

第一次执行剧本,任务状态全是黄色。

第二次执行剧本,任务状态全是绿色。

语法检查

选项–syntax-check,只检查剧本语法,不执行剧本。

ansible-playbook playbook.yaml --syntax-check
空运行

空运行,是指模拟运行,并不是真正执行。

ansible-playbook playbook.yaml -C
提高输出详细程度
  • -v,显示任务结果。一般情况使用 -v 即可。
  • -vv,任务结果和任务配置都会显示。
  • -vvv,包含关于与受管主机连接的信息。
  • -vvvv,增加了连接插件相关的额外详细程度选项,包括受管主机上用于执行脚本的用户,以及所执行的脚本。

Playbook 提权

在playbook中指定此关键字将覆盖/etc/ansible/ansible.cfg文件中的设置特权升级属性

  • remote_user,指定ssh用户

  • become,启用或禁用特权升级

  • become_method,启用特权升级的方法

  • become_user,特殊升级的帐户

---
- name: Enable intranet services
  hosts: node1
  
  remote_user: laoma
  become: true
  become_method: sudo
  become_user: root
  
  tasks:
    - name: latest version of httpd and firewalld installed
      yum:
        name:
          - httpd
          - firewalld
        state: latest

在 Ansible 中,Playbook 提权主要是通过become关键字来实现的,它可以让任务以另一个用户(通常是root)的身份执行。以下是具体的提权方法:

  • 任务级提权:只在需要提权的任务上加上become: yes。例如:
- name: 需要root权限的任务
  copy:
    src: app.conf
    dest: /etc/app.conf
  become: yes
  • Play 级提权:在hosts同级加上become: yes,则这个 Play 里的所有任务都会默认提权。示例如下:
- name: 提权示例
  hosts: all
  become: yes
  tasks:
    - name: 安装软件包
      apt:
        name: nginx
        state: present
  • 命令行提权:运行 playbook 时加上-b--become参数,优先级最高,可以临时强制提权,适合调试或一次性任务。如ansible -playbook my_playbook.yml --become

此外,还有一些与提权相关的指令:

  • become_method:用于指定提权方法,默认是sudo。对于 Windows 系统是runas,网络设备(交换机、路由器等)是enable,容器则可使用machinectl。例如,当管理网络设备时,需设置become_method: enable
  • become_flags:可给提权命令添加额外参数。比如使用su命令提权时,若需要切换环境变量,可设置become_flags: '--login'
  • --ask - become - pass-K:运行 playbook 时,如果提权需要输入密码,可用这个参数让 Ansible 提示输入密码,以确保安全。

想象一下,Ansible Playbook 就像一个 “办事员”,平时只能做些普通权限的活儿(比如整理自己抽屉里的文件)。但有时候需要处理重要文件(比如修改系统配置、安装软件),这些活儿普通权限干不了,得有 “管理员” 身份才行。

“提权” 就像是给这个办事员开了张 “临时通行证”:

  • 任务级提权:就像特定事情才亮通行证 —— 比如 “只有给 /etc 目录拷贝文件时,才用管理员身份”
  • Play 级提权:相当于全天通行证 ——“今天所有活儿都用管理员身份干”
  • 命令行提权:好比临时加急授权 ——“这次特殊情况,强制用管理员身份处理”

而 become_method 就像通行证的类型:用 sudo 是 “找 sudo 管理员签字”,用 su 是 “直接切换成管理员本人”,给网络设备提权则是 “申请进入特权模式”。

简单说,提权就是让 Playbook 在需要时 “穿上管理员的马甲”,干完活儿再脱下来,既安全又高效

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值