Ansible非标记语言YAML与任务剧本Playbook

前言

上篇介绍了 Ansible 单模块(AD-Hoc)的相关内容Ansible自动化运维Inventory与Ad-Hoc-CSDN博客,Ad-Hoc 命令是一次性的、即时执行的命令,用于在远程主机上执行特定任务,这些命令通常用于快速执行简单的任务。当需要在执行多个任务、配置复杂场景或需要可重复使用操作时,就需要用到任务剧本(Playbook)来定义复杂的任务流程和处理重复执行的操作。

Playbook 也通常被大家翻译成剧本。可以认为它是 Ansible 自定义的一门语言(可以将 Playbook 比作 Linux 中的 shell,而 Ansible 中的 Module 可以比作为 Linux 中的各种命令。

目录

前言

[一、YAML 非标记语言](#一、YAML 非标记语言)

[1. 概述介绍](#1. 概述介绍)

[2. Yaml 特点](#2. Yaml 特点)

[3. 基本语法](#3. 基本语法)

[3.1 字符串](#3.1 字符串)

[3.2 列表](#3.2 列表)

[3.3 字典](#3.3 字典)

[3.4 混合结构](#3.4 混合结构)

[3.5 验证YAML语法](#3.5 验证YAML语法)

二、Playbook

[1. Paly 的定义](#1. Paly 的定义)

[2. Play 属性](#2. Play 属性)

[3. tasks 属性中任务的多种写法](#3. tasks 属性中任务的多种写法)

[4. 具有多个 Play 的格式](#4. 具有多个 Play 的格式)

[5. Playbook 校验与执行](#5. Playbook 校验与执行)

[5.1 语法检验](#5.1 语法检验)

[5.2 列出任务](#5.2 列出任务)

[5.3 列出主机](#5.3 列出主机)

[5.4 单步跟重调试](#5.4 单步跟重调试)

[5.5 测试运行](#5.5 测试运行)

[5.6 执行](#5.6 执行)

[6. 编写 Playbook](#6. 编写 Playbook)

[7. Handlers 组件](#7. Handlers 组件)


一、YAML 非标记语言

1. 概述介绍

YAML(YAML Ain't Markup Language) 是一种人类可读的数据序列化格式,常用于配置文件和数据传输。它以缩进、换行和符号结构来表示数据,具有简洁、清晰的特点。YAML 旨在成为一个易于阅读和编写的数据格式,同时也适合机器解析和生成。它使用空格缩进来表示层级关系,不需要显式的标记符号(如 XML 或 JSON 中的尖括号或大括号),这使得它更加直观和易读。

YAML 官方网站:The Official YAML Web Site

Ansible 官网:YAML Syntax --- Ansible Documentation

2. Yaml 特点

YAML文件

  • 以 #为注释符
  • 以 .yml 或者 .yaml 结尾
  • 以 --- 开始,以 ... 结束,但开始和结束标志都是可选的

3. 基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时是使用Tab键还是使用空格一定要达到统一,建议使用空格,
  • 相同层级的元素必须左侧对齐即可

YAML 支持的数据结构有三种:

  • 字符串
  • 列表
  • 字典

3.1 字符串

bash 复制代码
---
# YAML 中的字符串可以不使用引号,即使里面存在空格的时候,当然了使用单引号和双引号也可以
this is a string
'this is a string'
"this is a string"
# YAML 中若一行写不下要表述的内容,可以进行折行。写法如下:
long line: |
Example 1
Example 2
Example 3
# 或者
long line: >
Example 1
Example 2
Example 3
...

3.2 列表

在 YAML 中,列表使用短横线 - 表示,后面跟着一个空格。列表可以包含任意类型的元素,例如字符串、数字、布尔值或者其他嵌套的列表。

bash 复制代码
---
#可以认为它就是 python 中的 List,可以认为它是 c 语言中的数组。
# 如何定义:以短横线开头 + 空格 + 具体的值
- red
- green
- blue
# 以上的值假如转换成 python 的 List 会是这样:
# ['red', 'green', 'blue']
...

3.3 字典

字典在 YAML 中使用键值对的形式表示,使用冒号 : 将键和值分隔开,键值之间需要有一个空格。字典可以包含嵌套的字典或者列表作为值。

bash 复制代码
---
# 可以认为它就是 python 中的 Dict
# 如何定义:key + 冒号(:) + 空格 + 值(value),即 key:value
name: Using Ansible
code: D1234
#转换为 python 的 Dict
#{'name': 'Using Ansibel','code': 'D1234'}
...

3.4 混合结构

但在日常生产中,往往需要的数据结构会特别复杂,有可能会是字符串、列表、字典的组合形式。这里举一个例子:学校里是以班级为单位。我们去使用列表和字典的形式去描述一个班级的组成。

bash 复制代码
---
class:
  - name: stu1
    num: 001
  - name: stu2
    num: 002
  - name: stu3
    num: 003
#{'class': [{'name': 'stul, 'num': 1},{'name': 'stu2', 'num': 2), ...]}
...

3.5 验证YAML语法

bash 复制代码
//将 YAML 文件,通过 Python 的 YAM 模块验证,若不正确则报错。若正确则会输出 YAML 里的内容。
//注意使用时,一定确保安装了 yaml 软件包,
python -c 'import yaml,sys; print yaml.load(sys.stdin)' < myyaml.yml
python3 -c 'import yaml,sys; print(yaml.load(sys.stdin)) < myyaml.yml

示例:

bash 复制代码
# cat myyaml.yml
---
- red
- geen
- blue
...
#python -c 'import yaml,sys; print yaml.save_load(sys.stdin)' < myyaml.yml
['red', 'green', 'blue']

在 Ansible Playbooks 中,列表和字典通常用来定义变量、任务、主机清单等信息。它们提供了一种直观且易读的方式来表示复杂的数据结构,使得编写和维护 Playbooks 更加方便和直观。

二、Playbook

1. Paly 的定义

bash 复制代码
由于 playbook 是由一个或者多个 play 组成,如何定义一个 play 呢?
1、每一个 play 都是以短横杠开始的
2、每一个 play 都是一个YAML 字典格式

格式结构:

bash 复制代码
---
- keyl: value1
- key2: value2
- key3: value3
...

多个Play结构:

bash 复制代码
---
- keyl: value1
  key2: value2
  key3: value3
- key4: value1
  key5: value2
  key6: value3
- key7: value1
  key8: value2
  key9: value3
...

2. Play 属性

Play 中的每一个 key,比如 key1,key2 等;这些 key 在 PlayBook 中被定义为 Play 的属性。

这些属性都具有特殊的意义,我们不能随意的自定义 Play 的属性。

常用属性:

  • name 属性:每个play的名字
  • hosts 属性:每个play涉及的被管理服务器,同 ad-hoc 中的资产选择器
  • tasks 属性:每个play 中具体要完成的任务,以列表的形式表达
  • become 属性:如果需要提权,则加上become相关属性
  • becomekuser 属性:若提权的话,提权到哪个用户上
  • remote_user 属性:指定连接到远程节点上的用户,即远程服务器上执行操作的用户。若不指定,则默认使用当前执行 ansible Playbook 的用户

3. tasks 属性中任务的多种写法

bash 复制代码
# 以启动 apache 服务,并增加开机启动为例
#一行的形式:
service: name=apache enabled=true state=started
#多行的形式:
sefvice: name=apache
         enabled=true
         state=started
#多行写成字典的形式:
service:
  name: apache
  enabled: true
  state: started

4. 具有多个 Play 的格式

bash 复制代码
---
- name: manage web servers
  hosts: webserver
  remote_user: root
  tasks :
  - name: install apache package
    yum: name=httpd state=present
  - name: copy apache conf
    copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
  - name: ensure apache is running start nginx server
    service: service: name=httpd state=started enabled=yes

- name: manager db servers
  hosts: dbservers
  tasks:
  - name update database confg
    copy :src=my.cnf dest=/etc/my.cnf
...

5. Playbook 校验与执行

5.1 语法检验

bash 复制代码
ansible-playbook apache.yaml  --syntax-check

5.2 列出任务

bash 复制代码
ansible-playbook apache.yaml --list-tasks

5.3 列出主机

bash 复制代码
ansible-playbook apache.yaml --list-hosts

5.4 单步跟重调试

执行 tasks 中的任务,需要手动确认是否往下执行。

bash 复制代码
ansible-playbook apache.yaml --step

5.5 测试运行

会执行完整的 Playbook,但是所有 task 中的行为都不会在远程被管理节点服务器上执行,所有的操作都是模拟。

bash 复制代码
ansible-playbook apache.yaml --C  #大写的C

5.6 执行

bash 复制代码
ansible-playbook apache.yaml

6. 编写 Playbook

批量安装apache

① 准备工作,卸载目标主机网站服务

bash 复制代码
管理节点:
[root@ansible ~]# ansible all -m yum -a "name=httpd state=removed"
#在Ansible中,all是一个用于指代所有主机的特殊关键字。当你在使用Ansible命令时,使用all会将命令应用到所有已定义的主机上。卸载httpd相关服务。

被管理节点:
[root@localhost ~]# yum list | grep httpd | grep @
httpd-tools.x86_64                       2.4.6-99.el7.centos.1         @updates 
#检查是否还有安装httpd相关包。

管理节点:
[root@ansible ~]# ansible all -m yum -a "name=httpd-tools state=removed"
#卸载httpd工具包,避免影响安装httpd。

管理节点:
[root@ansible ~]# yum install -y httpd
#Ansible服务器安装网站服务
[root@ansible ~]# mkdir apache
[root@ansible ~]# cd apache/
[root@ansible apache]# cp -rf /etc/httpd/conf/httpd.conf .

② 编写剧本

bash 复制代码
[root@ansible apache]# vim apache.yaml
- hosts: webserver                     #针对的剧本对象
  tasks:                               #任务
  - name: install apache packages      #任务1:安装apache包(可以自定义)
    yum: name=httpd state=present      #调用yum安装模块:httpd,present,表示确保软件包已经安装
  - name: copy apache conf             #任务2:拷贝apache配置文件
    copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf #调用拷贝模块,源------>目标
  - name: ensure apache is running     #确保apache服务已运行
    service: name=httpd state=started enabled=yes   #调用系统服务状态模块

③ 检查测试

bash 复制代码
[root@ansible apache]# ansible-playbook apache.yaml --syntax-check  #检验语法

playbook: apache.yaml
[root@ansible apache]# ansible-playbook apache.yaml --list-tasks    #列出任务

playbook: apache.yaml

  play #1 (webserver): webserver	TAGS: []
    tasks:
      install apache packages	TAGS: []
      copy apache conf	TAGS: []
      ensure apache is running	TAGS: []
[root@ansible apache]# ansible-playbook apache.yaml --list-hosts    #列出主机

playbook: apache.yaml

  play #1 (webserver): webserver	TAGS: []
    pattern: [u'webserver']
    hosts (4):
      host4
      host3
      host2
      host1

④ 执行剧本

bash 复制代码
[root@ansible apache]# ansible-playbook apache.yaml

PLAY [webserver] ************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************
ok: [host2]
ok: [host3]
ok: [host1]
ok: [host4]

TASK [install apache packages] **********************************************************************************
changed: [host2]
changed: [host1]
changed: [host4]
changed: [host3]

TASK [copy apache conf] *****************************************************************************************
ok: [host2]
ok: [host3]
ok: [host1]
ok: [host4]

TASK [ensure apache is running] *********************************************************************************
changed: [host2]
changed: [host1]
changed: [host4]
changed: [host3]

PLAY RECAP ******************************************************************************************************
host1                      : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2                      : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host3                      : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host4                      : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

7. Handlers 组件

在 Playbook 中,Handlers 通常会在任务中触发,并在整个 Playbook 运行结束时才会执行。

示例:修改管理节点apace配置文件模板,拷贝到被管理节点,查看apache相关信息:

① 修改管理几点服务器apache监听端口号,执行剧本查看被代理节点服务器配置是否拷贝

bash 复制代码
[root@ansible ~]# yum install -y httpd
#Ansible服务器安装网站服务
[root@ansible ~]# mkdir apache
[root@ansible ~]# cd apache/
[root@ansible apache]# cp -rf /etc/httpd/conf/httpd.conf .
[root@ansible apache]# sed -i 's/Listen 80/Listen 8080/' httpd.conf

② 查看被代理节点apache配置文件已及更新,但是并没有生效

③ 由于剧本服务模块指令是启动,需要定义、引用处理程序

注意:如果将 state=started 改为 restart ,将会导致每次执行剧本都会重启 apache 服务。

bash 复制代码
[root@ansible apache]# vim apache.yaml
- hosts: webserver                       #定义了将要执行任务的目标主机或主机组
  tasks:
  - name: install apache packages        #对Playbook的描述,用于标识该Playbook的作用。
    yum: name=httpd state=present
  - name: copy apache conf
    copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify: restart apache service       #通知,当copy模块产生改变,通知程序重启,需要与handlers的name一样 #应用处理程序
  - name: ensure apache is running
    service: name=httpd state=started enabled=yes
  handlers:                              #当任务触发会执行 #定义处理程序
  - name: restart apache service         #任务,重启apache(名字自定义)
    service: name=httpd state=restarted

④ 再次修改管理节点 apachep 配置文件端口号,执行剧本,查看被代理节点 apache 端口信息

相关推荐
hello world smile1 天前
最全的Flutter中pubspec.yaml及其yaml 语法的使用说明
android·前端·javascript·flutter·dart·yaml·pubspec.yaml
2301_806131363 天前
yaml文件编写
yaml
peanutfish17 天前
Chapter 9 RH294 RHEL Automation with Ansible
linux·ansible·yaml
peanutfish22 天前
Chapter 8 RH294 RHEL Automation with Ansible
linux·ansible·yaml
peanutfish1 个月前
Chapter 4 RH294 RHEL Automation with Ansible
linux·ansible·yaml
peanutfish1 个月前
Chapter 5 RH294 RHEL Automation with Ansible
linux·ansible·yaml
henan程序媛1 个月前
Ansible PlayBook实践案例
ansible·playbook
Shenqi Lotus2 个月前
Ansible——Playbook基本功能
运维·ansible·playbook
曹开尔3 个月前
hexo+github+zeabur个人博客
arcgis·node.js·github·yaml
JingAi_jia9173 个月前
Yaml及解析框架SnakeYaml简介及TypeDescription的使用和原理
yaml·snakeyaml·snakeyaml原理·typedescription·yaml解析