处理流程图

  • playbook 剧本是由一个或多个"play"组成的列表
  • play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。Task实 际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让它们联合起来,按 事先编排的机制执行预定义的动作
  • Playbook 文件是采用YAML语言编写的

处理YAML信息

  • 为了最大限度地提高编程语言和实现之间的数据可移植性,YAML 的用户应注意序列化或表示属性与 YAML 表示形式一部分的属性之间的区别。因此,虽然对映射键施加顺序对于将 YAML 表示形式平展到顺序访问介质是必要的,但此序列化详细信息不得用于传达应用程序级信息。以类似的方式,虽然需要缩进技术和节点样式的选择来提高可读性,但这些表示详细信息既不是 YAML 序列化也不是 YAML 表示的一部分。通过仔细分离序列化和表示所需的属性,应用程序信息的 YAML 表示形式将在各种编程环境之间保持一致和可移植。
  • 上图总结了这三种信息模型。全箭头表示组合,空心箭头表示继承,“1”和“*”表示“一”和“多”关系。单个“+”表示序列化详细信息,双“++”表示表示详细信息。
  • YAML既是一种文本格式,也是一种以这种格式呈现任何数据结构的方法。因此,此规范定义了两个概念:一类称为 YAML 表示形式的数据对象,以及用于将 YAML 表示形式表示为一系列字符的语法(称为 YAML 流)。YAML 处理器是用于在这些互补视图之间转换信息的工具。假设 YAML 处理器代表另一个模块(称为应用程序)执行其工作。
  • YAML信息以两种方式使用:用于机器处理和供人类消费。协调这两种观点的挑战最好在三个不同的翻译阶段完成:表示、序列化和呈现。表示法解决了 YAML 如何查看本机数据结构以实现编程环境之间的可移植性。序列化关注的是将 YAML 表示形式转换为串行形式,即具有顺序访问约束的表单。
  • YAML 处理器不需要公开序列化或表示阶段。它可以直接在本机数据结构和字符流之间转换(上图中的转储和加载)。但是,应该进行这种直接转换,以便仅根据表示中可用的信息构造本机数据结构。
  • YAML使用三种节点类型表示任何本机数据结构:序列 - 有序的条目系列;映射 - 唯一键与值的无序关联;和标量 - 任何具有不透明结构的基准面,可表示为一系列 Unicode 字符。这些基元组合在一起,生成有向图结构。选择这些原语是因为它们既强大又熟悉:序列对应于Perl数组和Python列表,映射对应于Perl哈希表和Python字典。标量表示字符串、整数、日期和其他原子数据类型。

    每个 YAML 节点除了其种类和内容外,还需要一个指定其数据类型的标记。类型说明符可以是全局 URI,也可以是单个应用程序的本地范围。例如,在 YAML 中,一个整数用标量加上全局标记“tag:yaml.org,2002:int”表示。同样,特定于给定组织的发票对象可以与本地标记“!invoice”一起表示为映射。这个简单的模型可以表示独立于编程语言的任何数据结构。

序列化模型

  • 对于顺序访问媒体(如事件回调 API),YAML 表示形式必须序列化为有序树。由于在 YAML 表示形式中,映射键是无序的,并且节点可能被多次引用(具有多个传入的“箭头”),因此序列化过程需要对映射键施加排序,并将对给定节点的第二个和后续引用替换为称为别名的占位符.YAML 不指定如何选择这些序列化详细信息。YAML处理器可以提出人性化的键顺序和锚点名称,可能是在应用程序的帮助下。然后,可以遍历此过程的结果(YAML 序列化树),以生成一系列事件调用,以便对 YAML 数据进行一次性处理。

  • 要使用串行 API 表示 YAML 表示形式,必须对映射键施加顺序,并使用别名节点来指示以前遇到的节点的后续出现。此过程的结果是一个序列化树,其中每个节点都有一组有序的子节点。对于基于事件的串行 API,可以遍历此树。从串行接口构造本机结构不应使用键序或锚点来保存重要数据。

加载故障点

  • 从 YAML 流加载本机数据结构的过程有几个潜在的故障点。字符流可能格式不正确,别名可能未识别,未指定的标记可能无法解析,标记可能无法识别,内容可能无效,并且本机类型可能不可用.这些故障中的每一个都会导致不完整的加载。

    部分表示不需要解析每个节点的标签,并且标量内容的规范形式也不需要可用。这种较弱的表示形式对于文档中使用的类型不完全了解的情况很有用。相反,完整表示指定每个节点的标记,并提供标量内容的规范形式,从而允许进行相等性测试。为了构造本机数据结构,需要完整的表示形式。

YAML介绍

  • YAML:YAML Ain’t Markup Language,即YAML不是标记语言。不过,在开发的这种语言时,YAML的 意思其实是:“Yet Another Markup Language”(仍是一种标记语言)
  • YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、 Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者,目前很多最新的软件比较流行采用此格式的文件存放 配置信息,如:ubuntu,anisble,docker,kubernetes等
  • Yaml官网:http://www.yaml.org
  • ansible官网:https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html

Ymal语言特点

  • YAML的可读性好
  • YAML和脚本语言的交互性好
  • YAML使用实现语言的数据类型
  • YAML有一个一致的信息模型
  • YAML易于实现
  • YAML可以基于流来处理
  • YAML表达能力强,扩展性好

Ymal语法简介

  • 在单一文件第一行,用连续三个连字号"-" 开始,还有选择性的连续三个点号( … )用来表示文件的结 尾
  • 次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
  • 使用#号注释代码
  • 缩进必须是统一的,不能空格和tab混用 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换 行来实现的
  • YAML文件内容是区别大小写的,key/value的值均需大小写敏感
  • 多个key/value可同行写也可换行写,同行使用,分隔
  • key后面冒号要加一个空格 比如: key: value value可是个字符串,也可是另一个列表
  • YAML文件扩展名通常为yml或yaml

Yaml支持的常用数据类型

  • 标量:单个的、不可再分的值
  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
scalar标量
  • 标量是最基本的不可在分的值,包含:

    • 字符串
    • 布尔值
    • 整数
    • 浮点数
    • null
    • 时间
    • 日期
Dictionary 字典
  • 字典由多个key与value构成,key和value之间用 :分隔, 并且 : 后面有一个空格,所有k/v可以放在一 行,或者每个 k/v 分别放在不同行
List列表
  • 列表由多个元素组成,每个元素放在不同行,且元素前均使用"-"打头,并且 - 后有一个空格, 或者将所有 元素用 [ ] 括起来放在同一行
#使用缩进的方式
martin:
  name: Martin D'vloper
  job: Developer
  skill: Elite
#key对应value,字典列表
- martin:
    name: Martin D'vloper
    job: Developer
    skills:
      - python
      - perl
      - pascal
- tabitha:
    name: Tabitha Bitumen
    job: Developer
    skills:
      - lisp
      - fortran
      - erlang
martin: {name: Martin D'vloper, job: Developer, skill: Elite}
fruits: ['Apple', 'Orange', 'Strawberry', 'Mango']
#几种形式指定布尔值(true/false)
create_key: yes
needs_agent: no
knows_oop: True
likes_emacs: TRUE
uses_cvs: false
#使用yaml表示一个家庭
name: John Smith
age: 41
gender: Male
spouse: { name: Jane Smith, age: 37, gender: Female } # 写在一行里
 name: Jane Smith   #也可以写成多行
 age: 37
 gender: Female
children: [ {name: Jimmy Smith,age: 17, gender: Male}, {name: Jenny Smith, age: 
13, gender: Female}, {name: hao Smith, age: 20, gender: Male } ]  #写在一行
 - name: Jimmy Smith    #写在多行,更为推荐的写法
   age: 17
   gender: Male
 - {name: Jenny Smith, age: 13, gender: Female}
 - {name: hao Smith, age: 20, gender: Male }  

PlayBook的核心组件

  • https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords. html#playbook-keywords

playbook常见组件说明

一个playbook中由多个组件组成,其中所用到的常见组件类型如下:

  • Hosts 执行的远程主机列表
  • Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最 少元素需包括 name 和 task,一个name只能包括一个task
  • Variables 内置变量或自定义变量在playbook中调用
  • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
  • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  • tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此 会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地 长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

hosts组件

Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用 于指定要执行指定任务的主机,须事先定义在主机清单中

one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*
Websrvs:dbsrvs     #或者,两个组的并集
Websrvs:&dbsrvs   #与,两个组的交集
webservers:!dbsrvs  #在websrvs组,但不在dbsrvs组

remote_user组件

remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可 用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

- hosts: websrvs remote_user: root #指定任务执行默认用户 tasks: - name: test connection ping: remote_user: xiang sudo: yes #默认sudo为root sudo_user:Test #sudo为Test

task列表和action组件

play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主 机上执行,即在所有主机上完成第一个task后,再开始第二个task task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着 多次执行是安全的,因为其结果均一致

每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。 如果未提供name,则action的结果将用于输出

task的两种格式
action: module arguments  #示例: action: shell wall hello 
module: arguments   #建议使用 #示例: shell: wall hello 
  • shell和command模块后面跟命令,而非key=value
- hosts: websrvs remote_user: root gather_facts: no tasks: - name: install httpd yum: name=httpd - name: start httpd service: name=httpd state=started enabled=yes

其他组件说明

  • 某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers任务
  • 还可以通过"tags"给task 打标签,可在ansible-playbook命令上使用-t指定进行调用

案例:对比shell与playbook

#shell 脚本实现安装httpd
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd 
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
systemctl enable --now httpd
#playbook实验安装httpd
- hosts: websrvs
 remote_user: root
 gather_facts: no
 tasks:
   - name: "安装Apache"
     yum: name=httpd
   - name: "复制配置文件"
     copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
   - name: "复制配置文件"
     copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
   - name: "启动Apache,并设置开机启动"
     service: name=httpd state=started enabled=yes

playbook命令

https://docs.ansible.com/ansible/2.9/user_guide/playbooks.html#working-with-playbooks

ansible-playbook命令格式

ansible-playbook <filename.yml> ... [options]
--syntax-check      #语法检查,可缩写成--syntax, 相当于bash -n 
-C --check #模拟执行,只检测可能会发生的改变,但不真正执行操作,dry run 
--list-hosts    #列出运行任务的主机
--list-tags #列出tag
--list-tasks #列出task
--limit 主机列表 #只针对主机列表中的特定主机执行
-i INVENTORY        #指定主机清单文件,通常一个项对应一个主机清单文件
--start-at-task START_AT_TASK #从指定task开始执行,而非从头开始,START_AT_TASK为任务的
-v -vv  -vvv #显示过程
[root@ansible ansible]#cat hello.yml
- hosts: websrvs
  tasks:
   - name: hello
     command: echo "hello ansible"
ansible-playbook file.yml  --check #只检测语法
ansible-playbook file.yml  #直接执行
ansible-playbook file.yml  --limit websrvs 只执行存在webservs列表内的主机

初步使用Playbook

yaml脚本

playbook创建用户与组(mysql_user.yaml)
- hosts: webservs #指定hostsliet remote_user: root #指定执行tasks的默认用户 gather_facts: no #关闭setup收集信息 tasks: - name: "创建组,组名:mysql 系统组 gid为306" group: name=mysql system=yes gid=306 - name: "创建用户 mysql,不可登录,不创建家目录,是系统用户加入mysql组" user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 home=/data/mysql create_hoem=no - hosts: webservs #指定hostsliet remote_user: root #指定执行tasks的默认用户 gather_facts: no #关闭setup收集信息 tasks: - { name: create group,group: name=mysql system=yes gid=306 } - { name: create user, user: name=mysql shell=/sbin/nologin system=yes group=mysql uid=306 home=/data/mysql create_home=no } #环境清理 - hosts: webservs remote_user: root gather_facts: no tasks: - name: "删除nginx用户相关的组和目录" user: name=nginx state=absent remove=yes
playbook安装nginx(install_nginx)
- hosts: websers remote_user: root gather_facts: no tasks: - name: "创建挂载目录" file: path=/mnt/cdrom state=directory mode=755 - name: "临时挂载cdrom" mount: src=/dev/cdrom path=/mnt/cdrom fstype=iso9660 state=present - name: "创建nginx组" group: name=nginx state=present gid=307 system=yes - name: "创建nginx用户" user: name=nginx state=present group=nginx uid=307 system=yes create_home=no shell=/sbin/bologin - name: "安装nginx" yum: name=nginx state=present - name: "拷贝网页文件" copy: src=/root/files/index.html dest=/usr/share/nginx/html/index.html - name: "启动服务" service: name=nginx state=started enabled=yes - hosts: webservs remote_user: root gather_facts: no tasks: - { name: "创建挂载目录",file: path=/mnt/cdrom state=directory mode=755 } - { name: "临时挂载cdrom",mount: src=/dev/cdrom path=/mnt/cdrom fstype=iso9660 state=present } - { name: "创建nginx组",group: name=nginx state=present gid=307 system=yes } - { name: "创建nginx用户",user: name=nginx state=present group=nginx uid=307 system=yes create_home=no shell=/sbin/bologin } - { name: "安装nginx",yum: name=nginx state=present } - { name: "拷贝网页文件",copy: src=/root/files/index.html dest=/usr/share/nginx/html/index.html } - { name: "启动服务",service: name=nginx state=started enabled=yes } #环境清理 - hosts: webservs remote_user: root gather_facts: no tasks: - name: "停止服务" service: name=nginx state=stopped - name: "删除nginx用户相关的组和目录" user: name=nginx state=absent remove=yes - name: "卸载目录" mount: path=/mnt/cdrom state=unmounted - name: "删除index文件" file: path=/usr/share/nginx/html/index.html state=absent
playbook安装mysql5.6
#!/usr/bin/ansible-playbook
#This is playbook file
#install mysql 5.6
- hosts: dbservs
  remote_user: root
  gather_facts: yes
  vars:
    version: "mysql-5.6.46-linux-glibc2.12-x86_64"
    suffix: "tar.gz"
    pack_file: "{{version}}.{{suffix}}"
    bash: mysql-5.6_install.sh
  tasks:
    - name: install packages
      yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long
    - name: create mysql group
      group: name=mysql system=yes gid=306 
    - name: create mysql user
      user: name=mysql group=mysql uid=306 system=yes create_home=no shell=/sbin/nologin home=/data/mysql
    - name: copy tar to remote host and file mode
      unarchive: src=/data/ansible/files/{{file}} dest=/usr/local/ owner=root group=root 
    - name: create linkfile  /usr/local/mysql
      file: src=/usr/local/{{version}} dest=/usr/local/mysql state=link
    - name: create linkfile /usr/local/mysql 
      file: src=/usr/local/{{version}} dest=/usr/local/mysql state=link
    - name: data dir
      shell: chdir=/usr/local/mysql/ ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
      tags: data
    - name: config my.cnf
      copy: src=/data/ansible/files/my.cnf  dest=/etc/my.cnf 
    - name: service script
      shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
    - name: enable service
      shell: /etc/init.d/mysqld start;chkconfig --add mysqld;chkconfig mysqld on 
      tags: service
    - name: PATH variable
      copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
    - name: secure script
      script: /data/ansible/files/{{bash}}
      tags: script

playbook中的忽略错误组件: ignore_errors

  • 如果一个task出错,默认将不会继续执行后续的其它task 但利用 ignore_errors: yes 可以忽略此task的错误,继续向下执行playbook其它task
- hosts: websrvs tasks: - name: error command: /bin/false #执行后默认值为1,即rc=1,$?=1 ignore_errors: yes #忽略错误 - name: continue command: wall continue #广播 continue

playbook的触发器组件:handlers和notify

Handlers本质是task list ,类似于MySQL中的触发器触发的行为,其中的task与前述的task并没有本质 上的不同,主要用于当关注的资源发生变化时,才会采取一定的操作。而Notify对应的action可用于在 每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完 成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作;

  • 如果多个task通知了相同的handlers, 此handlers仅会在所有tasks结束后运行一 次。
  • 只有notify对应的task发生改变了才会通知handlers, 没有改变则不会触发handlers
  • handlers 是在所有前面的tasks都成功执行才会执行,如果前面任何一个task失败,会导致handler跳 过执行,可以使用force_handlers: yes 强制执行handler
#复制httpd的配置文件到指定目录
cp -p /etc/httpd/conf/httpd.conf /root/files/
#生成playbook,对httpd.conf设置notify
- hosts: websrvs
  remote_user: root
  gather_facts: no
  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: src=/root/files/httpd.conf dest=/etc/httpd/conf/ #当httpd.conf文件发生改变时触发notify
      notify: 
        - restart httpd
        - wall
    - name: ensure apache is running
      service: name=httpd state=started enabled=yes
 handlers:
    - name: restart httpd
      service: name=httpd state=restarted
    - name: wall
      command: wall "The config file is changed"
#执行playbook,可以发现没有触发notify,因此HANDLER直接跳过了
[root@Ansible-Master Date14:04]#ansible-playbook install_httpd.yaml 
PLAY [webservs] **********************************************************************************************************************************************************************************************************
TASK [Install httpd] *****************************************************************************************************************************************************************************************************
changed: [192.168.213.123]
changed: [192.168.213.122]
TASK [Install configure file] ********************************************************************************************************************************************************************************************
changed: [192.168.213.122]
changed: [192.168.213.123]
TASK [ensure apache is running] ******************************************************************************************************************************************************************************************
changed: [192.168.213.123]
changed: [192.168.213.122]
RUNNING HANDLER [restart httpd] ******************************************************************************************************************************************************************************************
changed: [192.168.213.123]
changed: [192.168.213.122]
RUNNING HANDLER [wall] ***************************************************************************************************************************************************************************************************
skipping: [192.168.213.122]
skipping: [192.168.213.123]
PLAY RECAP ***************************************************************************************************************************************************************************************************************
192.168.213.122            : ok=4    changed=4    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
192.168.213.123            : ok=4    changed=4    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0 
#修改httpd.conf文档后在执行playbook
sed -ri '/Listen/s/80/8088/' /root/files/httpd.conf
#再次执行playbook,成功触发HANDLER
[root@Ansible-Master Date14:07]#ansible-playbook -C install_httpd.yaml 
PLAY [webservs] **********************************************************************************************************************************************************************************************************
TASK [Install httpd] *****************************************************************************************************************************************************************************************************
^C [ERROR]: User interrupted execution
[root@Ansible-Master Date14:12]#ansible-playbook install_httpd.yaml 
PLAY [webservs] **********************************************************************************************************************************************************************************************************
TASK [Install httpd] *****************************************************************************************************************************************************************************************************
ok: [192.168.213.123]
ok: [192.168.213.122]
TASK [Install configure file] ********************************************************************************************************************************************************************************************
changed: [192.168.213.123]
changed: [192.168.213.122]
TASK [ensure apache is running] ******************************************************************************************************************************************************************************************
ok: [192.168.213.123]
ok: [192.168.213.122]
RUNNING HANDLER [restart httpd] ******************************************************************************************************************************************************************************************
changed: [192.168.213.123]
changed: [192.168.213.122]
RUNNING HANDLER [wall] ***************************************************************************************************************************************************************************************************
changed: [192.168.213.122]
changed: [192.168.213.123]
PLAY RECAP ***************************************************************************************************************************************************************************************************************
192.168.213.122            : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.213.123            : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
#强制触发HANDLER
- hosts: websers
  remote_user: root
  gather_facts: no
  force_handlers: yes #无论task中的任何一个task失败,仍强制调用handlers
  tasks:
    - name: config file
      copy: src=nginx.conf  dest=/etc/nginx/nginx.conf
      notify: 
       - restart nginx
    - name: install package
      yum: name=no_exist_package
  handlers:
  - name: restart nginx
    service: name=nginx state=restarted
  - name: "wall"
    command: wall "call handlers"

playbook中的标签组件:tags

https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html
  • 在playbook文件中,可以利用tags组件,为特定 task 指定标签,当在执行playbook时,可以只执行特 定tags的task,而非整个playbook文件
  • 可以一个task对应多个tag,也可以多个task对应一个tag
  • 还有另外3个特殊关键字用于标签, tagged, untagged 和 all,它们分别是仅运行已标记,只有未标记和所 有任务。
#对单个任务添加标签
- hosts: webservs
  remote_user: root
  gather_facts: no
  tasks:
   - name: Install httpd
     yum: name=httpd state=present
   - name: Install configure file
     copy: src=files/httpd.conf dest=/etc/httpd/conf/
     tags:
        - conf
        - file
   - name: start httpd service
     tags: service
     service: name=httpd state=started enabled=yes
#查看标签
[root@Ansible-Master Date16:44]#ansible-playbook --list-tags tag_Test-01.yaml 
playbook: tag_Test-01.yaml
  play #1 (webservs): webservs	TAGS: []
      TASK TAGS: [conf, file, service]
#运行单个标签
[root@Ansible-Master Date16:46]#ansible-playbook -t conf tag_Test-01.yaml 
PLAY [webservs] **********************************************************************************************************************************************************************************************************
TASK [Install configure file] ********************************************************************************************************************************************************************************************
ok: [192.168.213.122]
ok: [192.168.213.123]
PLAY RECAP ***************************************************************************************************************************************************************************************************************
192.168.213.122            : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.213.123            : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
#跳过某个标签
[root@Ansible-Master Date16:46]#ansible-playbook -t conf tag_Test-01.yaml 
PLAY [webservs] **********************************************************************************************************************************************************************************************************
TASK [Install configure file] ********************************************************************************************************************************************************************************************
ok: [192.168.213.122]
ok: [192.168.213.123]
PLAY RECAP ***************************************************************************************************************************************************************************************************************
192.168.213.122            : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.213.123            : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
[root@Ansible-Master Date16:46]#ansible-playbook --skip-tags  conf tag_Test-01.yaml 
PLAY [webservs] **********************************************************************************************************************************************************************************************************
TASK [Install httpd] *****************************************************************************************************************************************************************************************************
ok: [192.168.213.123]
ok: [192.168.213.122]
TASK [start httpd service] ***********************************************************************************************************************************************************************************************
ok: [192.168.213.123]
ok: [192.168.213.122]
PLAY RECAP ***************************************************************************************************************************************************************************************************************
192.168.213.122            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.213.123            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
#对tasks打标签
- hosts: websevs
  remote_user: root
  tags: install
  gather_facts: no
  tasks:
	- { name: "创建挂载目录",file: path=/mnt/cdrom state=directory mode=755 }
  	- { name: "临时挂载cdrom",mount: src=/dev/cdrom path=/mnt/cdrom fstype=iso9660 state=present }
  	- { name: "创建nginx组",group: name=nginx state=present gid=307 system=yes }
  	- { name: "创建nginx用户",user: name=nginx state=present group=nginx uid=307 system=yes create_home=no shell=/sbin/bologin }
 	- { name: "安装nginx",yum: name=nginx state=present }
  	- { name: "拷贝网页文件",copy: src=/root/files/index.html dest=/usr/share/nginx/html/index.html }
  	- { name: "启动服务",service: name=nginx state=started enabled=yes }
- hosts: webservs
  remote_user: root
  tags: clear
  gather_facts: no
  tasks:
  - name: "停止服务"
    service: name=nginx state=stopped
  - name: "删除nginx用户相关的组和目录"
    user: name=nginx state=absent remove=yes
  - name: "卸载目录"
    mount: path=/mnt/cdrom state=unmounted
  - name: "删除index文件"
    file: path=/usr/share/nginx/html/index.html state=absent
#查看标签
[root@Ansible-Master Date16:56]#ansible-playbook --list-tags tag_Test-02.yaml 
playbook: tag_Test-02.yaml
  play #1 (webservs): webservs	TAGS: [install]
      TASK TAGS: [install]
  play #2 (webservs): webservs	TAGS: [clear]
      TASK TAGS: [clear]
#只运行clear标签
[root@Ansible-Master Date16:56]#ansible-playbook -t clear tag_Test-02.yaml 
PLAY [webservs] **********************************************************************************************************************************************************************************************************
PLAY [webservs] **********************************************************************************************************************************************************************************************************
TASK [停止服务] **************************************************************************************************************************************************************************************************************
ok: [192.168.213.123]
ok: [192.168.213.122]
TASK [删除nginx用户相关的组和目录] **************************************************************************************************************************************************************************************************
ok: [192.168.213.122]
ok: [192.168.213.123]
TASK [卸载目录] **************************************************************************************************************************************************************************************************************
changed: [192.168.213.122]
changed: [192.168.213.123]
TASK [删除index文件] *********************************************************************************************************************************************************************************************************
changed: [192.168.213.122]
changed: [192.168.213.123]
PLAY RECAP ***************************************************************************************************************************************************************************************************************
192.168.213.122            : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.213.123            : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

playbook的变量:vars

Playbook中同样也支持变量